big fixes
fixes feedback from thecodacus
This commit is contained in:
@@ -18,7 +18,7 @@ import Cookies from 'js-cookie';
|
||||
import type { IProviderSetting, ProviderInfo, IProviderConfig } from '~/types/model';
|
||||
import type { TabWindowConfig, TabVisibilityConfig } from '~/components/settings/settings.types';
|
||||
import { logStore } from '~/lib/stores/logs';
|
||||
import { getLocalStorage, setLocalStorage } from '~/utils/localStorage';
|
||||
import { getLocalStorage, setLocalStorage } from '~/lib/persistence';
|
||||
|
||||
export interface Settings {
|
||||
theme: 'light' | 'dark' | 'system';
|
||||
|
||||
53
app/lib/modules/llm/providers/github.ts
Normal file
53
app/lib/modules/llm/providers/github.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { BaseProvider } from '~/lib/modules/llm/base-provider';
|
||||
import type { ModelInfo } from '~/lib/modules/llm/types';
|
||||
import type { IProviderSetting } from '~/types/model';
|
||||
import type { LanguageModelV1 } from 'ai';
|
||||
import { createOpenAI } from '@ai-sdk/openai';
|
||||
|
||||
export default class GithubProvider extends BaseProvider {
|
||||
name = 'Github';
|
||||
getApiKeyLink = 'https://github.com/settings/personal-access-tokens';
|
||||
|
||||
config = {
|
||||
apiTokenKey: 'GITHUB_API_KEY',
|
||||
};
|
||||
|
||||
// find more in https://github.com/marketplace?type=models
|
||||
staticModels: ModelInfo[] = [
|
||||
{ name: 'gpt-4o', label: 'GPT-4o', provider: 'Github', maxTokenAllowed: 8000 },
|
||||
{ name: 'o1', label: 'o1-preview', provider: 'Github', maxTokenAllowed: 100000 },
|
||||
{ name: 'o1-mini', label: 'o1-mini', provider: 'Github', maxTokenAllowed: 8000 },
|
||||
{ name: 'gpt-4o-mini', label: 'GPT-4o Mini', provider: 'Github', maxTokenAllowed: 8000 },
|
||||
{ name: 'gpt-4-turbo', label: 'GPT-4 Turbo', provider: 'Github', maxTokenAllowed: 8000 },
|
||||
{ name: 'gpt-4', label: 'GPT-4', provider: 'Github', maxTokenAllowed: 8000 },
|
||||
{ name: 'gpt-3.5-turbo', label: 'GPT-3.5 Turbo', provider: 'Github', maxTokenAllowed: 8000 },
|
||||
];
|
||||
|
||||
getModelInstance(options: {
|
||||
model: string;
|
||||
serverEnv: Env;
|
||||
apiKeys?: Record<string, string>;
|
||||
providerSettings?: Record<string, IProviderSetting>;
|
||||
}): LanguageModelV1 {
|
||||
const { model, serverEnv, apiKeys, providerSettings } = options;
|
||||
|
||||
const { apiKey } = this.getProviderBaseUrlAndKey({
|
||||
apiKeys,
|
||||
providerSettings: providerSettings?.[this.name],
|
||||
serverEnv: serverEnv as any,
|
||||
defaultBaseUrlKey: '',
|
||||
defaultApiTokenKey: 'GITHUB_API_KEY',
|
||||
});
|
||||
|
||||
if (!apiKey) {
|
||||
throw new Error(`Missing API key for ${this.name} provider`);
|
||||
}
|
||||
|
||||
const openai = createOpenAI({
|
||||
baseURL: 'https://models.inference.ai.azure.com',
|
||||
apiKey,
|
||||
});
|
||||
|
||||
return openai(model);
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import TogetherProvider from './providers/together';
|
||||
import XAIProvider from './providers/xai';
|
||||
import HyperbolicProvider from './providers/hyperbolic';
|
||||
import AmazonBedrockProvider from './providers/amazon-bedrock';
|
||||
import GithubProvider from './providers/github';
|
||||
|
||||
export {
|
||||
AnthropicProvider,
|
||||
@@ -34,4 +35,5 @@ export {
|
||||
TogetherProvider,
|
||||
LMStudioProvider,
|
||||
AmazonBedrockProvider,
|
||||
GithubProvider,
|
||||
};
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from './localStorage';
|
||||
export * from './db';
|
||||
export * from './useChatHistory';
|
||||
|
||||
28
app/lib/persistence/localStorage.ts
Normal file
28
app/lib/persistence/localStorage.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
// Client-side storage utilities
|
||||
const isClient = typeof window !== 'undefined' && typeof localStorage !== 'undefined';
|
||||
|
||||
export function getLocalStorage(key: string): any | null {
|
||||
if (!isClient) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const item = localStorage.getItem(key);
|
||||
return item ? JSON.parse(item) : null;
|
||||
} catch (error) {
|
||||
console.error(`Error reading from localStorage key "${key}":`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function setLocalStorage(key: string, value: any): void {
|
||||
if (!isClient) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
localStorage.setItem(key, JSON.stringify(value));
|
||||
} catch (error) {
|
||||
console.error(`Error writing to localStorage key "${key}":`, error);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { WebContainer } from '@webcontainer/api';
|
||||
import type { WebContainer } from '@webcontainer/api';
|
||||
import { path } from '~/utils/path';
|
||||
import { atom, map, type MapStore } from 'nanostores';
|
||||
import * as nodePath from 'node:path';
|
||||
import type { ActionAlert, BoltAction } from '~/types/actions';
|
||||
import { createScopedLogger } from '~/utils/logger';
|
||||
import { unreachable } from '~/utils/unreachable';
|
||||
@@ -276,9 +276,9 @@ export class ActionRunner {
|
||||
}
|
||||
|
||||
const webcontainer = await this.#webcontainer;
|
||||
const relativePath = nodePath.relative(webcontainer.workdir, action.filePath);
|
||||
const relativePath = path.relative(webcontainer.workdir, action.filePath);
|
||||
|
||||
let folder = nodePath.dirname(relativePath);
|
||||
let folder = path.dirname(relativePath);
|
||||
|
||||
// remove trailing slashes
|
||||
folder = folder.replace(/\/+$/g, '');
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { PathWatcherEvent, WebContainer } from '@webcontainer/api';
|
||||
import { getEncoding } from 'istextorbinary';
|
||||
import { map, type MapStore } from 'nanostores';
|
||||
import { Buffer } from 'node:buffer';
|
||||
import * as nodePath from 'node:path';
|
||||
import { path } from '~/utils/path';
|
||||
import { bufferWatchEvents } from '~/utils/buffer';
|
||||
import { WORK_DIR } from '~/utils/constants';
|
||||
import { computeFileModifications } from '~/utils/diff';
|
||||
@@ -84,7 +84,7 @@ export class FilesStore {
|
||||
const webcontainer = await this.#webcontainer;
|
||||
|
||||
try {
|
||||
const relativePath = nodePath.relative(webcontainer.workdir, filePath);
|
||||
const relativePath = path.relative(webcontainer.workdir, filePath);
|
||||
|
||||
if (!relativePath) {
|
||||
throw new Error(`EINVAL: invalid file path, write '${relativePath}'`);
|
||||
|
||||
@@ -10,15 +10,18 @@ import { FilesStore, type FileMap } from './files';
|
||||
import { PreviewsStore } from './previews';
|
||||
import { TerminalStore } from './terminal';
|
||||
import JSZip from 'jszip';
|
||||
import { saveAs } from 'file-saver';
|
||||
import fileSaver from 'file-saver';
|
||||
import { Octokit, type RestEndpointMethodTypes } from '@octokit/rest';
|
||||
import * as nodePath from 'node:path';
|
||||
import { path } from '~/utils/path';
|
||||
import { extractRelativePath } from '~/utils/diff';
|
||||
import { description } from '~/lib/persistence';
|
||||
import Cookies from 'js-cookie';
|
||||
import { createSampler } from '~/utils/sampler';
|
||||
import type { ActionAlert } from '~/types/actions';
|
||||
|
||||
// Destructure saveAs from the CommonJS module
|
||||
const { saveAs } = fileSaver;
|
||||
|
||||
export interface ArtifactState {
|
||||
id: string;
|
||||
title: string;
|
||||
@@ -329,7 +332,7 @@ export class WorkbenchStore {
|
||||
|
||||
if (data.action.type === 'file') {
|
||||
const wc = await webcontainer;
|
||||
const fullPath = nodePath.join(wc.workdir, data.action.filePath);
|
||||
const fullPath = path.join(wc.workdir, data.action.filePath);
|
||||
|
||||
if (this.selectedFile.value !== fullPath) {
|
||||
this.setSelectedFile(fullPath);
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
import { type ClassValue, clsx } from 'clsx';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
Reference in New Issue
Block a user