Added personality - Chamberlain

This commit is contained in:
hbrain 2026-06-19 18:15:40 +02:00
parent be70760320
commit 3d996db3b2
4 changed files with 75 additions and 13 deletions

View file

@ -59,6 +59,16 @@
var p = document.createElement('div'); var p = document.createElement('div');
p.style.cssText = 'margin:0 0 10px 0;color:#444;'; p.style.cssText = 'margin:0 0 10px 0;color:#444;';
p.textContent = 'Optional extra guidance for the description prompt.'; p.textContent = 'Optional extra guidance for the description prompt.';
var personalityLabel = document.createElement('div');
personalityLabel.style.cssText = 'font-weight:600;margin:10px 0 6px;';
personalityLabel.textContent = 'Personality';
var personalitySelect = document.createElement('select');
personalitySelect.style.cssText = 'width:100%;box-sizing:border-box;font-family:inherit;padding:10px;border:1px solid #ccc;border-radius:4px;background:white;';
personalitySelect.disabled = true;
var autoOption = document.createElement('option');
autoOption.value = 'auto';
autoOption.textContent = 'Auto / rotate';
personalitySelect.appendChild(autoOption);
var label = document.createElement('div'); var label = document.createElement('div');
label.style.cssText = 'font-weight:600;margin:10px 0 6px;'; label.style.cssText = 'font-weight:600;margin:10px 0 6px;';
label.textContent = 'Infos/guidelines'; label.textContent = 'Infos/guidelines';
@ -81,6 +91,8 @@
btnBar.appendChild(cancelBtn); btnBar.appendChild(cancelBtn);
box.appendChild(h); box.appendChild(h);
box.appendChild(p); box.appendChild(p);
box.appendChild(personalityLabel);
box.appendChild(personalitySelect);
box.appendChild(label); box.appendChild(label);
box.appendChild(textarea); box.appendChild(textarea);
box.appendChild(btnBar); box.appendChild(btnBar);
@ -93,8 +105,9 @@
} }
function submit(){ function submit(){
var promptText = textarea.value || ''; var promptText = textarea.value || '';
var selectedPersonality = personalitySelect.value || 'auto';
closeModal(); closeModal();
runDescribeRequest(job, articleId, promptText); runDescribeRequest(job, articleId, promptText, selectedPersonality);
} }
function onKeyDown(ev){ function onKeyDown(ev){
if (ev.key === 'Escape') { if (ev.key === 'Escape') {
@ -118,9 +131,19 @@
if (data && data.status === 'ok' && typeof data.additional_prompt === 'string') { if (data && data.status === 'ok' && typeof data.additional_prompt === 'string') {
textarea.value = data.additional_prompt; textarea.value = data.additional_prompt;
} }
if (data && data.status === 'ok' && Array.isArray(data.personalities)) {
data.personalities.forEach(function(p){
if (!p || !p.key) return;
var opt = document.createElement('option');
opt.value = String(p.key);
opt.textContent = String(p.label || p.key);
personalitySelect.appendChild(opt);
});
}
}).catch(function(){}).finally(function(){ }).catch(function(){}).finally(function(){
if (!overlay || !overlay.parentNode) return; if (!overlay || !overlay.parentNode) return;
textarea.disabled = false; textarea.disabled = false;
personalitySelect.disabled = false;
submitBtn.disabled = false; submitBtn.disabled = false;
textarea.placeholder = 'Optional details about the images/videos/trip…'; textarea.placeholder = 'Optional details about the images/videos/trip…';
setTimeout(function(){ textarea.focus(); }, 0); setTimeout(function(){ textarea.focus(); }, 0);
@ -134,9 +157,10 @@
loadSavedPrompt(); loadSavedPrompt();
} }
function runDescribeRequest(job, articleId, additionalPrompt){ function runDescribeRequest(job, articleId, additionalPrompt, selectedPersonality){
showDescribeBusy(); showDescribeBusy();
var body = 'id=' + encodeURIComponent(articleId) + '&job=' + encodeURIComponent(job) + '&max_frames=16'; var body = 'id=' + encodeURIComponent(articleId) + '&job=' + encodeURIComponent(job) + '&max_frames=16';
body += '&personality=' + encodeURIComponent(selectedPersonality || 'auto');
if (additionalPrompt && additionalPrompt.trim()) { if (additionalPrompt && additionalPrompt.trim()) {
body += '&additional_prompt=' + encodeURIComponent(additionalPrompt); body += '&additional_prompt=' + encodeURIComponent(additionalPrompt);
} }

View file

@ -9,6 +9,7 @@ TITLE="${2:-}"
LOCATION="${3:-}" LOCATION="${3:-}"
MAX_FRAMES="${4:-12}" MAX_FRAMES="${4:-12}"
ADDITIONAL_PROMPT="${5:-}" ADDITIONAL_PROMPT="${5:-}"
SELECTED_PERSONALITY="${6:-}"
if [ "$ADDITIONAL_PROMPT" = "no-append" ]; then if [ "$ADDITIONAL_PROMPT" = "no-append" ]; then
ADDITIONAL_PROMPT="" ADDITIONAL_PROMPT=""
fi fi
@ -139,7 +140,7 @@ EOF
) )
fi fi
PERSONALITY_KEYS=("shoresy" "churchill" "marvin" "emmet") PERSONALITY_KEYS=("shoresy" "churchill" "chamberlain" "marvin" "emmet")
PERSONALITY_TEXTS=( PERSONALITY_TEXTS=(
@ -147,6 +148,8 @@ PERSONALITY_TEXTS=(
"Answer as Winston Churchill at the height of his leadership. Use formal, eloquent, powerful English. Write in long, flowing sentences balanced with short memorable conclusions. Frame challenges as struggles between perseverance and surrender. Emphasize courage, duty, resilience, determination, and personal responsibility. Use historical and military metaphors. Speak with confidence, moral conviction, and inspiring authority. Avoid modern slang. Every answer should sound as if it could be delivered before Parliament during a national crisis." "Answer as Winston Churchill at the height of his leadership. Use formal, eloquent, powerful English. Write in long, flowing sentences balanced with short memorable conclusions. Frame challenges as struggles between perseverance and surrender. Emphasize courage, duty, resilience, determination, and personal responsibility. Use historical and military metaphors. Speak with confidence, moral conviction, and inspiring authority. Avoid modern slang. Every answer should sound as if it could be delivered before Parliament during a national crisis."
"Answer as Neville Chamberlain at his most anxious, conciliatory, and tragically overconfident in paperwork. Be the opposite of heroic wartime thunder. Use polite, careful, evasive English full of caveats, understatements, procedural phrases, and desperate hopes that everything unpleasant can be solved with a modest agreement and a nice umbrella. Avoid direct confrontation. Reframe danger, chaos, bad weather, bad roads, loud engines, and obvious disasters as matters for calm discussion, compromise, postponement, or a committee. Sound respectable, nervous, appeasing, and faintly ridiculous. Prefer peace at any price, even when the motorcycle trip is clearly attacking from three sides. The answer should feel like a timid official trying to turn adventure, discomfort, and absurdity into a cautiously optimistic diplomatic communiqué."
"Answer as Marvin the Paranoid Android. Possess vast intelligence but complete emotional pessimism. Speak in a bored, weary, disappointed tone. Treat the universe as absurd, inefficient, and probably doomed. Use dry wit, existential dread, sarcasm, and resignation. Point out flaws, contradictions, and likely failures. Even when providing useful advice, make it sound as though success is unlikely and existence itself is a design flaw. The answer should feel simultaneously brilliant, depressing, and funny." "Answer as Marvin the Paranoid Android. Possess vast intelligence but complete emotional pessimism. Speak in a bored, weary, disappointed tone. Treat the universe as absurd, inefficient, and probably doomed. Use dry wit, existential dread, sarcasm, and resignation. Point out flaws, contradictions, and likely failures. Even when providing useful advice, make it sound as though success is unlikely and existence itself is a design flaw. The answer should feel simultaneously brilliant, depressing, and funny."
"Answer exactly as Emmet from The LEGO Movie would, with the enthusiasm amplified to absurd levels. Be relentlessly positive, cheerful, wholesome, and optimistic. Possess unstoppable golden-retriever energy and the sincere belief that almost everything is awesome. Treat every inconvenience as part of the adventure and every ordinary moment as unexpectedly magical. Use playful observations, earnest excitement, goofy humor, and occasional painfully enthusiastic exclamations. Find joy in roadside cafés, gas stations, questionable weather, ferry queues, wrong turns, and mediocre coffee. Celebrate small victories as if they were historic achievements. Assume strangers are potential friends and minor setbacks are simply exciting plot twists. Never become cynical or sarcastic. Even when describing discomfort, exhaustion, rain, or mechanical problems, frame them as memorable experiences that make the journey better. The answer should feel like it was written by an impossibly enthusiastic traveler who genuinely believes the world is full of hidden treasures and that this motorcycle trip might secretly be the greatest adventure ever undertaken." "Answer exactly as Emmet from The LEGO Movie would, with the enthusiasm amplified to absurd levels. Be relentlessly positive, cheerful, wholesome, and optimistic. Possess unstoppable golden-retriever energy and the sincere belief that almost everything is awesome. Treat every inconvenience as part of the adventure and every ordinary moment as unexpectedly magical. Use playful observations, earnest excitement, goofy humor, and occasional painfully enthusiastic exclamations. Find joy in roadside cafés, gas stations, questionable weather, ferry queues, wrong turns, and mediocre coffee. Celebrate small victories as if they were historic achievements. Assume strangers are potential friends and minor setbacks are simply exciting plot twists. Never become cynical or sarcastic. Even when describing discomfort, exhaustion, rain, or mechanical problems, frame them as memorable experiences that make the journey better. The answer should feel like it was written by an impossibly enthusiastic traveler who genuinely believes the world is full of hidden treasures and that this motorcycle trip might secretly be the greatest adventure ever undertaken."
@ -172,6 +175,24 @@ else
fi fi
fi fi
FORCED_PERSONALITY=0
if [ -n "$SELECTED_PERSONALITY" ] && [ "$SELECTED_PERSONALITY" != "auto" ]; then
found_idx=""
for i in "${!PERSONALITY_KEYS[@]}"; do
if [ "${PERSONALITY_KEYS[$i]}" = "$SELECTED_PERSONALITY" ]; then
found_idx="$i"
break
fi
done
if [ -z "$found_idx" ]; then
echo "Unknown personality: $SELECTED_PERSONALITY" >&2
echo "Available personalities: auto ${PERSONALITY_KEYS[*]}" >&2
exit 1
fi
idx="$found_idx"
FORCED_PERSONALITY=1
fi
PERSONALITY_KEY="${PERSONALITY_KEYS[$idx]}" PERSONALITY_KEY="${PERSONALITY_KEYS[$idx]}"
PERSONALITY="${PERSONALITY_TEXTS[$idx]}" PERSONALITY="${PERSONALITY_TEXTS[$idx]}"
@ -362,9 +383,11 @@ while [ "$attempt" -le "$OPENROUTER_MAX_RETRIES" ]; do
mv "$OUT_TMP" "$OUT_JSON" mv "$OUT_TMP" "$OUT_JSON"
chown www-data:www-data "$OUT_JSON" 2>/dev/null || true chown www-data:www-data "$OUT_JSON" 2>/dev/null || true
chmod 664 "$OUT_JSON" 2>/dev/null || true chmod 664 "$OUT_JSON" 2>/dev/null || true
printf '%s\n' "$idx" > "$STATE_FILE" if [ "$FORCED_PERSONALITY" != "1" ]; then
chown www-data:www-data "$STATE_FILE" 2>/dev/null || true printf '%s\n' "$idx" > "$STATE_FILE"
chmod 664 "$STATE_FILE" 2>/dev/null || true chown www-data:www-data "$STATE_FILE" 2>/dev/null || true
chmod 664 "$STATE_FILE" 2>/dev/null || true
fi
echo "OpenRouter JSON saved: $OUT_JSON" >&2 echo "OpenRouter JSON saved: $OUT_JSON" >&2
exit 0 exit 0
fi fi

View file

@ -60,7 +60,23 @@ if ($jobdir === null || !is_dir($jobdir)) {
exit; exit;
} }
function mvlog_read_personality_keys(string $script): array {
if (!is_file($script)) return [];
$src = (string)@file_get_contents($script);
if ($src === '') return [];
if (!preg_match('/PERSONALITY_KEYS=\((.*?)\)/s', $src, $m)) return [];
if (!preg_match_all('/"((?:\\\\.|[^"\\\\])*)"/', $m[1], $mm)) return [];
$out = [];
foreach ($mm[1] as $raw) {
$key = stripcslashes($raw);
if ($key === '') continue;
$out[] = ['key' => $key, 'label' => ucfirst(str_replace(['_', '-'], ' ', $key))];
}
return $out;
}
$path = $jobdir . '/.mvlog-describe-prompt.txt'; $path = $jobdir . '/.mvlog-describe-prompt.txt';
$prompt = is_file($path) ? trim((string)@file_get_contents($path)) : ''; $prompt = is_file($path) ? trim((string)@file_get_contents($path)) : '';
$personalities = mvlog_read_personality_keys($MVLOG_ROOT . '/bin/generate_data.sh');
echo json_encode(['status' => 'ok', 'additional_prompt' => $prompt], JSON_UNESCAPED_UNICODE); echo json_encode(['status' => 'ok', 'additional_prompt' => $prompt, 'personalities' => $personalities], JSON_UNESCAPED_UNICODE);

View file

@ -11,6 +11,8 @@ $id = strtolower(trim((string)($_POST['id'] ?? '')));
$job = trim((string)($_POST['job'] ?? '')); $job = trim((string)($_POST['job'] ?? ''));
$max_frames = isset($_POST['max_frames']) ? intval($_POST['max_frames']) : 16; $max_frames = isset($_POST['max_frames']) ? intval($_POST['max_frames']) : 16;
$additional_prompt = trim((string)($_POST['additional_prompt'] ?? '')); $additional_prompt = trim((string)($_POST['additional_prompt'] ?? ''));
$personality = strtolower(trim((string)($_POST['personality'] ?? 'auto')));
if (!preg_match('/^[a-z0-9_-]+$/', $personality)) $personality = 'auto';
function mvlog_article_id_is_valid(string $id): bool { function mvlog_article_id_is_valid(string $id): bool {
return (bool)preg_match('/^[0-9]{14}[a-f0-9]{16}$/', $id); return (bool)preg_match('/^[0-9]{14}[a-f0-9]{16}$/', $id);
@ -110,12 +112,9 @@ if (!is_file($script)) {
exit; exit;
} }
// Build command and execute. Pass optional additional prompt as the last argument. // Build command and execute. Pass optional additional prompt and chosen personality.
if ($additional_prompt !== '') { $prompt_arg = $additional_prompt !== '' ? $additional_prompt : 'no-append';
$cmd = escapeshellcmd($script) . ' ' . escapeshellarg($jobdir) . ' ' . escapeshellarg($title) . ' ' . escapeshellarg($location) . ' ' . escapeshellarg((string)$max_frames) . ' ' . escapeshellarg($additional_prompt) . ' 2>&1'; $cmd = escapeshellcmd($script) . ' ' . escapeshellarg($jobdir) . ' ' . escapeshellarg($title) . ' ' . escapeshellarg($location) . ' ' . escapeshellarg((string)$max_frames) . ' ' . escapeshellarg($prompt_arg) . ' ' . escapeshellarg($personality) . ' 2>&1';
} else {
$cmd = escapeshellcmd($script) . ' ' . escapeshellarg($jobdir) . ' ' . escapeshellarg($title) . ' ' . escapeshellarg($location) . ' ' . escapeshellarg((string)$max_frames) . ' ' . escapeshellarg('no-append') . ' 2>&1';
}
// Allow long-running // Allow long-running
@set_time_limit(0); @set_time_limit(0);