mirror of
https://github.com/coleam00/bolt.new-any-llm
synced 2024-12-27 22:33:03 +00:00
Fix linting issues
This commit is contained in:
parent
fe3e2ebddf
commit
7d8f811886
@ -10,6 +10,7 @@ interface APIKeyManagerProps {
|
||||
labelForGetApiKey?: string;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
export const APIKeyManager: React.FC<APIKeyManagerProps> = ({ provider, apiKey, setApiKey }) => {
|
||||
const [isEditing, setIsEditing] = useState(false);
|
||||
const [tempKey, setTempKey] = useState(apiKey);
|
||||
|
@ -9,7 +9,7 @@ import { Menu } from '~/components/sidebar/Menu.client';
|
||||
import { IconButton } from '~/components/ui/IconButton';
|
||||
import { Workbench } from '~/components/workbench/Workbench.client';
|
||||
import { classNames } from '~/utils/classNames';
|
||||
import { MODEL_LIST, DEFAULT_PROVIDER, PROVIDER_LIST, initializeModelList } from '~/utils/constants';
|
||||
import { MODEL_LIST, PROVIDER_LIST, initializeModelList } from '~/utils/constants';
|
||||
import { Messages } from './Messages.client';
|
||||
import { SendButton } from './SendButton.client';
|
||||
import { useState } from 'react';
|
||||
@ -27,22 +27,25 @@ const EXAMPLE_PROMPTS = [
|
||||
{ text: 'How do I center a div?' },
|
||||
];
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const providerList = PROVIDER_LIST;
|
||||
|
||||
// @ts-ignore TODO: Introduce proper types
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const ModelSelector = ({ model, setModel, provider, setProvider, modelList, providerList, apiKeys }) => {
|
||||
return (
|
||||
<div className="mb-2 flex gap-2 flex-col sm:flex-row">
|
||||
<select
|
||||
value={provider?.name}
|
||||
onChange={(e) => {
|
||||
setProvider(providerList.find((p) => p.name === e.target.value));
|
||||
setProvider(providerList.find((p: ProviderInfo) => p.name === e.target.value));
|
||||
|
||||
const firstModel = [...modelList].find((m) => m.provider == e.target.value);
|
||||
setModel(firstModel ? firstModel.name : '');
|
||||
}}
|
||||
className="flex-1 p-2 rounded-lg border border-bolt-elements-borderColor bg-bolt-elements-prompt-background text-bolt-elements-textPrimary focus:outline-none focus:ring-2 focus:ring-bolt-elements-focus transition-all"
|
||||
>
|
||||
{providerList.map((provider) => (
|
||||
{providerList.map((provider: ProviderInfo) => (
|
||||
<option key={provider.name} value={provider.name}>
|
||||
{provider.name}
|
||||
</option>
|
||||
|
@ -2,7 +2,6 @@ import { motion, type Variants } from 'framer-motion';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
import { Dialog, DialogButton, DialogDescription, DialogRoot, DialogTitle } from '~/components/ui/Dialog';
|
||||
import { IconButton } from '~/components/ui/IconButton';
|
||||
import { ThemeSwitch } from '~/components/ui/ThemeSwitch';
|
||||
import { db, deleteById, getAll, chatId, type ChatHistoryItem, useChatHistory } from '~/lib/persistence';
|
||||
import { cubicEasingFn } from '~/utils/easings';
|
||||
|
@ -52,7 +52,7 @@ export function getBaseURL(cloudflareEnv: Env, provider: string) {
|
||||
return env.OPENAI_LIKE_API_BASE_URL || cloudflareEnv.OPENAI_LIKE_API_BASE_URL;
|
||||
case 'LMStudio':
|
||||
return env.LMSTUDIO_API_BASE_URL || cloudflareEnv.LMSTUDIO_API_BASE_URL || 'http://localhost:1234';
|
||||
case 'Ollama':
|
||||
case 'Ollama': {
|
||||
let baseUrl = env.OLLAMA_API_BASE_URL || cloudflareEnv.OLLAMA_API_BASE_URL || 'http://localhost:11434';
|
||||
|
||||
if (env.RUNNING_IN_DOCKER === 'true') {
|
||||
@ -60,6 +60,7 @@ export function getBaseURL(cloudflareEnv: Env, provider: string) {
|
||||
}
|
||||
|
||||
return baseUrl;
|
||||
}
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
|
@ -11,14 +11,14 @@ import { createOpenRouter } from '@openrouter/ai-sdk-provider';
|
||||
import { createMistral } from '@ai-sdk/mistral';
|
||||
import { createCohere } from '@ai-sdk/cohere';
|
||||
|
||||
export function getAnthropicModel(apiKey: string, model: string) {
|
||||
export function getAnthropicModel(apiKey: string | undefined, model: string) {
|
||||
const anthropic = createAnthropic({
|
||||
apiKey,
|
||||
});
|
||||
|
||||
return anthropic(model);
|
||||
}
|
||||
export function getOpenAILikeModel(baseURL: string, apiKey: string, model: string) {
|
||||
export function getOpenAILikeModel(baseURL: string, apiKey: string | undefined, model: string) {
|
||||
const openai = createOpenAI({
|
||||
baseURL,
|
||||
apiKey,
|
||||
@ -27,7 +27,7 @@ export function getOpenAILikeModel(baseURL: string, apiKey: string, model: strin
|
||||
return openai(model);
|
||||
}
|
||||
|
||||
export function getCohereAIModel(apiKey: string, model: string) {
|
||||
export function getCohereAIModel(apiKey: string | undefined, model: string) {
|
||||
const cohere = createCohere({
|
||||
apiKey,
|
||||
});
|
||||
@ -35,7 +35,7 @@ export function getCohereAIModel(apiKey: string, model: string) {
|
||||
return cohere(model);
|
||||
}
|
||||
|
||||
export function getOpenAIModel(apiKey: string, model: string) {
|
||||
export function getOpenAIModel(apiKey: string | undefined, model: string) {
|
||||
const openai = createOpenAI({
|
||||
apiKey,
|
||||
});
|
||||
@ -43,7 +43,7 @@ export function getOpenAIModel(apiKey: string, model: string) {
|
||||
return openai(model);
|
||||
}
|
||||
|
||||
export function getMistralModel(apiKey: string, model: string) {
|
||||
export function getMistralModel(apiKey: string | undefined, model: string) {
|
||||
const mistral = createMistral({
|
||||
apiKey,
|
||||
});
|
||||
@ -51,7 +51,7 @@ export function getMistralModel(apiKey: string, model: string) {
|
||||
return mistral(model);
|
||||
}
|
||||
|
||||
export function getGoogleModel(apiKey: string, model: string) {
|
||||
export function getGoogleModel(apiKey: string | undefined, model: string) {
|
||||
const google = createGoogleGenerativeAI({
|
||||
apiKey,
|
||||
});
|
||||
@ -59,7 +59,7 @@ export function getGoogleModel(apiKey: string, model: string) {
|
||||
return google(model);
|
||||
}
|
||||
|
||||
export function getGroqModel(apiKey: string, model: string) {
|
||||
export function getGroqModel(apiKey: string | undefined, model: string) {
|
||||
const openai = createOpenAI({
|
||||
baseURL: 'https://api.groq.com/openai/v1',
|
||||
apiKey,
|
||||
@ -68,7 +68,7 @@ export function getGroqModel(apiKey: string, model: string) {
|
||||
return openai(model);
|
||||
}
|
||||
|
||||
export function getHuggingFaceModel(apiKey: string, model: string) {
|
||||
export function getHuggingFaceModel(apiKey: string | undefined, model: string) {
|
||||
const openai = createOpenAI({
|
||||
baseURL: 'https://api-inference.huggingface.co/v1/',
|
||||
apiKey,
|
||||
@ -78,16 +78,16 @@ export function getHuggingFaceModel(apiKey: string, model: string) {
|
||||
}
|
||||
|
||||
export function getOllamaModel(baseURL: string, model: string) {
|
||||
const Ollama = ollama(model, {
|
||||
const ollamaInstance = ollama(model, {
|
||||
numCtx: 32768,
|
||||
});
|
||||
|
||||
Ollama.config.baseURL = `${baseURL}/api`;
|
||||
ollamaInstance.config.baseURL = `${baseURL}/api`;
|
||||
|
||||
return Ollama;
|
||||
return ollamaInstance;
|
||||
}
|
||||
|
||||
export function getDeepseekModel(apiKey: string, model: string) {
|
||||
export function getDeepseekModel(apiKey: string | undefined, model: string) {
|
||||
const openai = createOpenAI({
|
||||
baseURL: 'https://api.deepseek.com/beta',
|
||||
apiKey,
|
||||
@ -96,7 +96,7 @@ export function getDeepseekModel(apiKey: string, model: string) {
|
||||
return openai(model);
|
||||
}
|
||||
|
||||
export function getOpenRouterModel(apiKey: string, model: string) {
|
||||
export function getOpenRouterModel(apiKey: string | undefined, model: string) {
|
||||
const openRouter = createOpenRouter({
|
||||
apiKey,
|
||||
});
|
||||
@ -113,7 +113,7 @@ export function getLMStudioModel(baseURL: string, model: string) {
|
||||
return lmstudio(model);
|
||||
}
|
||||
|
||||
export function getXAIModel(apiKey: string, model: string) {
|
||||
export function getXAIModel(apiKey: string | undefined, model: string) {
|
||||
const openai = createOpenAI({
|
||||
baseURL: 'https://api.x.ai/v1',
|
||||
apiKey,
|
||||
|
@ -110,6 +110,7 @@ export function useChatHistory() {
|
||||
toast.success('Chat duplicated successfully');
|
||||
} catch (error) {
|
||||
toast.error('Failed to duplicate chat');
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -1,11 +1,10 @@
|
||||
import { WebContainer, type WebContainerProcess } from '@webcontainer/api';
|
||||
import { WebContainer } from '@webcontainer/api';
|
||||
import { atom, map, type MapStore } from 'nanostores';
|
||||
import * as nodePath from 'node:path';
|
||||
import type { BoltAction } from '~/types/actions';
|
||||
import { createScopedLogger } from '~/utils/logger';
|
||||
import { unreachable } from '~/utils/unreachable';
|
||||
import type { ActionCallbackData } from './message-parser';
|
||||
import type { ITerminal } from '~/types/terminal';
|
||||
import type { BoltShell } from '~/utils/shell';
|
||||
|
||||
const logger = createScopedLogger('ActionRunner');
|
||||
@ -94,9 +93,10 @@ export class ActionRunner {
|
||||
|
||||
this.#updateAction(actionId, { ...action, ...data.action, executed: !isStreaming });
|
||||
|
||||
// eslint-disable-next-line consistent-return
|
||||
return (this.#currentExecutionPromise = this.#currentExecutionPromise
|
||||
.then(() => {
|
||||
return this.#executeAction(actionId, isStreaming);
|
||||
this.#executeAction(actionId, isStreaming);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Action failed:', error);
|
||||
@ -127,12 +127,11 @@ export class ActionRunner {
|
||||
|
||||
/*
|
||||
* adding a delay to avoid any race condition between 2 start actions
|
||||
* i am up for a better approch
|
||||
* i am up for a better approach
|
||||
*/
|
||||
await new Promise((resolve) => setTimeout(resolve, 2000));
|
||||
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,6 @@ import JSZip from 'jszip';
|
||||
import { saveAs } from 'file-saver';
|
||||
import { Octokit, type RestEndpointMethodTypes } from '@octokit/rest';
|
||||
import * as nodePath from 'node:path';
|
||||
import type { WebContainerProcess } from '@webcontainer/api';
|
||||
import { extractRelativePath } from '~/utils/diff';
|
||||
|
||||
export interface ArtifactState {
|
||||
@ -42,7 +41,6 @@ export class WorkbenchStore {
|
||||
unsavedFiles: WritableAtom<Set<string>> = import.meta.hot?.data.unsavedFiles ?? atom(new Set<string>());
|
||||
modifiedFiles = new Set<string>();
|
||||
artifactIdList: string[] = [];
|
||||
#boltTerminal: { terminal: ITerminal; process: WebContainerProcess } | undefined;
|
||||
#globalExecutionQueue = Promise.resolve();
|
||||
constructor() {
|
||||
if (import.meta.hot) {
|
||||
@ -439,6 +437,8 @@ export class WorkbenchStore {
|
||||
});
|
||||
return { path: extractRelativePath(filePath), sha: blob.sha };
|
||||
}
|
||||
|
||||
return null;
|
||||
}),
|
||||
);
|
||||
|
||||
|
@ -192,7 +192,7 @@ const PROVIDER_LIST: ProviderInfo[] = [
|
||||
{ name: 'deepseek-coder', label: 'Deepseek-Coder', provider: 'Deepseek', maxTokenAllowed: 8000 },
|
||||
{ name: 'deepseek-chat', label: 'Deepseek-Chat', provider: 'Deepseek', maxTokenAllowed: 8000 },
|
||||
],
|
||||
getApiKeyLink: 'https://platform.deepseek.com/api_keys',
|
||||
getApiKeyLink: 'https://platform.deepseek.com/apiKeys',
|
||||
},
|
||||
{
|
||||
name: 'Mistral',
|
||||
@ -242,8 +242,8 @@ const getOllamaBaseUrl = () => {
|
||||
|
||||
async function getOllamaModels(): Promise<ModelInfo[]> {
|
||||
try {
|
||||
const base_url = getOllamaBaseUrl();
|
||||
const response = await fetch(`${base_url}/api/tags`);
|
||||
const baseUrl = getOllamaBaseUrl();
|
||||
const response = await fetch(`${baseUrl}/api/tags`);
|
||||
const data = (await response.json()) as OllamaApiResponse;
|
||||
|
||||
return data.models.map((model: OllamaModel) => ({
|
||||
@ -252,6 +252,7 @@ async function getOllamaModels(): Promise<ModelInfo[]> {
|
||||
provider: 'Ollama',
|
||||
maxTokenAllowed: 8000,
|
||||
}));
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
@ -259,16 +260,16 @@ async function getOllamaModels(): Promise<ModelInfo[]> {
|
||||
|
||||
async function getOpenAILikeModels(): Promise<ModelInfo[]> {
|
||||
try {
|
||||
const base_url = import.meta.env.OPENAI_LIKE_API_BASE_URL || '';
|
||||
const baseUrl = import.meta.env.OPENAI_LIKE_API_BASE_URL || '';
|
||||
|
||||
if (!base_url) {
|
||||
if (!baseUrl) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const api_key = import.meta.env.OPENAI_LIKE_API_KEY ?? '';
|
||||
const response = await fetch(`${base_url}/models`, {
|
||||
const apiKey = import.meta.env.OPENAI_LIKE_API_KEY ?? '';
|
||||
const response = await fetch(`${baseUrl}/models`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${api_key}`,
|
||||
Authorization: `Bearer ${apiKey}`,
|
||||
},
|
||||
});
|
||||
const res = (await response.json()) as any;
|
||||
@ -278,6 +279,7 @@ async function getOpenAILikeModels(): Promise<ModelInfo[]> {
|
||||
label: model.id,
|
||||
provider: 'OpenAILike',
|
||||
}));
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
@ -318,8 +320,8 @@ async function getOpenRouterModels(): Promise<ModelInfo[]> {
|
||||
|
||||
async function getLMStudioModels(): Promise<ModelInfo[]> {
|
||||
try {
|
||||
const base_url = import.meta.env.LMSTUDIO_API_BASE_URL || 'http://localhost:1234';
|
||||
const response = await fetch(`${base_url}/v1/models`);
|
||||
const baseUrl = import.meta.env.LMSTUDIO_API_BASE_URL || 'http://localhost:1234';
|
||||
const response = await fetch(`${baseUrl}/v1/models`);
|
||||
const data = (await response.json()) as any;
|
||||
|
||||
return data.data.map((model: any) => ({
|
||||
@ -327,6 +329,7 @@ async function getLMStudioModels(): Promise<ModelInfo[]> {
|
||||
label: model.id,
|
||||
provider: 'LMStudio',
|
||||
}));
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
|
@ -52,6 +52,8 @@ export async function newShellProcess(webcontainer: WebContainer, terminal: ITer
|
||||
return process;
|
||||
}
|
||||
|
||||
export type ExecutionResult = { output: string; exitCode: number } | undefined;
|
||||
|
||||
export class BoltShell {
|
||||
#initialized: (() => void) | undefined;
|
||||
#readyPromise: Promise<void>;
|
||||
@ -61,36 +63,39 @@ export class BoltShell {
|
||||
executionState = atom<{ sessionId: string; active: boolean; executionPrms?: Promise<any> } | undefined>();
|
||||
#outputStream: ReadableStreamDefaultReader<string> | undefined;
|
||||
#shellInputStream: WritableStreamDefaultWriter<string> | undefined;
|
||||
|
||||
constructor() {
|
||||
this.#readyPromise = new Promise((resolve) => {
|
||||
this.#initialized = resolve;
|
||||
});
|
||||
}
|
||||
|
||||
ready() {
|
||||
return this.#readyPromise;
|
||||
}
|
||||
|
||||
async init(webcontainer: WebContainer, terminal: ITerminal) {
|
||||
this.#webcontainer = webcontainer;
|
||||
this.#terminal = terminal;
|
||||
|
||||
const callback = (data: string) => {
|
||||
console.log(data);
|
||||
};
|
||||
const { process, output } = await this.newBoltShellProcess(webcontainer, terminal);
|
||||
this.#process = process;
|
||||
this.#outputStream = output.getReader();
|
||||
await this.waitTillOscCode('interactive');
|
||||
this.#initialized?.();
|
||||
}
|
||||
|
||||
get terminal() {
|
||||
return this.#terminal;
|
||||
}
|
||||
|
||||
get process() {
|
||||
return this.#process;
|
||||
}
|
||||
async executeCommand(sessionId: string, command: string) {
|
||||
|
||||
async executeCommand(sessionId: string, command: string): Promise<ExecutionResult> {
|
||||
if (!this.process || !this.terminal) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const state = this.executionState.get();
|
||||
@ -109,14 +114,15 @@ export class BoltShell {
|
||||
this.terminal.input(command.trim() + '\n');
|
||||
|
||||
//wait for the execution to finish
|
||||
const executionPrms = this.getCurrentExecutionResult();
|
||||
this.executionState.set({ sessionId, active: true, executionPrms });
|
||||
const executionPromise = this.getCurrentExecutionResult();
|
||||
this.executionState.set({ sessionId, active: true, executionPrms: executionPromise });
|
||||
|
||||
const resp = await executionPrms;
|
||||
const resp = await executionPromise;
|
||||
this.executionState.set({ sessionId, active: false });
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
async newBoltShellProcess(webcontainer: WebContainer, terminal: ITerminal) {
|
||||
const args: string[] = [];
|
||||
|
||||
@ -167,10 +173,12 @@ export class BoltShell {
|
||||
|
||||
return { process, output: internalOutput };
|
||||
}
|
||||
async getCurrentExecutionResult() {
|
||||
|
||||
async getCurrentExecutionResult(): Promise<ExecutionResult> {
|
||||
const { output, exitCode } = await this.waitTillOscCode('exit');
|
||||
return { output, exitCode };
|
||||
}
|
||||
|
||||
async waitTillOscCode(waitCode: string) {
|
||||
let fullOutput = '';
|
||||
let exitCode: number = 0;
|
||||
@ -192,7 +200,7 @@ export class BoltShell {
|
||||
fullOutput += text;
|
||||
|
||||
// Check if command completion signal with exit code
|
||||
const [, osc, , pid, code] = text.match(/\x1b\]654;([^\x07=]+)=?((-?\d+):(\d+))?\x07/) || [];
|
||||
const [, osc, , , code] = text.match(/\x1b\]654;([^\x07=]+)=?((-?\d+):(\d+))?\x07/) || [];
|
||||
|
||||
if (osc === 'exit') {
|
||||
exitCode = parseInt(code, 10);
|
||||
@ -206,6 +214,7 @@ export class BoltShell {
|
||||
return { output: fullOutput, exitCode };
|
||||
}
|
||||
}
|
||||
|
||||
export function newBoltShellProcess() {
|
||||
return new BoltShell();
|
||||
}
|
||||
|
3
worker-configuration.d.ts
vendored
3
worker-configuration.d.ts
vendored
@ -9,4 +9,7 @@ interface Env {
|
||||
OPENAI_LIKE_API_BASE_URL: string;
|
||||
DEEPSEEK_API_KEY: string;
|
||||
LMSTUDIO_API_BASE_URL: string;
|
||||
GOOGLE_GENERATIVE_AI_API_KEY: string;
|
||||
MISTRAL_API_KEY: string;
|
||||
XAI_API_KEY: string;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user