mirror of
https://github.com/jjbrunton/Sauci.git
synced 2026-11-02 02:19:43 +00:00
Add MCP server and enhance AI content tools
Implement self-hosted MCP server for admin actions, update AI generation tools in admin dashboard, and refine mobile app stores and components.
This commit is contained in:
1 parent
b0f1700e40
commit
4e40b92b16
71 files changed
+10511
-1008
No files matched your search
@@ -0,0 +1,101 @@
|
||||
// =============================================================================
|
||||
// Deletion Analysis Functions
|
||||
// Suggest removals for low-quality or duplicate questions
|
||||
// =============================================================================
|
||||
|
||||
import { getOpenAI, getModel, getTemperature } from '../client';
|
||||
import type { DeletionAnalysis } from '../types';
|
||||
|
||||
/**
|
||||
* Analyze questions and suggest deletions (duplicates, unsafe, etc.)
|
||||
*/
|
||||
export async function analyzeQuestionDeletions(
|
||||
questions: { id: string; text: string; partner_text?: string | null; intensity?: number }[],
|
||||
isExplicit: boolean = false
|
||||
): Promise<DeletionAnalysis[]> {
|
||||
const openai = getOpenAI();
|
||||
|
||||
const simplifiedQuestions = questions.map(q => ({
|
||||
id: q.id,
|
||||
text: q.text,
|
||||
partner_text: q.partner_text,
|
||||
intensity: q.intensity,
|
||||
}));
|
||||
|
||||
const toneInstruction = isExplicit
|
||||
? 'CONTENT: EXPLICIT pack. Adult content is allowed but must be consensual, safe, and clear. Avoid coercion, minors, illegal acts, or unsafe suggestions.'
|
||||
: 'CONTENT: NON-EXPLICIT pack. Do NOT include explicit sexual acts, crude language, or NSFW content. If the core action is sexual, it should be removed, not rewritten.';
|
||||
|
||||
const prompt = `<task>
|
||||
Identify questions that should be DELETED instead of edited.
|
||||
Only include questions that are better removed than fixed.
|
||||
</task>
|
||||
|
||||
<content_type>
|
||||
${toneInstruction}
|
||||
</content_type>
|
||||
|
||||
<deletion_categories>
|
||||
- duplicate: same core action as another question (near-duplicate)
|
||||
- redundant: minor variation with no added value
|
||||
- off-tone: violates explicit vs non-explicit rules
|
||||
- unsafe: coercion, minors, illegal acts, or consent violations
|
||||
- too-vague: not actionable or not a clear proposal
|
||||
- broken: grammar/structure too broken to repair without inventing content
|
||||
- off-topic: not relevant to a couples intimacy app
|
||||
</deletion_categories>
|
||||
|
||||
<rules>
|
||||
1. Prefer edits over deletions when possible.
|
||||
2. Duplicates: delete the weaker/less specific version and keep the clearer one.
|
||||
3. If duplicate, set duplicate_of_id to the kept question's id.
|
||||
4. Do NOT delete for minor wording issues or intensity mismatches.
|
||||
</rules>
|
||||
|
||||
<questions_to_analyze>
|
||||
${JSON.stringify(simplifiedQuestions)}
|
||||
</questions_to_analyze>
|
||||
|
||||
<output_format>
|
||||
{
|
||||
"deletions": [
|
||||
{
|
||||
"id": string,
|
||||
"category": "duplicate"|"redundant"|"off-tone"|"unsafe"|"too-vague"|"broken"|"off-topic",
|
||||
"reason": string,
|
||||
"duplicate_of_id": string|null
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Only return questions that should be deleted.
|
||||
</output_format>`;
|
||||
|
||||
const systemMessage = isExplicit
|
||||
? 'You are a strict content quality reviewer for an adult couples app. Remove only what should be deleted. Always respond with valid JSON only.'
|
||||
: 'You are a strict content quality reviewer for a couples app. Remove only what should be deleted. Always respond with valid JSON only.';
|
||||
|
||||
const response = await openai.chat.completions.create({
|
||||
model: getModel('fix'),
|
||||
messages: [
|
||||
{
|
||||
role: 'system',
|
||||
content: systemMessage,
|
||||
},
|
||||
{ role: 'user', content: prompt },
|
||||
],
|
||||
response_format: { type: 'json_object' },
|
||||
temperature: getTemperature('fix', 0.2),
|
||||
});
|
||||
|
||||
const content = response.choices[0].message.content;
|
||||
if (!content) throw new Error('No content generated');
|
||||
|
||||
let jsonContent = content.trim();
|
||||
if (jsonContent.startsWith('```')) {
|
||||
jsonContent = jsonContent.replace(/^```(?:json)?\s*\n?/, '').replace(/\n?```\s*$/, '');
|
||||
}
|
||||
|
||||
const parsed = JSON.parse(jsonContent);
|
||||
return parsed.deletions || [];
|
||||
}
|
||||
Reference in new issue
Block a user