Skip to content

Commit

Permalink
Added #95
Browse files Browse the repository at this point in the history
  • Loading branch information
clusterzx committed Jan 19, 2025
1 parent f7f8c5c commit 5a85b51
Show file tree
Hide file tree
Showing 9 changed files with 547 additions and 48 deletions.
7 changes: 6 additions & 1 deletion config/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ console.log('Loaded environment variables:', {
});

module.exports = {
PAPERLESS_AI_VERSION: '2.2.1',
PAPERLESS_AI_VERSION: '2.3.0',
CONFIGURED: false,
predefinedMode: process.env.PROCESS_PREDEFINED_DOCUMENTS,
paperless: {
Expand All @@ -25,6 +25,11 @@ module.exports = {
apiUrl: process.env.OLLAMA_API_URL || 'http://localhost:11434',
model: process.env.OLLAMA_MODEL || 'llama2'
},
custom: {
apiUrl: process.env.CUSTOM_BASE_URL || '',
apiKey: process.env.CUSTOM_API_KEY || '',
model: process.env.CUSTOM_MODEL || ''
},
aiProvider: process.env.AI_PROVIDER || 'openai',
scanInterval: process.env.SCAN_INTERVAL || '*/30 * * * *',
specialPromptPreDefinedTags: `You are a document analysis AI. You will analyze the document.
Expand Down
50 changes: 37 additions & 13 deletions public/js/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ class ThemeManager {
}
}

// Form Management
class FormManager {
constructor() {
this.form = document.getElementById('setupForm');
Expand Down Expand Up @@ -64,25 +63,50 @@ class FormManager {
const provider = this.aiProvider.value;
const openaiSettings = document.getElementById('openaiSettings');
const ollamaSettings = document.getElementById('ollamaSettings');
const customSettings = document.getElementById('customSettings');

// Get all provider-specific fields
const openaiKey = document.getElementById('openaiKey');
const ollamaUrl = document.getElementById('ollamaUrl');
const ollamaModel = document.getElementById('ollamaModel');
const customBaseUrl = document.getElementById('customBaseUrl');
const customApiKey = document.getElementById('customApiKey');
const customModel = document.getElementById('customModel');

if (provider === 'openai') {
openaiSettings.classList.remove('hidden');
ollamaSettings.classList.add('hidden');
openaiKey.required = true;
ollamaUrl.required = false;
ollamaModel.required = false;
} else {
openaiSettings.classList.add('hidden');
ollamaSettings.classList.remove('hidden');
openaiKey.required = false;
ollamaUrl.required = true;
ollamaModel.required = true;
// Hide all settings sections first
openaiSettings.classList.add('hidden');
ollamaSettings.classList.add('hidden');
customSettings.classList.add('hidden');

// Reset all required fields
openaiKey.required = false;
ollamaUrl.required = false;
ollamaModel.required = false;
customBaseUrl.required = false;
customApiKey.required = false;
customModel.required = false;

// Show and set required fields based on selected provider
switch (provider) {
case 'openai':
openaiSettings.classList.remove('hidden');
openaiKey.required = true;
break;
case 'ollama':
ollamaSettings.classList.remove('hidden');
ollamaUrl.required = true;
ollamaModel.required = true;
break;
case 'custom':
customSettings.classList.remove('hidden');
customBaseUrl.required = true;
customApiKey.required = true;
customModel.required = true;
break;
}
}

// Rest of the class methods remain the same
toggleTagsInput() {
const showTags = this.showTags.value;
const tagsInputSection = document.getElementById('tagsInputSection');
Expand Down
49 changes: 36 additions & 13 deletions public/js/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ class ThemeManager {
}
}

// Form Management
class FormManager {
constructor() {
this.form = document.getElementById('setupForm');
Expand Down Expand Up @@ -73,22 +72,46 @@ class FormManager {
const provider = this.aiProvider.value;
const openaiSettings = document.getElementById('openaiSettings');
const ollamaSettings = document.getElementById('ollamaSettings');
const customSettings = document.getElementById('customSettings');

// Get all required fields
const openaiKey = document.getElementById('openaiKey');
const ollamaUrl = document.getElementById('ollamaUrl');
const ollamaModel = document.getElementById('ollamaModel');
const customBaseUrl = document.getElementById('customBaseUrl');
const customApiKey = document.getElementById('customApiKey');
const customModel = document.getElementById('customModel');

if (provider === 'openai') {
openaiSettings.style.display = 'block';
ollamaSettings.style.display = 'none';
openaiKey.required = true;
ollamaUrl.required = false;
ollamaModel.required = false;
} else {
openaiSettings.style.display = 'none';
ollamaSettings.style.display = 'block';
openaiKey.required = false;
ollamaUrl.required = true;
ollamaModel.required = true;
// Hide all settings first
openaiSettings.style.display = 'none';
ollamaSettings.style.display = 'none';
customSettings.style.display = 'none';

// Reset all required attributes
openaiKey.required = false;
ollamaUrl.required = false;
ollamaModel.required = false;
customBaseUrl.required = false;
customApiKey.required = false;
customModel.required = false;

// Show and set required fields based on selected provider
switch (provider) {
case 'openai':
openaiSettings.style.display = 'block';
openaiKey.required = true;
break;
case 'ollama':
ollamaSettings.style.display = 'block';
ollamaUrl.required = true;
ollamaModel.required = true;
break;
case 'custom':
customSettings.style.display = 'block';
customBaseUrl.required = true;
customApiKey.required = true;
customModel.required = true;
break;
}
}

Expand Down
38 changes: 33 additions & 5 deletions routes/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -808,9 +808,14 @@ router.post('/setup', express.json(), async (req, res) => {
username,
password,
paperlessUsername,
useExistingData
useExistingData,
customApiKey,
customBaseUrl,
customModel
} = req.body;

console.log('Setup request received:', req.body);

const normalizeArray = (value) => {
if (!value) return [];
if (Array.isArray(value)) return value;
Expand Down Expand Up @@ -862,7 +867,10 @@ router.post('/setup', express.json(), async (req, res) => {
PROMPT_TAGS: normalizeArray(promptTags),
USE_EXISTING_DATA: useExistingData || 'no',
API_KEY: apiToken,
JWT_SECRET: jwtToken
JWT_SECRET: jwtToken,
CUSTOM_API_KEY: customApiKey || '',
CUSTOM_BASE_URL: customBaseUrl || '',
CUSTOM_MODEL: customModel || ''
};

// Validate AI provider config
Expand All @@ -884,8 +892,19 @@ router.post('/setup', express.json(), async (req, res) => {
}
config.OLLAMA_API_URL = ollamaUrl || 'http://localhost:11434';
config.OLLAMA_MODEL = ollamaModel || 'llama3.2';
}else if (aiProvider === 'custom') {
console.log('Custom AI provider selected');
const isCustomValid = await setupService.validateCustomConfig(customBaseUrl, customApiKey, customModel);
if (!isCustomValid) {
return res.status(400).json({
error: 'Custom connection failed. Please check URL, API Key and Model.'
});
}
config.CUSTOM_BASE_URL = customBaseUrl;
config.CUSTOM_API_KEY = customApiKey;
config.CUSTOM_MODEL = customModel;
}

// Save configuration
await setupService.saveConfig(config);
const hashedPassword = await bcrypt.hash(password, 15);
Expand Down Expand Up @@ -929,7 +948,10 @@ router.post('/settings', express.json(), async (req, res) => {
usePromptTags,
promptTags,
paperlessUsername,
useExistingData
useExistingData,
customApiKey,
customBaseUrl,
customModel
} = req.body;

const currentConfig = {
Expand All @@ -950,7 +972,10 @@ router.post('/settings', express.json(), async (req, res) => {
USE_PROMPT_TAGS: process.env.USE_PROMPT_TAGS || 'no',
PROMPT_TAGS: process.env.PROMPT_TAGS || '',
USE_EXISTING_DATA: process.env.USE_EXISTING_DATA || 'no',
API_KEY: process.env.API_KEY || ''
API_KEY: process.env.API_KEY || '',
CUSTOM_API_KEY: process.env.CUSTOM_API_KEY || '',
CUSTOM_BASE_URL: process.env.CUSTOM_BASE_URL || '',
CUSTOM_MODEL: process.env.CUSTOM_MODEL || ''
};

const normalizeArray = (value) => {
Expand Down Expand Up @@ -1017,6 +1042,9 @@ router.post('/settings', express.json(), async (req, res) => {
if (usePromptTags) updatedConfig.USE_PROMPT_TAGS = usePromptTags;
if (promptTags) updatedConfig.PROMPT_TAGS = normalizeArray(promptTags);
if (useExistingData) updatedConfig.USE_EXISTING_DATA = useExistingData;
if (customApiKey) updatedConfig.CUSTOM_API_KEY = customApiKey;
if (customBaseUrl) updatedConfig.CUSTOM_BASE_URL = customBaseUrl;
if (customModel) updatedConfig.CUSTOM_MODEL = customModel;

let apiToken = '';
//generate a random secure api token
Expand Down
3 changes: 3 additions & 0 deletions services/aiServiceFactory.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const config = require('../config/config');
const openaiService = require('./openaiService');
const ollamaService = require('./ollamaService');
const customService = require('./customService');

class AIServiceFactory {
static getService() {
Expand All @@ -10,6 +11,8 @@ class AIServiceFactory {
case 'openai':
default:
return openaiService;
case 'custom':
return customService;
}
}
}
Expand Down
Loading

0 comments on commit 5a85b51

Please sign in to comment.