mirror of
https://github.com/stackblitz-labs/bolt.diy
synced 2025-06-26 18:26:38 +00:00
Fixes for cloudflare deployment (#3)
This commit is contained in:
parent
6bc218340c
commit
6543f33d54
@ -9,7 +9,6 @@ import { Menu } from '~/components/sidebar/Menu.client';
|
|||||||
import { IconButton } from '~/components/ui/IconButton';
|
import { IconButton } from '~/components/ui/IconButton';
|
||||||
import { Workbench } from '~/components/workbench/Workbench.client';
|
import { Workbench } from '~/components/workbench/Workbench.client';
|
||||||
import { classNames } from '~/utils/classNames';
|
import { classNames } from '~/utils/classNames';
|
||||||
import { MODEL_LIST, PROVIDER_LIST, initializeModelList } from '~/utils/constants';
|
|
||||||
import { Messages } from './Messages.client';
|
import { Messages } from './Messages.client';
|
||||||
import { SendButton } from './SendButton.client';
|
import { SendButton } from './SendButton.client';
|
||||||
import { APIKeyManager } from './APIKeyManager';
|
import { APIKeyManager } from './APIKeyManager';
|
||||||
@ -25,7 +24,6 @@ import GitCloneButton from './GitCloneButton';
|
|||||||
import FilePreview from './FilePreview';
|
import FilePreview from './FilePreview';
|
||||||
import { ModelSelector } from '~/components/chat/ModelSelector';
|
import { ModelSelector } from '~/components/chat/ModelSelector';
|
||||||
import { SpeechRecognitionButton } from '~/components/chat/SpeechRecognition';
|
import { SpeechRecognitionButton } from '~/components/chat/SpeechRecognition';
|
||||||
import type { IProviderSetting, ProviderInfo } from '~/types/model';
|
|
||||||
import { ScreenshotStateManager } from './ScreenshotStateManager';
|
import { ScreenshotStateManager } from './ScreenshotStateManager';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
@ -43,11 +41,6 @@ interface BaseChatProps {
|
|||||||
enhancingPrompt?: boolean;
|
enhancingPrompt?: boolean;
|
||||||
promptEnhanced?: boolean;
|
promptEnhanced?: boolean;
|
||||||
input?: string;
|
input?: string;
|
||||||
model?: string;
|
|
||||||
setModel?: (model: string) => void;
|
|
||||||
provider?: ProviderInfo;
|
|
||||||
setProvider?: (provider: ProviderInfo) => void;
|
|
||||||
providerList?: ProviderInfo[];
|
|
||||||
handleStop?: () => void;
|
handleStop?: () => void;
|
||||||
sendMessage?: (event: React.UIEvent, messageInput?: string, simulation?: boolean) => void;
|
sendMessage?: (event: React.UIEvent, messageInput?: string, simulation?: boolean) => void;
|
||||||
handleInputChange?: (event: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
handleInputChange?: (event: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
||||||
@ -69,11 +62,6 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
|||||||
showChat = true,
|
showChat = true,
|
||||||
chatStarted = false,
|
chatStarted = false,
|
||||||
isStreaming = false,
|
isStreaming = false,
|
||||||
model,
|
|
||||||
setModel,
|
|
||||||
provider,
|
|
||||||
setProvider,
|
|
||||||
providerList,
|
|
||||||
input = '',
|
input = '',
|
||||||
enhancingPrompt,
|
enhancingPrompt,
|
||||||
handleInputChange,
|
handleInputChange,
|
||||||
@ -93,22 +81,6 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
|||||||
ref,
|
ref,
|
||||||
) => {
|
) => {
|
||||||
const TEXTAREA_MAX_HEIGHT = chatStarted ? 400 : 200;
|
const TEXTAREA_MAX_HEIGHT = chatStarted ? 400 : 200;
|
||||||
const [apiKeys, setApiKeys] = useState<Record<string, string>>(() => {
|
|
||||||
const savedKeys = Cookies.get('apiKeys');
|
|
||||||
|
|
||||||
if (savedKeys) {
|
|
||||||
try {
|
|
||||||
return JSON.parse(savedKeys);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Failed to parse API keys from cookies:', error);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
});
|
|
||||||
const [modelList, setModelList] = useState(MODEL_LIST);
|
|
||||||
const [isModelSettingsCollapsed, setIsModelSettingsCollapsed] = useState(false);
|
|
||||||
const [isListening, setIsListening] = useState(false);
|
const [isListening, setIsListening] = useState(false);
|
||||||
const [recognition, setRecognition] = useState<SpeechRecognition | null>(null);
|
const [recognition, setRecognition] = useState<SpeechRecognition | null>(null);
|
||||||
const [transcript, setTranscript] = useState('');
|
const [transcript, setTranscript] = useState('');
|
||||||
@ -120,50 +92,6 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Load API keys from cookies on component mount
|
// Load API keys from cookies on component mount
|
||||||
|
|
||||||
let parsedApiKeys: Record<string, string> | undefined = {};
|
|
||||||
|
|
||||||
try {
|
|
||||||
const storedApiKeys = Cookies.get('apiKeys');
|
|
||||||
|
|
||||||
if (storedApiKeys) {
|
|
||||||
const parsedKeys = JSON.parse(storedApiKeys);
|
|
||||||
|
|
||||||
if (typeof parsedKeys === 'object' && parsedKeys !== null) {
|
|
||||||
setApiKeys(parsedKeys);
|
|
||||||
parsedApiKeys = parsedKeys;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error loading API keys from cookies:', error);
|
|
||||||
|
|
||||||
// Clear invalid cookie data
|
|
||||||
Cookies.remove('apiKeys');
|
|
||||||
}
|
|
||||||
|
|
||||||
let providerSettings: Record<string, IProviderSetting> | undefined = undefined;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const savedProviderSettings = Cookies.get('providers');
|
|
||||||
|
|
||||||
if (savedProviderSettings) {
|
|
||||||
const parsedProviderSettings = JSON.parse(savedProviderSettings);
|
|
||||||
|
|
||||||
if (typeof parsedProviderSettings === 'object' && parsedProviderSettings !== null) {
|
|
||||||
providerSettings = parsedProviderSettings;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error loading Provider Settings from cookies:', error);
|
|
||||||
|
|
||||||
// Clear invalid cookie data
|
|
||||||
Cookies.remove('providers');
|
|
||||||
}
|
|
||||||
|
|
||||||
initializeModelList({ apiKeys: parsedApiKeys, providerSettings }).then((modelList) => {
|
|
||||||
console.log('Model List: ', modelList);
|
|
||||||
setModelList(modelList);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (typeof window !== 'undefined' && ('SpeechRecognition' in window || 'webkitSpeechRecognition' in window)) {
|
if (typeof window !== 'undefined' && ('SpeechRecognition' in window || 'webkitSpeechRecognition' in window)) {
|
||||||
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
||||||
const recognition = new SpeechRecognition();
|
const recognition = new SpeechRecognition();
|
||||||
@ -351,31 +279,6 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
|||||||
<rect className={classNames(styles.PromptEffectLine)} pathLength="100" strokeLinecap="round"></rect>
|
<rect className={classNames(styles.PromptEffectLine)} pathLength="100" strokeLinecap="round"></rect>
|
||||||
<rect className={classNames(styles.PromptShine)} x="48" y="24" width="70" height="1"></rect>
|
<rect className={classNames(styles.PromptShine)} x="48" y="24" width="70" height="1"></rect>
|
||||||
</svg>
|
</svg>
|
||||||
<div>
|
|
||||||
<div className={isModelSettingsCollapsed ? 'hidden' : ''}>
|
|
||||||
<ModelSelector
|
|
||||||
key={provider?.name + ':' + modelList.length}
|
|
||||||
model={model}
|
|
||||||
setModel={setModel}
|
|
||||||
modelList={modelList}
|
|
||||||
provider={provider}
|
|
||||||
setProvider={setProvider}
|
|
||||||
providerList={providerList || (PROVIDER_LIST as ProviderInfo[])}
|
|
||||||
apiKeys={apiKeys}
|
|
||||||
/>
|
|
||||||
{(providerList || []).length > 0 && provider && (
|
|
||||||
<APIKeyManager
|
|
||||||
provider={provider}
|
|
||||||
apiKey={apiKeys[provider.name] || ''}
|
|
||||||
setApiKey={(key) => {
|
|
||||||
const newApiKeys = { ...apiKeys, [provider.name]: key };
|
|
||||||
setApiKeys(newApiKeys);
|
|
||||||
Cookies.set('apiKeys', JSON.stringify(newApiKeys));
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<FilePreview
|
<FilePreview
|
||||||
files={uploadedFiles}
|
files={uploadedFiles}
|
||||||
imageDataList={imageDataList}
|
imageDataList={imageDataList}
|
||||||
@ -476,7 +379,6 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
|||||||
show={input.length > 0 || isStreaming || uploadedFiles.length > 0}
|
show={input.length > 0 || isStreaming || uploadedFiles.length > 0}
|
||||||
simulation={false}
|
simulation={false}
|
||||||
isStreaming={isStreaming}
|
isStreaming={isStreaming}
|
||||||
disabled={!providerList || providerList.length === 0}
|
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
if (isStreaming) {
|
if (isStreaming) {
|
||||||
handleStop?.();
|
handleStop?.();
|
||||||
@ -492,7 +394,6 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
|||||||
show={(input.length > 0 || uploadedFiles.length > 0) && chatStarted}
|
show={(input.length > 0 || uploadedFiles.length > 0) && chatStarted}
|
||||||
simulation={true}
|
simulation={true}
|
||||||
isStreaming={isStreaming}
|
isStreaming={isStreaming}
|
||||||
disabled={!providerList || providerList.length === 0}
|
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
if (input.length > 0 || uploadedFiles.length > 0) {
|
if (input.length > 0 || uploadedFiles.length > 0) {
|
||||||
handleSendMessage?.(event, undefined, true);
|
handleSendMessage?.(event, undefined, true);
|
||||||
@ -530,20 +431,6 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
|||||||
disabled={isStreaming}
|
disabled={isStreaming}
|
||||||
/>
|
/>
|
||||||
{chatStarted && <ClientOnly>{() => <ExportChatButton exportChat={exportChat} />}</ClientOnly>}
|
{chatStarted && <ClientOnly>{() => <ExportChatButton exportChat={exportChat} />}</ClientOnly>}
|
||||||
<IconButton
|
|
||||||
title="Model Settings"
|
|
||||||
className={classNames('transition-all flex items-center gap-1', {
|
|
||||||
'bg-bolt-elements-item-backgroundAccent text-bolt-elements-item-contentAccent':
|
|
||||||
isModelSettingsCollapsed,
|
|
||||||
'bg-bolt-elements-item-backgroundDefault text-bolt-elements-item-contentDefault':
|
|
||||||
!isModelSettingsCollapsed,
|
|
||||||
})}
|
|
||||||
onClick={() => setIsModelSettingsCollapsed(!isModelSettingsCollapsed)}
|
|
||||||
disabled={!providerList || providerList.length === 0}
|
|
||||||
>
|
|
||||||
<div className={`i-ph:caret-${isModelSettingsCollapsed ? 'right' : 'down'} text-lg`} />
|
|
||||||
{isModelSettingsCollapsed ? <span className="text-xs">{model}</span> : <span />}
|
|
||||||
</IconButton>
|
|
||||||
</div>
|
</div>
|
||||||
{input.length > 3 ? (
|
{input.length > 3 ? (
|
||||||
<div className="text-xs text-bolt-elements-textTertiary">
|
<div className="text-xs text-bolt-elements-textTertiary">
|
||||||
|
@ -12,18 +12,16 @@ import { useMessageParser, usePromptEnhancer, useShortcuts, useSnapScroll } from
|
|||||||
import { description, useChatHistory } from '~/lib/persistence';
|
import { description, useChatHistory } from '~/lib/persistence';
|
||||||
import { chatStore } from '~/lib/stores/chat';
|
import { chatStore } from '~/lib/stores/chat';
|
||||||
import { workbenchStore } from '~/lib/stores/workbench';
|
import { workbenchStore } from '~/lib/stores/workbench';
|
||||||
import { DEFAULT_MODEL, DEFAULT_PROVIDER, PROMPT_COOKIE_KEY, PROVIDER_LIST } from '~/utils/constants';
|
import { PROMPT_COOKIE_KEY } from '~/utils/constants';
|
||||||
import { cubicEasingFn } from '~/utils/easings';
|
import { cubicEasingFn } from '~/utils/easings';
|
||||||
import { createScopedLogger, renderLogger } from '~/utils/logger';
|
import { createScopedLogger, renderLogger } from '~/utils/logger';
|
||||||
import { BaseChat } from './BaseChat';
|
import { BaseChat } from './BaseChat';
|
||||||
import Cookies from 'js-cookie';
|
import Cookies from 'js-cookie';
|
||||||
import { debounce } from '~/utils/debounce';
|
import { debounce } from '~/utils/debounce';
|
||||||
import { useSettings } from '~/lib/hooks/useSettings';
|
import { useSettings } from '~/lib/hooks/useSettings';
|
||||||
import type { ProviderInfo } from '~/types/model';
|
|
||||||
import { useSearchParams } from '@remix-run/react';
|
import { useSearchParams } from '@remix-run/react';
|
||||||
import { createSampler } from '~/utils/sampler';
|
import { createSampler } from '~/utils/sampler';
|
||||||
import { saveProjectPrompt } from './Messages.client';
|
import { saveProjectPrompt } from './Messages.client';
|
||||||
import { uint8ArrayToBase64 } from '~/lib/replay/ReplayProtocolClient';
|
|
||||||
import type { SimulationPromptClientData } from '~/lib/replay/SimulationPrompt';
|
import type { SimulationPromptClientData } from '~/lib/replay/SimulationPrompt';
|
||||||
import { getIFrameSimulationData } from '~/lib/replay/Recording';
|
import { getIFrameSimulationData } from '~/lib/replay/Recording';
|
||||||
import { getCurrentIFrame } from '../workbench/Preview';
|
import { getCurrentIFrame } from '../workbench/Preview';
|
||||||
@ -120,27 +118,15 @@ export const ChatImpl = memo(
|
|||||||
const [imageDataList, setImageDataList] = useState<string[]>([]); // Move here
|
const [imageDataList, setImageDataList] = useState<string[]>([]); // Move here
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
const files = useStore(workbenchStore.files);
|
const files = useStore(workbenchStore.files);
|
||||||
const { activeProviders, promptId } = useSettings();
|
const { promptId } = useSettings();
|
||||||
|
|
||||||
const [model, setModel] = useState(() => {
|
|
||||||
const savedModel = Cookies.get('selectedModel');
|
|
||||||
return savedModel || DEFAULT_MODEL;
|
|
||||||
});
|
|
||||||
const [provider, setProvider] = useState(() => {
|
|
||||||
const savedProvider = Cookies.get('selectedProvider');
|
|
||||||
return (PROVIDER_LIST.find((p) => p.name === savedProvider) || DEFAULT_PROVIDER) as ProviderInfo;
|
|
||||||
});
|
|
||||||
|
|
||||||
const { showChat } = useStore(chatStore);
|
const { showChat } = useStore(chatStore);
|
||||||
|
|
||||||
const [animationScope, animate] = useAnimate();
|
const [animationScope, animate] = useAnimate();
|
||||||
|
|
||||||
const [apiKeys, setApiKeys] = useState<Record<string, string>>({});
|
|
||||||
|
|
||||||
const { messages, isLoading, input, handleInputChange, setInput, stop, append } = useChat({
|
const { messages, isLoading, input, handleInputChange, setInput, stop, append } = useChat({
|
||||||
api: '/api/chat',
|
api: '/api/chat',
|
||||||
body: {
|
body: {
|
||||||
apiKeys,
|
|
||||||
files,
|
files,
|
||||||
promptId,
|
promptId,
|
||||||
},
|
},
|
||||||
@ -167,7 +153,6 @@ export const ChatImpl = memo(
|
|||||||
});
|
});
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const prompt = searchParams.get('prompt');
|
const prompt = searchParams.get('prompt');
|
||||||
console.log(prompt, searchParams, model, provider);
|
|
||||||
|
|
||||||
if (prompt) {
|
if (prompt) {
|
||||||
setSearchParams({});
|
setSearchParams({});
|
||||||
@ -177,12 +162,12 @@ export const ChatImpl = memo(
|
|||||||
content: [
|
content: [
|
||||||
{
|
{
|
||||||
type: 'text',
|
type: 'text',
|
||||||
text: `[Model: ${model}]\n\n[Provider: ${provider.name}]\n\n${prompt}`,
|
text: prompt,
|
||||||
},
|
},
|
||||||
] as any, // Type assertion to bypass compiler check
|
] as any, // Type assertion to bypass compiler check
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [model, provider, searchParams]);
|
}, [searchParams]);
|
||||||
|
|
||||||
const { enhancingPrompt, promptEnhanced, enhancePrompt, resetEnhancer } = usePromptEnhancer();
|
const { enhancingPrompt, promptEnhanced, enhancePrompt, resetEnhancer } = usePromptEnhancer();
|
||||||
const { parsedMessages, parseMessages } = useMessageParser();
|
const { parsedMessages, parseMessages } = useMessageParser();
|
||||||
@ -294,7 +279,7 @@ export const ChatImpl = memo(
|
|||||||
content: [
|
content: [
|
||||||
{
|
{
|
||||||
type: 'text',
|
type: 'text',
|
||||||
text: `[Model: ${model}]\n\n[Provider: ${provider.name}]\n\n${_input}`,
|
text: _input,
|
||||||
},
|
},
|
||||||
...imageDataList.map((imageData) => ({
|
...imageDataList.map((imageData) => ({
|
||||||
type: 'image',
|
type: 'image',
|
||||||
@ -314,7 +299,7 @@ export const ChatImpl = memo(
|
|||||||
content: [
|
content: [
|
||||||
{
|
{
|
||||||
type: 'text',
|
type: 'text',
|
||||||
text: `[Model: ${model}]\n\n[Provider: ${provider.name}]\n\n${_input}`,
|
text: _input,
|
||||||
},
|
},
|
||||||
...imageDataList.map((imageData) => ({
|
...imageDataList.map((imageData) => ({
|
||||||
type: 'image',
|
type: 'image',
|
||||||
@ -363,24 +348,6 @@ export const ChatImpl = memo(
|
|||||||
|
|
||||||
const [messageRef, scrollRef] = useSnapScroll();
|
const [messageRef, scrollRef] = useSnapScroll();
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const storedApiKeys = Cookies.get('apiKeys');
|
|
||||||
|
|
||||||
if (storedApiKeys) {
|
|
||||||
setApiKeys(JSON.parse(storedApiKeys));
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleModelChange = (newModel: string) => {
|
|
||||||
setModel(newModel);
|
|
||||||
Cookies.set('selectedModel', newModel, { expires: 30 });
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleProviderChange = (newProvider: ProviderInfo) => {
|
|
||||||
setProvider(newProvider);
|
|
||||||
Cookies.set('selectedProvider', newProvider.name, { expires: 30 });
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BaseChat
|
<BaseChat
|
||||||
ref={animationScope}
|
ref={animationScope}
|
||||||
@ -392,11 +359,6 @@ export const ChatImpl = memo(
|
|||||||
enhancingPrompt={enhancingPrompt}
|
enhancingPrompt={enhancingPrompt}
|
||||||
promptEnhanced={promptEnhanced}
|
promptEnhanced={promptEnhanced}
|
||||||
sendMessage={sendMessage}
|
sendMessage={sendMessage}
|
||||||
model={model}
|
|
||||||
setModel={handleModelChange}
|
|
||||||
provider={provider}
|
|
||||||
setProvider={handleProviderChange}
|
|
||||||
providerList={activeProviders}
|
|
||||||
messageRef={messageRef}
|
messageRef={messageRef}
|
||||||
scrollRef={scrollRef}
|
scrollRef={scrollRef}
|
||||||
handleInputChange={(e) => {
|
handleInputChange={(e) => {
|
||||||
@ -424,9 +386,6 @@ export const ChatImpl = memo(
|
|||||||
setInput(input);
|
setInput(input);
|
||||||
scrollTextArea();
|
scrollTextArea();
|
||||||
},
|
},
|
||||||
model,
|
|
||||||
provider,
|
|
||||||
apiKeys,
|
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
uploadedFiles={uploadedFiles}
|
uploadedFiles={uploadedFiles}
|
||||||
|
59
app/lib/.server/llm/chat-anthropic.ts
Normal file
59
app/lib/.server/llm/chat-anthropic.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import type { CoreMessage } from "ai";
|
||||||
|
import Anthropic from "@anthropic-ai/sdk";
|
||||||
|
import { ChatStreamController } from "~/utils/chatStreamController";
|
||||||
|
import type { ContentBlockParam, MessageParam } from "@anthropic-ai/sdk/resources/messages/messages.mjs";
|
||||||
|
|
||||||
|
const MaxMessageTokens = 8192;
|
||||||
|
|
||||||
|
function convertContentToAnthropic(content: any): ContentBlockParam[] {
|
||||||
|
if (typeof content === "string") {
|
||||||
|
return [{ type: "text", text: content }];
|
||||||
|
}
|
||||||
|
if (Array.isArray(content)) {
|
||||||
|
return content.flatMap(convertContentToAnthropic);
|
||||||
|
}
|
||||||
|
if (content.type === "text" && typeof content.text === "string") {
|
||||||
|
return [{ type: "text", text: content.text }];
|
||||||
|
}
|
||||||
|
console.log("AnthropicUnknownContent", JSON.stringify(content, null, 2));
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function chatAnthropic(chatController: ChatStreamController, apiKey: string, systemPrompt: string, messages: CoreMessage[]) {
|
||||||
|
const anthropic = new Anthropic({ apiKey });
|
||||||
|
|
||||||
|
const messageParams: MessageParam[] = [];
|
||||||
|
|
||||||
|
messageParams.push({
|
||||||
|
role: "assistant",
|
||||||
|
content: systemPrompt,
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const message of messages) {
|
||||||
|
const role = message.role == "user" ? "user" : "assistant";
|
||||||
|
const content = convertContentToAnthropic(message.content);
|
||||||
|
messageParams.push({
|
||||||
|
role,
|
||||||
|
content,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await anthropic.messages.create({
|
||||||
|
model: "claude-3-5-sonnet-20241022",
|
||||||
|
messages: messageParams,
|
||||||
|
max_tokens: MaxMessageTokens,
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const content of response.content) {
|
||||||
|
if (content.type === "text") {
|
||||||
|
chatController.writeText(content.text);
|
||||||
|
} else {
|
||||||
|
console.log("AnthropicUnknownResponse", JSON.stringify(content, null, 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const tokens = response.usage.input_tokens + response.usage.output_tokens;
|
||||||
|
console.log("AnthropicTokens", tokens);
|
||||||
|
|
||||||
|
chatController.writeUsage({ completionTokens: response.usage.output_tokens, promptTokens: response.usage.input_tokens });
|
||||||
|
}
|
@ -142,16 +142,15 @@ function extractPropertiesFromMessage(message: Message): { model: string; provid
|
|||||||
return { model, provider, content: cleanedContent };
|
return { model, provider, content: cleanedContent };
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function streamText(props: {
|
export async function getStreamTextArguments(props: {
|
||||||
messages: Messages;
|
messages: Messages;
|
||||||
env: Env;
|
env: Env;
|
||||||
options?: StreamingOptions;
|
|
||||||
apiKeys?: Record<string, string>;
|
apiKeys?: Record<string, string>;
|
||||||
files?: FileMap;
|
files?: FileMap;
|
||||||
providerSettings?: Record<string, IProviderSetting>;
|
providerSettings?: Record<string, IProviderSetting>;
|
||||||
promptId?: string;
|
promptId?: string;
|
||||||
}) {
|
}) {
|
||||||
const { messages, env: serverEnv, options, apiKeys, files, providerSettings, promptId } = props;
|
const { messages, env: serverEnv, apiKeys, files, providerSettings, promptId } = props;
|
||||||
|
|
||||||
// console.log({serverEnv});
|
// console.log({serverEnv});
|
||||||
|
|
||||||
@ -202,9 +201,7 @@ export async function streamText(props: {
|
|||||||
|
|
||||||
const coreMessages = convertToCoreMessages(processedMessages as any);
|
const coreMessages = convertToCoreMessages(processedMessages as any);
|
||||||
|
|
||||||
console.log("QueryModel", JSON.stringify({ systemPrompt, coreMessages }));
|
return {
|
||||||
|
|
||||||
return _streamText({
|
|
||||||
model: provider.getModelInstance({
|
model: provider.getModelInstance({
|
||||||
model: currentModel,
|
model: currentModel,
|
||||||
serverEnv,
|
serverEnv,
|
||||||
@ -214,6 +211,18 @@ export async function streamText(props: {
|
|||||||
system: systemPrompt,
|
system: systemPrompt,
|
||||||
maxTokens: dynamicMaxTokens,
|
maxTokens: dynamicMaxTokens,
|
||||||
messages: coreMessages,
|
messages: coreMessages,
|
||||||
...options,
|
};
|
||||||
});
|
}
|
||||||
|
|
||||||
|
export async function streamText(props: {
|
||||||
|
messages: Messages;
|
||||||
|
env: Env;
|
||||||
|
options?: StreamingOptions;
|
||||||
|
apiKeys?: Record<string, string>;
|
||||||
|
files?: FileMap;
|
||||||
|
providerSettings?: Record<string, IProviderSetting>;
|
||||||
|
promptId?: string;
|
||||||
|
}) {
|
||||||
|
const args = await getStreamTextArguments(props);
|
||||||
|
return _streamText({ ...args, ...props.options });
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import type { ProviderInfo } from '~/types/model';
|
|
||||||
import { createScopedLogger } from '~/utils/logger';
|
import { createScopedLogger } from '~/utils/logger';
|
||||||
|
|
||||||
const logger = createScopedLogger('usePromptEnhancement');
|
const logger = createScopedLogger('usePromptEnhancement');
|
||||||
@ -15,24 +14,15 @@ export function usePromptEnhancer() {
|
|||||||
|
|
||||||
const enhancePrompt = async (
|
const enhancePrompt = async (
|
||||||
input: string,
|
input: string,
|
||||||
setInput: (value: string) => void,
|
setInput: (value: string) => void
|
||||||
model: string,
|
|
||||||
provider: ProviderInfo,
|
|
||||||
apiKeys?: Record<string, string>,
|
|
||||||
) => {
|
) => {
|
||||||
setEnhancingPrompt(true);
|
setEnhancingPrompt(true);
|
||||||
setPromptEnhanced(false);
|
setPromptEnhanced(false);
|
||||||
|
|
||||||
const requestBody: any = {
|
const requestBody: any = {
|
||||||
message: input,
|
message: input,
|
||||||
model,
|
|
||||||
provider,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (apiKeys) {
|
|
||||||
requestBody.apiKeys = apiKeys;
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await fetch('/api/enhancer', {
|
const response = await fetch('/api/enhancer', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify(requestBody),
|
body: JSON.stringify(requestBody),
|
||||||
|
@ -4,10 +4,11 @@ import { assert, stringToBase64, uint8ArrayToBase64 } from "./ReplayProtocolClie
|
|||||||
|
|
||||||
export interface SimulationResource {
|
export interface SimulationResource {
|
||||||
url: string;
|
url: string;
|
||||||
requestBodyBase64: string;
|
requestBodyBase64?: string;
|
||||||
responseBodyBase64: string;
|
responseBodyBase64?: string;
|
||||||
responseStatus: number;
|
responseStatus?: number;
|
||||||
responseHeaders: Record<string, string>;
|
responseHeaders?: Record<string, string>;
|
||||||
|
error?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SimulationInteractionKind {
|
enum SimulationInteractionKind {
|
||||||
@ -122,7 +123,7 @@ export async function getMouseData(iframe: HTMLIFrameElement, position: { x: num
|
|||||||
|
|
||||||
// Add handlers to the current iframe's window.
|
// Add handlers to the current iframe's window.
|
||||||
function addRecordingMessageHandler(messageHandlerId: string) {
|
function addRecordingMessageHandler(messageHandlerId: string) {
|
||||||
const resources: Map<string, SimulationResource> = new Map();
|
const resources: SimulationResource[] = [];
|
||||||
const interactions: SimulationInteraction[] = [];
|
const interactions: SimulationInteraction[] = [];
|
||||||
const indexedDBAccesses: IndexedDBAccess[] = [];
|
const indexedDBAccesses: IndexedDBAccess[] = [];
|
||||||
const localStorageAccesses: LocalStorageAccess[] = [];
|
const localStorageAccesses: LocalStorageAccess[] = [];
|
||||||
@ -131,10 +132,7 @@ function addRecordingMessageHandler(messageHandlerId: string) {
|
|||||||
|
|
||||||
function addTextResource(path: string, text: string) {
|
function addTextResource(path: string, text: string) {
|
||||||
const url = (new URL(path, window.location.href)).href;
|
const url = (new URL(path, window.location.href)).href;
|
||||||
if (resources.has(url)) {
|
resources.push({
|
||||||
return;
|
|
||||||
}
|
|
||||||
resources.set(url, {
|
|
||||||
url,
|
url,
|
||||||
requestBodyBase64: "",
|
requestBodyBase64: "",
|
||||||
responseBodyBase64: stringToBase64(text),
|
responseBodyBase64: stringToBase64(text),
|
||||||
@ -147,7 +145,7 @@ function addRecordingMessageHandler(messageHandlerId: string) {
|
|||||||
return {
|
return {
|
||||||
locationHref: window.location.href,
|
locationHref: window.location.href,
|
||||||
documentUrl: window.location.href,
|
documentUrl: window.location.href,
|
||||||
resources: Array.from(resources.values()),
|
resources,
|
||||||
interactions,
|
interactions,
|
||||||
indexedDBAccesses,
|
indexedDBAccesses,
|
||||||
localStorageAccesses,
|
localStorageAccesses,
|
||||||
@ -475,10 +473,18 @@ function addRecordingMessageHandler(messageHandlerId: string) {
|
|||||||
|
|
||||||
const baseFetch = window.fetch;
|
const baseFetch = window.fetch;
|
||||||
window.fetch = async (info, options) => {
|
window.fetch = async (info, options) => {
|
||||||
const rv = await baseFetch(info, options);
|
|
||||||
const url = info instanceof Request ? info.url : info.toString();
|
const url = info instanceof Request ? info.url : info.toString();
|
||||||
responseToURL.set(rv, url);
|
try {
|
||||||
return createProxy(rv);
|
const rv = await baseFetch(info, options);
|
||||||
|
responseToURL.set(rv, url);
|
||||||
|
return createProxy(rv);
|
||||||
|
} catch (error) {
|
||||||
|
resources.push({
|
||||||
|
url,
|
||||||
|
error: String(error),
|
||||||
|
});
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,16 @@ export function assert(condition: any, message: string = "Assertion failed!"): a
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function defer<T>(): { promise: Promise<T>; resolve: (value: T) => void; reject: (reason?: any) => void } {
|
||||||
|
let resolve: (value: T) => void;
|
||||||
|
let reject: (reason?: any) => void;
|
||||||
|
const promise = new Promise<T>((_resolve, _reject) => {
|
||||||
|
resolve = _resolve;
|
||||||
|
reject = _reject;
|
||||||
|
});
|
||||||
|
return { promise, resolve: resolve!, reject: reject! };
|
||||||
|
}
|
||||||
|
|
||||||
export function uint8ArrayToBase64(data: Uint8Array) {
|
export function uint8ArrayToBase64(data: Uint8Array) {
|
||||||
let str = "";
|
let str = "";
|
||||||
for (const byte of data) {
|
for (const byte of data) {
|
||||||
|
@ -1,36 +1,14 @@
|
|||||||
import { type ActionFunctionArgs } from '@remix-run/cloudflare';
|
import { type ActionFunctionArgs } from '@remix-run/cloudflare';
|
||||||
import { createDataStream } from 'ai';
|
|
||||||
import { MAX_RESPONSE_SEGMENTS, MAX_TOKENS } from '~/lib/.server/llm/constants';
|
|
||||||
import { CONTINUE_PROMPT } from '~/lib/common/prompts/prompts';
|
|
||||||
import { streamText, type Messages, type StreamingOptions } from '~/lib/.server/llm/stream-text';
|
|
||||||
import SwitchableStream from '~/lib/.server/llm/switchable-stream';
|
|
||||||
import type { IProviderSetting } from '~/types/model';
|
|
||||||
import { type SimulationChatMessage, type SimulationPromptClientData, performSimulationPrompt } from '~/lib/replay/SimulationPrompt';
|
import { type SimulationChatMessage, type SimulationPromptClientData, performSimulationPrompt } from '~/lib/replay/SimulationPrompt';
|
||||||
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 Messages } from '~/lib/.server/llm/stream-text';
|
||||||
|
import { chatAnthropic } from '~/lib/.server/llm/chat-anthropic';
|
||||||
|
|
||||||
export async function action(args: ActionFunctionArgs) {
|
export async function action(args: ActionFunctionArgs) {
|
||||||
return chatAction(args);
|
return chatAction(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseCookies(cookieHeader: string): Record<string, string> {
|
|
||||||
const cookies: Record<string, string> = {};
|
|
||||||
|
|
||||||
const items = cookieHeader.split(';').map((cookie) => cookie.trim());
|
|
||||||
|
|
||||||
items.forEach((item) => {
|
|
||||||
const [name, ...rest] = item.split('=');
|
|
||||||
|
|
||||||
if (name && rest) {
|
|
||||||
const decodedName = decodeURIComponent(name.trim());
|
|
||||||
const decodedValue = decodeURIComponent(rest.join('=').trim());
|
|
||||||
cookies[decodedName] = decodedValue;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return cookies;
|
|
||||||
}
|
|
||||||
|
|
||||||
function extractMessageContent(baseContent: any): string {
|
function extractMessageContent(baseContent: any): string {
|
||||||
let content = baseContent;
|
let content = baseContent;
|
||||||
|
|
||||||
@ -68,138 +46,66 @@ async function chatAction({ context, request }: ActionFunctionArgs) {
|
|||||||
simulationClientData?: SimulationPromptClientData;
|
simulationClientData?: SimulationPromptClientData;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
let finished: (v?: any) => void;
|
||||||
|
context.cloudflare.ctx.waitUntil(new Promise((resolve) => finished = resolve));
|
||||||
|
|
||||||
console.log("SimulationClientData", simulationClientData);
|
console.log("SimulationClientData", simulationClientData);
|
||||||
|
|
||||||
const cookieHeader = request.headers.get('Cookie');
|
|
||||||
const apiKeys = JSON.parse(parseCookies(cookieHeader || '').apiKeys || '{}');
|
|
||||||
const providerSettings: Record<string, IProviderSetting> = JSON.parse(
|
|
||||||
parseCookies(cookieHeader || '').providers || '{}',
|
|
||||||
);
|
|
||||||
|
|
||||||
const stream = new SwitchableStream();
|
|
||||||
|
|
||||||
const cumulativeUsage = {
|
|
||||||
completionTokens: 0,
|
|
||||||
promptTokens: 0,
|
|
||||||
totalTokens: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (simulationClientData) {
|
const { system, messages: coreMessages } = await getStreamTextArguments({
|
||||||
const chatHistory: SimulationChatMessage[] = [];
|
|
||||||
for (const { role, content } of messages) {
|
|
||||||
chatHistory.push({ role, content: extractMessageContent(content) });
|
|
||||||
}
|
|
||||||
const lastHistoryMessage = chatHistory.pop();
|
|
||||||
assert(lastHistoryMessage?.role == "user", "Last message in chat history must be a user message");
|
|
||||||
const userPrompt = lastHistoryMessage.content;
|
|
||||||
|
|
||||||
const anthropicApiKey = process.env.ANTHROPIC_API_KEY;
|
|
||||||
if (!anthropicApiKey) {
|
|
||||||
throw new Error("Anthropic API key is not set");
|
|
||||||
}
|
|
||||||
|
|
||||||
const { message, fileChanges } = await performSimulationPrompt(simulationClientData, userPrompt, chatHistory, anthropicApiKey);
|
|
||||||
|
|
||||||
const resultStream = new ReadableStream({
|
|
||||||
async start(controller) {
|
|
||||||
const chatController = new ChatStreamController(controller);
|
|
||||||
|
|
||||||
chatController.writeText(message + "\n");
|
|
||||||
chatController.writeFileChanges("Update Files", fileChanges);
|
|
||||||
|
|
||||||
/*
|
|
||||||
chatController.writeText("Hello World\n");
|
|
||||||
chatController.writeText("Hello World 2\n");
|
|
||||||
chatController.writeText("Hello\n World 3\n");
|
|
||||||
chatController.writeFileChanges("Rewrite Files", [{filePath: "src/services/llm.ts", contents: "FILE_CONTENTS_FIXME" }]);
|
|
||||||
chatController.writeAnnotation("usage", { completionTokens: 10, promptTokens: 20, totalTokens: 30 });
|
|
||||||
*/
|
|
||||||
|
|
||||||
controller.close();
|
|
||||||
setTimeout(() => stream.close(), 1000);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
stream.switchSource(resultStream);
|
|
||||||
|
|
||||||
return new Response(stream.readable, {
|
|
||||||
status: 200,
|
|
||||||
headers: {
|
|
||||||
contentType: 'text/plain; charset=utf-8',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const options: StreamingOptions = {
|
|
||||||
toolChoice: 'none',
|
|
||||||
onFinish: async ({ text: content, finishReason, usage }) => {
|
|
||||||
console.log("QueryModelFinished", usage, content);
|
|
||||||
|
|
||||||
if (usage) {
|
|
||||||
cumulativeUsage.completionTokens += usage.completionTokens || 0;
|
|
||||||
cumulativeUsage.promptTokens += usage.promptTokens || 0;
|
|
||||||
cumulativeUsage.totalTokens += usage.totalTokens || 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (finishReason !== 'length') {
|
|
||||||
return stream
|
|
||||||
.switchSource(
|
|
||||||
createDataStream({
|
|
||||||
async execute(dataStream) {
|
|
||||||
dataStream.writeMessageAnnotation({
|
|
||||||
type: 'usage',
|
|
||||||
value: {
|
|
||||||
completionTokens: cumulativeUsage.completionTokens,
|
|
||||||
promptTokens: cumulativeUsage.promptTokens,
|
|
||||||
totalTokens: cumulativeUsage.totalTokens,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onError: (error: any) => `Custom error: ${error.message}`,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.then(() => stream.close());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stream.switches >= MAX_RESPONSE_SEGMENTS) {
|
|
||||||
throw Error('Cannot continue message: Maximum segments reached');
|
|
||||||
}
|
|
||||||
|
|
||||||
const switchesLeft = MAX_RESPONSE_SEGMENTS - stream.switches;
|
|
||||||
|
|
||||||
console.log(`Reached max token limit (${MAX_TOKENS}): Continuing message (${switchesLeft} switches left)`);
|
|
||||||
|
|
||||||
messages.push({ role: 'assistant', content });
|
|
||||||
messages.push({ role: 'user', content: CONTINUE_PROMPT });
|
|
||||||
|
|
||||||
const result = await streamText({
|
|
||||||
messages,
|
|
||||||
env: context.cloudflare.env,
|
|
||||||
options,
|
|
||||||
apiKeys,
|
|
||||||
files,
|
|
||||||
providerSettings,
|
|
||||||
promptId,
|
|
||||||
});
|
|
||||||
|
|
||||||
return stream.switchSource(result.toDataStream());
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const result = await streamText({
|
|
||||||
messages,
|
messages,
|
||||||
env: context.cloudflare.env,
|
env: context.cloudflare.env,
|
||||||
options,
|
apiKeys: {},
|
||||||
apiKeys,
|
|
||||||
files,
|
files,
|
||||||
providerSettings,
|
providerSettings: undefined,
|
||||||
promptId,
|
promptId,
|
||||||
});
|
});
|
||||||
|
|
||||||
stream.switchSource(result.toDataStream());
|
const anthropicApiKey = context.cloudflare.env.ANTHROPIC_API_KEY;
|
||||||
|
if (!anthropicApiKey) {
|
||||||
|
throw new Error("Anthropic API key is not set");
|
||||||
|
}
|
||||||
|
|
||||||
return new Response(stream.readable, {
|
const resultStream = new ReadableStream({
|
||||||
|
async start(controller) {
|
||||||
|
const chatController = new ChatStreamController(controller);
|
||||||
|
|
||||||
|
/*
|
||||||
|
chatController.writeText("Hello World\n");
|
||||||
|
chatController.writeText("Hello World 2\n");
|
||||||
|
chatController.writeText("Hello\n World 3\n");
|
||||||
|
chatController.writeFileChanges("Rewrite Files", [{filePath: "src/services/llm.ts", contents: "FILE_CONTENTS_FIXME" }]);
|
||||||
|
chatController.writeAnnotation("usage", { completionTokens: 10, promptTokens: 20, totalTokens: 30 });
|
||||||
|
*/
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (simulationClientData) {
|
||||||
|
const chatHistory: SimulationChatMessage[] = [];
|
||||||
|
for (const { role, content } of messages) {
|
||||||
|
chatHistory.push({ role, content: extractMessageContent(content) });
|
||||||
|
}
|
||||||
|
const lastHistoryMessage = chatHistory.pop();
|
||||||
|
assert(lastHistoryMessage?.role == "user", "Last message in chat history must be a user message");
|
||||||
|
const userPrompt = lastHistoryMessage.content;
|
||||||
|
|
||||||
|
const { message, fileChanges } = await performSimulationPrompt(simulationClientData, userPrompt, chatHistory, anthropicApiKey);
|
||||||
|
|
||||||
|
chatController.writeText(message + "\n");
|
||||||
|
chatController.writeFileChanges("Update Files", fileChanges);
|
||||||
|
} else {
|
||||||
|
await chatAnthropic(chatController, anthropicApiKey, system, coreMessages);
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error(error);
|
||||||
|
chatController.writeText("Error: " + error.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
controller.close();
|
||||||
|
setTimeout(finished, 1000);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return new Response(resultStream, {
|
||||||
status: 200,
|
status: 200,
|
||||||
headers: {
|
headers: {
|
||||||
contentType: 'text/plain; charset=utf-8',
|
contentType: 'text/plain; charset=utf-8',
|
||||||
|
@ -10,13 +10,16 @@ export interface ChatFileChange {
|
|||||||
|
|
||||||
export class ChatStreamController {
|
export class ChatStreamController {
|
||||||
private controller: ReadableStreamDefaultController;
|
private controller: ReadableStreamDefaultController;
|
||||||
|
private encoder: TextEncoder;
|
||||||
|
|
||||||
constructor(controller: ReadableStreamDefaultController) {
|
constructor(controller: ReadableStreamDefaultController) {
|
||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
|
this.encoder = new TextEncoder();
|
||||||
}
|
}
|
||||||
|
|
||||||
writeText(text: string) {
|
writeText(text: string) {
|
||||||
this.controller.enqueue(`0:${JSON.stringify(text)}\n`);
|
const data = this.encoder.encode(`0:${JSON.stringify(text)}\n`);
|
||||||
|
this.controller.enqueue(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
writeFileChanges(title: string, fileChanges: ChatFileChange[]) {
|
writeFileChanges(title: string, fileChanges: ChatFileChange[]) {
|
||||||
@ -29,6 +32,11 @@ export class ChatStreamController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
writeAnnotation(type: string, value: any) {
|
writeAnnotation(type: string, value: any) {
|
||||||
this.controller.enqueue(`8:[{"type":"${type}","value":${JSON.stringify(value)}}]\n`);
|
const data = this.encoder.encode(`8:[{"type":"${type}","value":${JSON.stringify(value)}}]\n`);
|
||||||
|
this.controller.enqueue(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
writeUsage({ completionTokens, promptTokens }: { completionTokens: number, promptTokens: number }) {
|
||||||
|
this.writeAnnotation("usage", { completionTokens, promptTokens, totalTokens: completionTokens + promptTokens });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
"@ai-sdk/google": "^0.0.52",
|
"@ai-sdk/google": "^0.0.52",
|
||||||
"@ai-sdk/mistral": "^0.0.43",
|
"@ai-sdk/mistral": "^0.0.43",
|
||||||
"@ai-sdk/openai": "^0.0.66",
|
"@ai-sdk/openai": "^0.0.66",
|
||||||
|
"@anthropic-ai/sdk": "^0.33.1",
|
||||||
"@codemirror/autocomplete": "^6.18.3",
|
"@codemirror/autocomplete": "^6.18.3",
|
||||||
"@codemirror/commands": "^6.7.1",
|
"@codemirror/commands": "^6.7.1",
|
||||||
"@codemirror/lang-cpp": "^6.0.2",
|
"@codemirror/lang-cpp": "^6.0.2",
|
||||||
|
133
pnpm-lock.yaml
133
pnpm-lock.yaml
@ -26,6 +26,9 @@ importers:
|
|||||||
'@ai-sdk/openai':
|
'@ai-sdk/openai':
|
||||||
specifier: ^0.0.66
|
specifier: ^0.0.66
|
||||||
version: 0.0.66(zod@3.23.8)
|
version: 0.0.66(zod@3.23.8)
|
||||||
|
'@anthropic-ai/sdk':
|
||||||
|
specifier: ^0.33.1
|
||||||
|
version: 0.33.1
|
||||||
'@codemirror/autocomplete':
|
'@codemirror/autocomplete':
|
||||||
specifier: ^6.18.3
|
specifier: ^6.18.3
|
||||||
version: 6.18.3(@codemirror/language@6.10.6)(@codemirror/state@6.4.1)(@codemirror/view@6.35.0)(@lezer/common@1.2.3)
|
version: 6.18.3(@codemirror/language@6.10.6)(@codemirror/state@6.4.1)(@codemirror/view@6.35.0)(@lezer/common@1.2.3)
|
||||||
@ -435,6 +438,9 @@ packages:
|
|||||||
'@antfu/utils@0.7.10':
|
'@antfu/utils@0.7.10':
|
||||||
resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==}
|
resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==}
|
||||||
|
|
||||||
|
'@anthropic-ai/sdk@0.33.1':
|
||||||
|
resolution: {integrity: sha512-VrlbxiAdVRGuKP2UQlCnsShDHJKWepzvfRCkZMpU+oaUdKLpOfmylLMRojGrAgebV+kDtPjewCVP0laHXg+vsA==}
|
||||||
|
|
||||||
'@babel/code-frame@7.26.2':
|
'@babel/code-frame@7.26.2':
|
||||||
resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==}
|
resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
@ -2126,9 +2132,15 @@ packages:
|
|||||||
'@types/ms@0.7.34':
|
'@types/ms@0.7.34':
|
||||||
resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==}
|
resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==}
|
||||||
|
|
||||||
|
'@types/node-fetch@2.6.12':
|
||||||
|
resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==}
|
||||||
|
|
||||||
'@types/node-forge@1.3.11':
|
'@types/node-forge@1.3.11':
|
||||||
resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==}
|
resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==}
|
||||||
|
|
||||||
|
'@types/node@18.19.70':
|
||||||
|
resolution: {integrity: sha512-RE+K0+KZoEpDUbGGctnGdkrLFwi1eYKTlIHNl2Um98mUkGsm1u2Ff6Ltd0e8DktTtC98uy7rSj+hO8t/QuLoVQ==}
|
||||||
|
|
||||||
'@types/node@22.10.1':
|
'@types/node@22.10.1':
|
||||||
resolution: {integrity: sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==}
|
resolution: {integrity: sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==}
|
||||||
|
|
||||||
@ -2396,6 +2408,10 @@ packages:
|
|||||||
engines: {node: '>=0.4.0'}
|
engines: {node: '>=0.4.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
agentkeepalive@4.6.0:
|
||||||
|
resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==}
|
||||||
|
engines: {node: '>= 8.0.0'}
|
||||||
|
|
||||||
aggregate-error@3.1.0:
|
aggregate-error@3.1.0:
|
||||||
resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
|
resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@ -2468,6 +2484,9 @@ packages:
|
|||||||
async-lock@1.4.1:
|
async-lock@1.4.1:
|
||||||
resolution: {integrity: sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==}
|
resolution: {integrity: sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==}
|
||||||
|
|
||||||
|
asynckit@0.4.0:
|
||||||
|
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||||
|
|
||||||
available-typed-arrays@1.0.7:
|
available-typed-arrays@1.0.7:
|
||||||
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
|
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@ -2692,6 +2711,10 @@ packages:
|
|||||||
colorjs.io@0.5.2:
|
colorjs.io@0.5.2:
|
||||||
resolution: {integrity: sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==}
|
resolution: {integrity: sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==}
|
||||||
|
|
||||||
|
combined-stream@1.0.8:
|
||||||
|
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||||
|
engines: {node: '>= 0.8'}
|
||||||
|
|
||||||
comma-separated-tokens@2.0.3:
|
comma-separated-tokens@2.0.3:
|
||||||
resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
|
resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
|
||||||
|
|
||||||
@ -2869,6 +2892,10 @@ packages:
|
|||||||
defu@6.1.4:
|
defu@6.1.4:
|
||||||
resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
|
resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
|
||||||
|
|
||||||
|
delayed-stream@1.0.0:
|
||||||
|
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
||||||
|
engines: {node: '>=0.4.0'}
|
||||||
|
|
||||||
depd@2.0.0:
|
depd@2.0.0:
|
||||||
resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
|
resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
@ -3246,10 +3273,21 @@ packages:
|
|||||||
resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==}
|
resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
|
|
||||||
|
form-data-encoder@1.7.2:
|
||||||
|
resolution: {integrity: sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==}
|
||||||
|
|
||||||
|
form-data@4.0.1:
|
||||||
|
resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==}
|
||||||
|
engines: {node: '>= 6'}
|
||||||
|
|
||||||
format@0.2.2:
|
format@0.2.2:
|
||||||
resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==}
|
resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==}
|
||||||
engines: {node: '>=0.4.x'}
|
engines: {node: '>=0.4.x'}
|
||||||
|
|
||||||
|
formdata-node@4.4.1:
|
||||||
|
resolution: {integrity: sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==}
|
||||||
|
engines: {node: '>= 12.20'}
|
||||||
|
|
||||||
formdata-polyfill@4.0.10:
|
formdata-polyfill@4.0.10:
|
||||||
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
|
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
|
||||||
engines: {node: '>=12.20.0'}
|
engines: {node: '>=12.20.0'}
|
||||||
@ -3463,6 +3501,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
|
resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
|
||||||
engines: {node: '>=10.17.0'}
|
engines: {node: '>=10.17.0'}
|
||||||
|
|
||||||
|
humanize-ms@1.2.1:
|
||||||
|
resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==}
|
||||||
|
|
||||||
husky@9.1.7:
|
husky@9.1.7:
|
||||||
resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==}
|
resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
@ -4232,6 +4273,15 @@ packages:
|
|||||||
node-fetch-native@1.6.4:
|
node-fetch-native@1.6.4:
|
||||||
resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==}
|
resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==}
|
||||||
|
|
||||||
|
node-fetch@2.7.0:
|
||||||
|
resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
|
||||||
|
engines: {node: 4.x || >=6.0.0}
|
||||||
|
peerDependencies:
|
||||||
|
encoding: ^0.1.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
encoding:
|
||||||
|
optional: true
|
||||||
|
|
||||||
node-fetch@3.3.2:
|
node-fetch@3.3.2:
|
||||||
resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==}
|
resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==}
|
||||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||||
@ -5304,6 +5354,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
|
resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
|
tr46@0.0.3:
|
||||||
|
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
|
||||||
|
|
||||||
trim-lines@3.0.1:
|
trim-lines@3.0.1:
|
||||||
resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
|
resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
|
||||||
|
|
||||||
@ -5377,6 +5430,9 @@ packages:
|
|||||||
unconfig@0.5.5:
|
unconfig@0.5.5:
|
||||||
resolution: {integrity: sha512-VQZ5PT9HDX+qag0XdgQi8tJepPhXiR/yVOkn707gJDKo31lGjRilPREiQJ9Z6zd/Ugpv6ZvO5VxVIcatldYcNQ==}
|
resolution: {integrity: sha512-VQZ5PT9HDX+qag0XdgQi8tJepPhXiR/yVOkn707gJDKo31lGjRilPREiQJ9Z6zd/Ugpv6ZvO5VxVIcatldYcNQ==}
|
||||||
|
|
||||||
|
undici-types@5.26.5:
|
||||||
|
resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
|
||||||
|
|
||||||
undici-types@6.20.0:
|
undici-types@6.20.0:
|
||||||
resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==}
|
resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==}
|
||||||
|
|
||||||
@ -5667,6 +5723,16 @@ packages:
|
|||||||
resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==}
|
resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
|
|
||||||
|
web-streams-polyfill@4.0.0-beta.3:
|
||||||
|
resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==}
|
||||||
|
engines: {node: '>= 14'}
|
||||||
|
|
||||||
|
webidl-conversions@3.0.1:
|
||||||
|
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
|
||||||
|
|
||||||
|
whatwg-url@5.0.0:
|
||||||
|
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
|
||||||
|
|
||||||
which-typed-array@1.1.16:
|
which-typed-array@1.1.16:
|
||||||
resolution: {integrity: sha512-g+N+GAWiRj66DngFwHvISJd+ITsyphZvD1vChfVg6cEdnzy53GzB3oy0fUNlvhz7H7+MiqhYr26qxQShCpKTTQ==}
|
resolution: {integrity: sha512-g+N+GAWiRj66DngFwHvISJd+ITsyphZvD1vChfVg6cEdnzy53GzB3oy0fUNlvhz7H7+MiqhYr26qxQShCpKTTQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@ -5904,6 +5970,18 @@ snapshots:
|
|||||||
|
|
||||||
'@antfu/utils@0.7.10': {}
|
'@antfu/utils@0.7.10': {}
|
||||||
|
|
||||||
|
'@anthropic-ai/sdk@0.33.1':
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 18.19.70
|
||||||
|
'@types/node-fetch': 2.6.12
|
||||||
|
abort-controller: 3.0.0
|
||||||
|
agentkeepalive: 4.6.0
|
||||||
|
form-data-encoder: 1.7.2
|
||||||
|
formdata-node: 4.4.1
|
||||||
|
node-fetch: 2.7.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- encoding
|
||||||
|
|
||||||
'@babel/code-frame@7.26.2':
|
'@babel/code-frame@7.26.2':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/helper-validator-identifier': 7.25.9
|
'@babel/helper-validator-identifier': 7.25.9
|
||||||
@ -7562,10 +7640,19 @@ snapshots:
|
|||||||
|
|
||||||
'@types/ms@0.7.34': {}
|
'@types/ms@0.7.34': {}
|
||||||
|
|
||||||
|
'@types/node-fetch@2.6.12':
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 22.10.1
|
||||||
|
form-data: 4.0.1
|
||||||
|
|
||||||
'@types/node-forge@1.3.11':
|
'@types/node-forge@1.3.11':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 22.10.1
|
'@types/node': 22.10.1
|
||||||
|
|
||||||
|
'@types/node@18.19.70':
|
||||||
|
dependencies:
|
||||||
|
undici-types: 5.26.5
|
||||||
|
|
||||||
'@types/node@22.10.1':
|
'@types/node@22.10.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 6.20.0
|
undici-types: 6.20.0
|
||||||
@ -7975,6 +8062,10 @@ snapshots:
|
|||||||
|
|
||||||
acorn@8.14.0: {}
|
acorn@8.14.0: {}
|
||||||
|
|
||||||
|
agentkeepalive@4.6.0:
|
||||||
|
dependencies:
|
||||||
|
humanize-ms: 1.2.1
|
||||||
|
|
||||||
aggregate-error@3.1.0:
|
aggregate-error@3.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
clean-stack: 2.2.0
|
clean-stack: 2.2.0
|
||||||
@ -8049,6 +8140,8 @@ snapshots:
|
|||||||
|
|
||||||
async-lock@1.4.1: {}
|
async-lock@1.4.1: {}
|
||||||
|
|
||||||
|
asynckit@0.4.0: {}
|
||||||
|
|
||||||
available-typed-arrays@1.0.7:
|
available-typed-arrays@1.0.7:
|
||||||
dependencies:
|
dependencies:
|
||||||
possible-typed-array-names: 1.0.0
|
possible-typed-array-names: 1.0.0
|
||||||
@ -8307,6 +8400,10 @@ snapshots:
|
|||||||
|
|
||||||
colorjs.io@0.5.2: {}
|
colorjs.io@0.5.2: {}
|
||||||
|
|
||||||
|
combined-stream@1.0.8:
|
||||||
|
dependencies:
|
||||||
|
delayed-stream: 1.0.0
|
||||||
|
|
||||||
comma-separated-tokens@2.0.3: {}
|
comma-separated-tokens@2.0.3: {}
|
||||||
|
|
||||||
common-tags@1.8.2: {}
|
common-tags@1.8.2: {}
|
||||||
@ -8455,6 +8552,8 @@ snapshots:
|
|||||||
|
|
||||||
defu@6.1.4: {}
|
defu@6.1.4: {}
|
||||||
|
|
||||||
|
delayed-stream@1.0.0: {}
|
||||||
|
|
||||||
depd@2.0.0: {}
|
depd@2.0.0: {}
|
||||||
|
|
||||||
dequal@2.0.3: {}
|
dequal@2.0.3: {}
|
||||||
@ -8963,8 +9062,21 @@ snapshots:
|
|||||||
cross-spawn: 7.0.6
|
cross-spawn: 7.0.6
|
||||||
signal-exit: 4.1.0
|
signal-exit: 4.1.0
|
||||||
|
|
||||||
|
form-data-encoder@1.7.2: {}
|
||||||
|
|
||||||
|
form-data@4.0.1:
|
||||||
|
dependencies:
|
||||||
|
asynckit: 0.4.0
|
||||||
|
combined-stream: 1.0.8
|
||||||
|
mime-types: 2.1.35
|
||||||
|
|
||||||
format@0.2.2: {}
|
format@0.2.2: {}
|
||||||
|
|
||||||
|
formdata-node@4.4.1:
|
||||||
|
dependencies:
|
||||||
|
node-domexception: 1.0.0
|
||||||
|
web-streams-polyfill: 4.0.0-beta.3
|
||||||
|
|
||||||
formdata-polyfill@4.0.10:
|
formdata-polyfill@4.0.10:
|
||||||
dependencies:
|
dependencies:
|
||||||
fetch-blob: 3.2.0
|
fetch-blob: 3.2.0
|
||||||
@ -9249,6 +9361,10 @@ snapshots:
|
|||||||
|
|
||||||
human-signals@2.1.0: {}
|
human-signals@2.1.0: {}
|
||||||
|
|
||||||
|
humanize-ms@1.2.1:
|
||||||
|
dependencies:
|
||||||
|
ms: 2.1.3
|
||||||
|
|
||||||
husky@9.1.7: {}
|
husky@9.1.7: {}
|
||||||
|
|
||||||
iconv-lite@0.4.24:
|
iconv-lite@0.4.24:
|
||||||
@ -10354,6 +10470,10 @@ snapshots:
|
|||||||
|
|
||||||
node-fetch-native@1.6.4: {}
|
node-fetch-native@1.6.4: {}
|
||||||
|
|
||||||
|
node-fetch@2.7.0:
|
||||||
|
dependencies:
|
||||||
|
whatwg-url: 5.0.0
|
||||||
|
|
||||||
node-fetch@3.3.2:
|
node-fetch@3.3.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
data-uri-to-buffer: 4.0.1
|
data-uri-to-buffer: 4.0.1
|
||||||
@ -11497,6 +11617,8 @@ snapshots:
|
|||||||
|
|
||||||
totalist@3.0.1: {}
|
totalist@3.0.1: {}
|
||||||
|
|
||||||
|
tr46@0.0.3: {}
|
||||||
|
|
||||||
trim-lines@3.0.1: {}
|
trim-lines@3.0.1: {}
|
||||||
|
|
||||||
trough@2.2.0: {}
|
trough@2.2.0: {}
|
||||||
@ -11562,6 +11684,8 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
undici-types@5.26.5: {}
|
||||||
|
|
||||||
undici-types@6.20.0: {}
|
undici-types@6.20.0: {}
|
||||||
|
|
||||||
undici@5.28.4:
|
undici@5.28.4:
|
||||||
@ -11920,6 +12044,15 @@ snapshots:
|
|||||||
|
|
||||||
web-streams-polyfill@3.3.3: {}
|
web-streams-polyfill@3.3.3: {}
|
||||||
|
|
||||||
|
web-streams-polyfill@4.0.0-beta.3: {}
|
||||||
|
|
||||||
|
webidl-conversions@3.0.1: {}
|
||||||
|
|
||||||
|
whatwg-url@5.0.0:
|
||||||
|
dependencies:
|
||||||
|
tr46: 0.0.3
|
||||||
|
webidl-conversions: 3.0.1
|
||||||
|
|
||||||
which-typed-array@1.1.16:
|
which-typed-array@1.1.16:
|
||||||
dependencies:
|
dependencies:
|
||||||
available-typed-arrays: 1.0.7
|
available-typed-arrays: 1.0.7
|
||||||
|
Loading…
Reference in New Issue
Block a user