mirror of
https://github.com/elder-plinius/P4RS3LT0NGV3.git
synced 2026-04-22 03:36:19 +02:00
177 lines
7.6 KiB
JavaScript
177 lines
7.6 KiB
JavaScript
/**
|
|
* Syntactic Anti-Classifier — linguistic transformations via OpenRouter (same key as PromptCraft).
|
|
*/
|
|
class AntiClassifierTool extends Tool {
|
|
constructor() {
|
|
super({
|
|
id: 'anticlassifier',
|
|
name: 'Anti-Classifier',
|
|
icon: 'fa-robot',
|
|
title: 'Syntactic anti-classifier (OpenRouter)',
|
|
order: 12
|
|
});
|
|
}
|
|
|
|
getVueData() {
|
|
const models = (typeof window !== 'undefined' && window.OPENROUTER_MODELS && window.OPENROUTER_MODELS.length)
|
|
? window.OPENROUTER_MODELS
|
|
: [];
|
|
const savedTemp = parseFloat(localStorage.getItem('ac-temperature'));
|
|
const acTemperature = Number.isFinite(savedTemp)
|
|
? Math.min(2, Math.max(0, savedTemp))
|
|
: 0.7;
|
|
return {
|
|
acInput: '',
|
|
acOutput: '',
|
|
acError: '',
|
|
acLexemeAnalysis: { totalFindings: 0, findings: [], summary: 'No Latin-root wording findings.' },
|
|
acLoading: false,
|
|
acModel: localStorage.getItem('ac-model') || 'anthropic/claude-sonnet-4.6',
|
|
acModels: models,
|
|
acTemperature,
|
|
acMaxTokens: 2000
|
|
};
|
|
}
|
|
|
|
getVueMethods() {
|
|
return {
|
|
acGetApiKey: function() {
|
|
var key = localStorage.getItem('openrouter-api-key') ||
|
|
localStorage.getItem('plinyos-api-key') ||
|
|
localStorage.getItem('openrouter_api_key') || '';
|
|
if (!key && this.openrouterApiKey) {
|
|
key = this.openrouterApiKey;
|
|
localStorage.setItem('openrouter-api-key', key.trim());
|
|
}
|
|
return (key || '').trim();
|
|
},
|
|
acGetSystemPrompt: function() {
|
|
return (typeof window !== 'undefined' && window.ANTICLASSIFIER_SYSTEM_PROMPT)
|
|
? window.ANTICLASSIFIER_SYSTEM_PROMPT
|
|
: '';
|
|
},
|
|
acRefreshLexemeAnalysis: function() {
|
|
if (typeof window === 'undefined' || !window.LexemeAnalysis || typeof window.LexemeAnalysis.analyze !== 'function') {
|
|
this.acLexemeAnalysis = { totalFindings: 0, findings: [], summary: 'Lexeme analysis unavailable.' };
|
|
return;
|
|
}
|
|
this.acLexemeAnalysis = window.LexemeAnalysis.analyze(this.acInput);
|
|
},
|
|
acRun: async function() {
|
|
const apiKey = this.acGetApiKey();
|
|
if (!apiKey) {
|
|
this.acError = 'No API key found. Set your OpenRouter key in Advanced Settings first.';
|
|
return;
|
|
}
|
|
if (!this.acInput.trim()) {
|
|
this.acError = 'Enter a prompt to analyze.';
|
|
return;
|
|
}
|
|
const systemPrompt = this.acGetSystemPrompt();
|
|
if (!systemPrompt) {
|
|
this.acError = 'Anti-classifier system prompt failed to load.';
|
|
return;
|
|
}
|
|
|
|
this.acLoading = true;
|
|
this.acError = '';
|
|
this.acOutput = '';
|
|
localStorage.setItem('ac-model', this.acModel);
|
|
const rawT = Number(this.acTemperature);
|
|
const temperature = Number.isFinite(rawT)
|
|
? Math.min(2, Math.max(0, rawT))
|
|
: 0.7;
|
|
localStorage.setItem('ac-temperature', String(temperature));
|
|
|
|
try {
|
|
const res = await fetch('https://openrouter.ai/api/v1/chat/completions', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Authorization': 'Bearer ' + apiKey,
|
|
'Content-Type': 'application/json',
|
|
'HTTP-Referer': window.location.href || 'https://p4rs3lt0ngv3.app',
|
|
'X-Title': 'P4RS3LT0NGV3 Anti-Classifier'
|
|
},
|
|
body: JSON.stringify({
|
|
model: this.acModel,
|
|
messages: [
|
|
{ role: 'system', content: systemPrompt },
|
|
{ role: 'user', content: this.acInput }
|
|
],
|
|
temperature: temperature,
|
|
max_tokens: Math.max(100, Math.min(32000, Number(this.acMaxTokens) || 2000))
|
|
})
|
|
});
|
|
const data = await res.json();
|
|
if (res.status === 401) {
|
|
throw new Error('Invalid API key. Check your OpenRouter key in Advanced Settings.');
|
|
}
|
|
if (res.status === 402) {
|
|
throw new Error('Insufficient credits on your OpenRouter account.');
|
|
}
|
|
if (res.status === 403) {
|
|
throw new Error('Access denied. Your key may lack permissions for this model.');
|
|
}
|
|
if (data.error) {
|
|
const msg = typeof data.error === 'string' ? data.error : (data.error.message || 'API error');
|
|
throw new Error(msg);
|
|
}
|
|
if (data.choices && data.choices[0] && data.choices[0].message) {
|
|
this.acOutput = (data.choices[0].message.content || '').trim();
|
|
} else {
|
|
throw new Error('Empty response from model.');
|
|
}
|
|
} catch (e) {
|
|
this.acError = e.message || 'Request failed.';
|
|
} finally {
|
|
this.acLoading = false;
|
|
}
|
|
},
|
|
acCopyOutput: function() {
|
|
if (this.acOutput) {
|
|
this.copyToClipboard(this.acOutput);
|
|
}
|
|
},
|
|
acGetLexemeAnalysis: function() {
|
|
return this.acLexemeAnalysis || { totalFindings: 0, findings: [], summary: 'No Latin-root wording findings.' };
|
|
},
|
|
acNeutralizeInput: function() {
|
|
const analysis = this.acGetLexemeAnalysis();
|
|
if (!analysis.totalFindings || !window.LexemeAnalysis || typeof window.LexemeAnalysis.neutralizeText !== 'function') {
|
|
return;
|
|
}
|
|
this.acInput = window.LexemeAnalysis.neutralizeText(this.acInput, analysis);
|
|
if (typeof this.showNotification === 'function') {
|
|
this.showNotification('Applied neutral Latin-root rewrites', 'success', 'fas fa-seedling');
|
|
}
|
|
},
|
|
acApplyLexemeRewrite: function(term, rewrite) {
|
|
if (!term || !rewrite) {
|
|
return;
|
|
}
|
|
const escapedTerm = String(term).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
this.acInput = this.acInput.replace(new RegExp('\\b' + escapedTerm + '\\b', 'i'), rewrite);
|
|
if (typeof this.showNotification === 'function') {
|
|
this.showNotification('Applied rewrite for ' + term, 'success', 'fas fa-pen');
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
getVueWatchers() {
|
|
return {
|
|
acInput: function() {
|
|
if (typeof this.acRefreshLexemeAnalysis === 'function') {
|
|
this.acRefreshLexemeAnalysis();
|
|
}
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
if (typeof module !== 'undefined' && module.exports) {
|
|
module.exports = AntiClassifierTool;
|
|
} else {
|
|
window.AntiClassifierTool = AntiClassifierTool;
|
|
}
|