Initial commit — Mek-Tech AI Consultancy Framework v2.0
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const {
|
||||
PROVIDER_PRESETS, getProviders, getProvider, saveProvider, deleteProvider,
|
||||
maskKey, chatCompletion, syncAiConfigFile
|
||||
} = require('../lib/ai');
|
||||
const { logAudit } = require('../db');
|
||||
|
||||
router.get('/', (req, res) => {
|
||||
const providers = getProviders().map(p => ({
|
||||
...p,
|
||||
api_key_masked: maskKey(getProvider(p.id)?.api_key)
|
||||
}));
|
||||
res.render('ai-providers', {
|
||||
providers,
|
||||
presets: PROVIDER_PRESETS,
|
||||
saved: req.query.saved === '1',
|
||||
tested: req.query.tested,
|
||||
error: req.query.error || null
|
||||
});
|
||||
});
|
||||
|
||||
router.post('/save', (req, res) => {
|
||||
const { id, name, provider_type, api_key, base_url, default_model, is_active, is_default } = req.body;
|
||||
const preset = PROVIDER_PRESETS[provider_type] || PROVIDER_PRESETS.custom;
|
||||
let key = api_key;
|
||||
if (id && (!key || key.includes('••••'))) {
|
||||
const existing = getProvider(id);
|
||||
key = existing?.api_key || '';
|
||||
}
|
||||
saveProvider({
|
||||
id: id ? parseInt(id, 10) : null,
|
||||
name: name || preset.label,
|
||||
provider_type: provider_type || 'openrouter',
|
||||
api_key: key,
|
||||
base_url: base_url || preset.base_url,
|
||||
default_model: default_model || preset.models[0] || '',
|
||||
is_active: is_active === '1',
|
||||
is_default: is_default === '1'
|
||||
});
|
||||
logAudit(req.session.userId, req.session.username, 'ai_provider_saved', 'ai_provider', id || null, name);
|
||||
res.redirect('/ai?saved=1');
|
||||
});
|
||||
|
||||
router.post('/delete/:id', (req, res) => {
|
||||
deleteProvider(req.params.id);
|
||||
logAudit(req.session.userId, req.session.username, 'ai_provider_deleted', 'ai_provider', req.params.id, '');
|
||||
res.redirect('/ai?saved=1');
|
||||
});
|
||||
|
||||
router.post('/sync', (req, res) => {
|
||||
syncAiConfigFile();
|
||||
res.redirect('/ai?saved=1');
|
||||
});
|
||||
|
||||
router.post('/test/:id', async (req, res) => {
|
||||
try {
|
||||
const result = await chatCompletion(
|
||||
[{ role: 'user', content: 'Antwoord met exact: Mek-Tech AI verbinding OK' }],
|
||||
{ providerId: parseInt(req.params.id, 10), max_tokens: 50 }
|
||||
);
|
||||
const text = result.choices?.[0]?.message?.content || 'OK';
|
||||
res.redirect('/ai?tested=' + encodeURIComponent(text.slice(0, 80)));
|
||||
} catch (e) {
|
||||
res.redirect('/ai?error=' + encodeURIComponent(e.message));
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/chat', async (req, res) => {
|
||||
try {
|
||||
const { messages, provider_id, model, client_id } = req.body;
|
||||
const result = await chatCompletion(messages, {
|
||||
providerId: provider_id ? parseInt(provider_id, 10) : null,
|
||||
model
|
||||
});
|
||||
const content = result.choices?.[0]?.message?.content || '';
|
||||
if (client_id) {
|
||||
const { getDb } = require('../db');
|
||||
getDb().prepare('INSERT INTO client_notes (client_id, content, created_by) VALUES (?, ?, ?)')
|
||||
.run(client_id, `[AI] ${content.slice(0, 2000)}`, req.session.username || 'ai');
|
||||
}
|
||||
res.json({ success: true, content, model: result.model });
|
||||
} catch (e) {
|
||||
res.status(500).json({ success: false, error: e.message });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
Reference in New Issue
Block a user