Skip to content

Commit

Permalink
Fix: error building my application stackblitz-labs#1414
Browse files Browse the repository at this point in the history
  • Loading branch information
Stijnus committed Mar 3, 2025
1 parent 8d1f138 commit 578b661
Show file tree
Hide file tree
Showing 11 changed files with 106 additions and 742 deletions.
2 changes: 1 addition & 1 deletion app/lib/hooks/useShortcuts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export function useShortcuts(): void {
}

// Debug logging in development only
if (process.env.NODE_ENV === 'development') {
if (import.meta.env.DEV) {
console.log('Key pressed:', {
key: event.key,
code: event.code,
Expand Down
2 changes: 1 addition & 1 deletion app/lib/modules/llm/providers/lmstudio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default class LMStudioProvider extends BaseProvider {
throw new Error('No baseUrl found for LMStudio provider');
}

const isDocker = process.env.RUNNING_IN_DOCKER === 'true' || serverEnv?.RUNNING_IN_DOCKER === 'true';
const isDocker = serverEnv?.RUNNING_IN_DOCKER === 'true';

if (typeof window === 'undefined') {
baseUrl = isDocker ? baseUrl.replace('localhost', 'host.docker.internal') : baseUrl;
Expand Down
33 changes: 27 additions & 6 deletions app/lib/modules/llm/providers/ollama.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ export interface OllamaApiResponse {
models: OllamaModel[];
}

export const DEFAULT_NUM_CTX = process?.env?.DEFAULT_NUM_CTX ? parseInt(process.env.DEFAULT_NUM_CTX, 10) : 32768;

export default class OllamaProvider extends BaseProvider {
name = 'Ollama';
getApiKeyLink = 'https://ollama.com/download';
Expand All @@ -41,6 +39,26 @@ export default class OllamaProvider extends BaseProvider {

staticModels: ModelInfo[] = [];

private _convertEnvToRecord(env?: Env): Record<string, string> {
if (!env) {
return {};
}

// Convert Env to a plain object with string values
return Object.entries(env).reduce(
(acc, [key, value]) => {
acc[key] = String(value);
return acc;
},
{} as Record<string, string>,
);
}

getDefaultNumCtx(serverEnv?: Env): number {
const envRecord = this._convertEnvToRecord(serverEnv);
return envRecord.DEFAULT_NUM_CTX ? parseInt(envRecord.DEFAULT_NUM_CTX, 10) : 32768;
}

async getDynamicModels(
apiKeys?: Record<string, string>,
settings?: IProviderSetting,
Expand All @@ -63,7 +81,7 @@ export default class OllamaProvider extends BaseProvider {
* Running in Server
* Backend: Check if we're running in Docker
*/
const isDocker = process?.env?.RUNNING_IN_DOCKER === 'true' || serverEnv?.RUNNING_IN_DOCKER === 'true';
const isDocker = serverEnv?.RUNNING_IN_DOCKER === 'true';

baseUrl = isDocker ? baseUrl.replace('localhost', 'host.docker.internal') : baseUrl;
baseUrl = isDocker ? baseUrl.replace('127.0.0.1', 'host.docker.internal') : baseUrl;
Expand All @@ -81,17 +99,20 @@ export default class OllamaProvider extends BaseProvider {
maxTokenAllowed: 8000,
}));
}

getModelInstance: (options: {
model: string;
serverEnv?: Env;
apiKeys?: Record<string, string>;
providerSettings?: Record<string, IProviderSetting>;
}) => LanguageModelV1 = (options) => {
const { apiKeys, providerSettings, serverEnv, model } = options;
const envRecord = this._convertEnvToRecord(serverEnv);

let { baseUrl } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: providerSettings?.[this.name],
serverEnv: serverEnv as any,
serverEnv: envRecord,
defaultBaseUrlKey: 'OLLAMA_API_BASE_URL',
defaultApiTokenKey: '',
});
Expand All @@ -101,14 +122,14 @@ export default class OllamaProvider extends BaseProvider {
throw new Error('No baseUrl found for OLLAMA provider');
}

const isDocker = process?.env?.RUNNING_IN_DOCKER === 'true' || serverEnv?.RUNNING_IN_DOCKER === 'true';
const isDocker = envRecord.RUNNING_IN_DOCKER === 'true';
baseUrl = isDocker ? baseUrl.replace('localhost', 'host.docker.internal') : baseUrl;
baseUrl = isDocker ? baseUrl.replace('127.0.0.1', 'host.docker.internal') : baseUrl;

logger.debug('Ollama Base Url used: ', baseUrl);

const ollamaInstance = ollama(model, {
numCtx: DEFAULT_NUM_CTX,
numCtx: this.getDefaultNumCtx(serverEnv),
}) as LanguageModelV1 & { config: any };

ollamaInstance.config.baseURL = `${baseUrl}/api`;
Expand Down
2 changes: 1 addition & 1 deletion app/routes/api.check-env-key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const loader: LoaderFunction = async ({ context, request }) => {
}

const envVarName = providerBaseUrlEnvKeys[provider].apiTokenKey;
const isSet = !!(process.env[envVarName] || (context?.cloudflare?.env as Record<string, any>)?.[envVarName]);
const isSet = !!(context?.cloudflare?.env as Record<string, any>)?.[envVarName];

return Response.json({ isSet });
};
12 changes: 10 additions & 2 deletions app/routes/api.deploy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { type ActionFunctionArgs, json } from '@remix-run/cloudflare';
import crypto from 'crypto';
import type { NetlifySiteInfo } from '~/types/netlify';

interface DeployRequestBody {
Expand All @@ -8,6 +7,15 @@ interface DeployRequestBody {
chatId: string;
}

async function sha1(message: string) {
const msgBuffer = new TextEncoder().encode(message);
const hashBuffer = await crypto.subtle.digest('SHA-1', msgBuffer);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');

return hashHex;
}

export async function action({ request }: ActionFunctionArgs) {
try {
const { siteId, files, token, chatId } = (await request.json()) as DeployRequestBody & { token: string };
Expand Down Expand Up @@ -104,7 +112,7 @@ export async function action({ request }: ActionFunctionArgs) {
for (const [filePath, content] of Object.entries(files)) {
// Ensure file path starts with a forward slash
const normalizedPath = filePath.startsWith('/') ? filePath : '/' + filePath;
const hash = crypto.createHash('sha1').update(content).digest('hex');
const hash = await sha1(content);
fileDigests[normalizedPath] = hash;
}

Expand Down
47 changes: 18 additions & 29 deletions app/routes/api.system.app-info.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { ActionFunctionArgs, LoaderFunction } from '@remix-run/cloudflare';
import { json } from '@remix-run/cloudflare';
import { execSync } from 'child_process';

// These are injected by Vite at build time
declare const __APP_VERSION: string;
Expand All @@ -11,34 +10,24 @@ declare const __PKG_DEPENDENCIES: Record<string, string>;
declare const __PKG_DEV_DEPENDENCIES: Record<string, string>;
declare const __PKG_PEER_DEPENDENCIES: Record<string, string>;
declare const __PKG_OPTIONAL_DEPENDENCIES: Record<string, string>;
declare const __COMMIT_HASH: string;
declare const __GIT_BRANCH: string;
declare const __GIT_COMMIT_TIME: string;
declare const __GIT_AUTHOR: string;
declare const __GIT_EMAIL: string;
declare const __GIT_REMOTE_URL: string;
declare const __GIT_REPO_NAME: string;

const getGitInfo = () => {
try {
return {
commitHash: execSync('git rev-parse --short HEAD').toString().trim(),
branch: execSync('git rev-parse --abbrev-ref HEAD').toString().trim(),
commitTime: execSync('git log -1 --format=%cd').toString().trim(),
author: execSync('git log -1 --format=%an').toString().trim(),
email: execSync('git log -1 --format=%ae').toString().trim(),
remoteUrl: execSync('git config --get remote.origin.url').toString().trim(),
repoName: execSync('git config --get remote.origin.url')
.toString()
.trim()
.replace(/^.*github.com[:/]/, '')
.replace(/\.git$/, ''),
};
} catch (error) {
console.error('Failed to get git info:', error);
return {
commitHash: 'unknown',
branch: 'unknown',
commitTime: 'unknown',
author: 'unknown',
email: 'unknown',
remoteUrl: 'unknown',
repoName: 'unknown',
};
}
return {
commitHash: __COMMIT_HASH || 'unknown',
branch: __GIT_BRANCH || 'unknown',
commitTime: __GIT_COMMIT_TIME || 'unknown',
author: __GIT_AUTHOR || 'unknown',
email: __GIT_EMAIL || 'unknown',
remoteUrl: __GIT_REMOTE_URL || 'unknown',
repoName: __GIT_REPO_NAME || 'unknown',
};
};

const formatDependencies = (
Expand All @@ -60,11 +49,11 @@ const getAppResponse = () => {
version: __APP_VERSION || '0.1.0',
description: __PKG_DESCRIPTION || 'A DIY LLM interface',
license: __PKG_LICENSE || 'MIT',
environment: process.env.NODE_ENV || 'development',
environment: 'cloudflare',
gitInfo,
timestamp: new Date().toISOString(),
runtimeInfo: {
nodeVersion: process.version || 'unknown',
nodeVersion: 'cloudflare',
},
dependencies: {
production: formatDependencies(__PKG_DEPENDENCIES, 'production'),
Expand Down
143 changes: 8 additions & 135 deletions app/routes/api.system.git-info.ts
Original file line number Diff line number Diff line change
@@ -1,138 +1,11 @@
import type { LoaderFunction } from '@remix-run/cloudflare';
import { json } from '@remix-run/cloudflare';
import { execSync } from 'child_process';
import { json, type LoaderFunction } from '@remix-run/cloudflare';

interface GitHubRepoInfo {
name: string;
full_name: string;
default_branch: string;
stargazers_count: number;
forks_count: number;
open_issues_count: number;
parent?: {
full_name: string;
default_branch: string;
stargazers_count: number;
forks_count: number;
};
}

const getLocalGitInfo = () => {
try {
return {
commitHash: execSync('git rev-parse HEAD').toString().trim(),
branch: execSync('git rev-parse --abbrev-ref HEAD').toString().trim(),
commitTime: execSync('git log -1 --format=%cd').toString().trim(),
author: execSync('git log -1 --format=%an').toString().trim(),
email: execSync('git log -1 --format=%ae').toString().trim(),
remoteUrl: execSync('git config --get remote.origin.url').toString().trim(),
repoName: execSync('git config --get remote.origin.url')
.toString()
.trim()
.replace(/^.*github.com[:/]/, '')
.replace(/\.git$/, ''),
};
} catch (error) {
console.error('Failed to get local git info:', error);
return null;
}
};

const getGitHubInfo = async (repoFullName: string) => {
try {
// Add GitHub token if available
const headers: Record<string, string> = {
Accept: 'application/vnd.github.v3+json',
};

const githubToken = process.env.GITHUB_TOKEN;

if (githubToken) {
headers.Authorization = `token ${githubToken}`;
}

console.log('Fetching GitHub info for:', repoFullName); // Debug log

const response = await fetch(`https://api.github.com/repos/${repoFullName}`, {
headers,
});

if (!response.ok) {
console.error('GitHub API error:', {
status: response.status,
statusText: response.statusText,
repoFullName,
});

// If we get a 404, try the main repo as fallback
if (response.status === 404 && repoFullName !== 'stackblitz-labs/bolt.diy') {
return getGitHubInfo('stackblitz-labs/bolt.diy');
}

throw new Error(`GitHub API error: ${response.statusText}`);
}

const data = await response.json();
console.log('GitHub API response:', data); // Debug log

return data as GitHubRepoInfo;
} catch (error) {
console.error('Failed to get GitHub info:', error);
return null;
}
};

export const loader: LoaderFunction = async ({ request: _request }) => {
const localInfo = getLocalGitInfo();
console.log('Local git info:', localInfo); // Debug log

// If we have local info, try to get GitHub info for both our fork and upstream
let githubInfo = null;

if (localInfo?.repoName) {
githubInfo = await getGitHubInfo(localInfo.repoName);
}

// If no local info or GitHub info, try the main repo
if (!githubInfo) {
githubInfo = await getGitHubInfo('stackblitz-labs/bolt.diy');
}

const response = {
local: localInfo || {
commitHash: 'unknown',
branch: 'unknown',
commitTime: 'unknown',
author: 'unknown',
email: 'unknown',
remoteUrl: 'unknown',
repoName: 'unknown',
export const loader: LoaderFunction = async () => {
return json(
{
error: 'Git information is not available in the Cloudflare environment',
message: 'This feature requires system-level access and is only available in a server environment.',
},
github: githubInfo
? {
currentRepo: {
fullName: githubInfo.full_name,
defaultBranch: githubInfo.default_branch,
stars: githubInfo.stargazers_count,
forks: githubInfo.forks_count,
openIssues: githubInfo.open_issues_count,
},
upstream: githubInfo.parent
? {
fullName: githubInfo.parent.full_name,
defaultBranch: githubInfo.parent.default_branch,
stars: githubInfo.parent.stargazers_count,
forks: githubInfo.parent.forks_count,
}
: null,
}
: null,
isForked: Boolean(githubInfo?.parent),
timestamp: new Date().toISOString(),
};

console.log('Final response:', response);

// Debug log
return json(response);
{ status: 400 },
);
};
Loading

0 comments on commit 578b661

Please sign in to comment.