Fix TypeScript errors and update Dockerfile for Alpine compatibility
This commit is contained in:
21
Dockerfile
21
Dockerfile
@@ -8,7 +8,8 @@ RUN apk add --no-cache \
|
||||
make \
|
||||
python3 \
|
||||
curl \
|
||||
ca-certificates
|
||||
ca-certificates \
|
||||
vips-dev
|
||||
|
||||
# Configure npm for better reliability
|
||||
RUN npm config set strict-ssl false
|
||||
@@ -16,18 +17,24 @@ RUN npm config set registry https://registry.npmjs.org/
|
||||
RUN npm config set fetch-retry-mintimeout 20000
|
||||
RUN npm config set fetch-retry-maxtimeout 120000
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
# Install global packages needed for build
|
||||
RUN npm install -g typescript shx
|
||||
|
||||
# Clean npm cache and install dependencies
|
||||
# Copy package files and modify to prevent prepare script from running
|
||||
COPY package*.json ./
|
||||
RUN node -e "const pkg = require('./package.json'); delete pkg.scripts.prepare; require('fs').writeFileSync('./package.json', JSON.stringify(pkg, null, 2));"
|
||||
|
||||
# Install dependencies without running the prepare script, including sharp with the correct platform
|
||||
RUN npm cache clean --force && \
|
||||
npm install --legacy-peer-deps --no-optional
|
||||
npm install --legacy-peer-deps --no-optional && \
|
||||
npm install --platform=linuxmusl --arch=x64 sharp
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Build TypeScript code
|
||||
RUN npm run build
|
||||
# Build TypeScript code manually
|
||||
RUN npx tsc && \
|
||||
npx shx chmod +x dist/*.js
|
||||
|
||||
# Switch to production for runtime
|
||||
ENV NODE_ENV=production
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import axios, { AxiosError, AxiosInstance } from 'axios';
|
||||
import { McpError } from '@modelcontextprotocol/sdk/types.js';
|
||||
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
|
||||
|
||||
/**
|
||||
* Client for interacting with the OpenRouter API
|
||||
@@ -90,7 +90,7 @@ export class OpenRouterAPIClient {
|
||||
if (axiosError.response) {
|
||||
const responseData = axiosError.response.data as any;
|
||||
const message = responseData?.error?.message || axiosError.message;
|
||||
throw new McpError('RequestFailed', `OpenRouter API error: ${message}`);
|
||||
throw new McpError(ErrorCode.InternalError, `OpenRouter API error: ${message}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,17 +114,17 @@ export class OpenRouterAPIClient {
|
||||
const message = responseData?.error?.message || axiosError.message;
|
||||
|
||||
if (status === 401 || status === 403) {
|
||||
throw new McpError('Unauthorized', `Authentication error: ${message}`);
|
||||
throw new McpError(ErrorCode.InvalidRequest, `Authentication error: ${message}`);
|
||||
} else if (status === 429) {
|
||||
throw new McpError('RateLimitExceeded', `Rate limit exceeded: ${message}`);
|
||||
throw new McpError(ErrorCode.InternalError, `Rate limit exceeded: ${message}`);
|
||||
} else {
|
||||
throw new McpError('RequestFailed', `OpenRouter API error (${status}): ${message}`);
|
||||
throw new McpError(ErrorCode.InternalError, `OpenRouter API error (${status}): ${message}`);
|
||||
}
|
||||
} else if (axiosError.request) {
|
||||
throw new McpError('NetworkError', `Network error: ${axiosError.message}`);
|
||||
throw new McpError(ErrorCode.ConnectionClosed, `Network error: ${axiosError.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
throw new McpError('UnknownError', `Unknown error: ${error.message || 'No error message'}`);
|
||||
throw new McpError(ErrorCode.InternalError, `Unknown error: ${error.message || 'No error message'}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import path from 'path';
|
||||
import { promises as fs } from 'fs';
|
||||
import sharp from 'sharp';
|
||||
import { McpError } from '@modelcontextprotocol/sdk/types.js';
|
||||
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
|
||||
import OpenAI from 'openai';
|
||||
|
||||
export interface AnalyzeImageToolRequest {
|
||||
@@ -21,7 +21,7 @@ export async function handleAnalyzeImage(
|
||||
// Validate image path
|
||||
const imagePath = args.image_path;
|
||||
if (!path.isAbsolute(imagePath)) {
|
||||
throw new McpError('InvalidParams', 'Image path must be absolute');
|
||||
throw new McpError(ErrorCode.InvalidParams, 'Image path must be absolute');
|
||||
}
|
||||
|
||||
// Read image file
|
||||
@@ -85,7 +85,7 @@ export async function handleAnalyzeImage(
|
||||
// Call OpenRouter API
|
||||
const completion = await openai.chat.completions.create({
|
||||
model,
|
||||
messages,
|
||||
messages: messages as any,
|
||||
});
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { McpError } from '@modelcontextprotocol/sdk/types.js';
|
||||
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
|
||||
import { ModelCache } from '../model-cache.js';
|
||||
|
||||
export interface GetModelInfoToolRequest {
|
||||
@@ -26,7 +26,7 @@ export async function handleGetModelInfo(
|
||||
|
||||
const model = modelCache.getModel(args.model);
|
||||
if (!model) {
|
||||
throw new McpError('NotFound', `Model '${args.model}' not found`);
|
||||
throw new McpError(ErrorCode.InvalidParams, `Model '${args.model}' not found`);
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import fetch from 'node-fetch';
|
||||
import sharp from 'sharp';
|
||||
import { McpError } from '@modelcontextprotocol/sdk/types.js';
|
||||
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
|
||||
import OpenAI from 'openai';
|
||||
|
||||
export interface MultiImageAnalysisToolRequest {
|
||||
@@ -90,11 +90,11 @@ export async function handleMultiImageAnalysis(
|
||||
try {
|
||||
// Validate inputs
|
||||
if (!args.images || args.images.length === 0) {
|
||||
throw new McpError('InvalidParams', 'At least one image is required');
|
||||
throw new McpError(ErrorCode.InvalidParams, 'At least one image is required');
|
||||
}
|
||||
|
||||
if (!args.prompt) {
|
||||
throw new McpError('InvalidParams', 'A prompt is required');
|
||||
throw new McpError(ErrorCode.InvalidParams, 'A prompt is required');
|
||||
}
|
||||
|
||||
// Prepare content array for the message
|
||||
@@ -137,7 +137,7 @@ export async function handleMultiImageAnalysis(
|
||||
messages: [{
|
||||
role: 'user',
|
||||
content
|
||||
}]
|
||||
}] as any
|
||||
});
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user