openvibers/openvibe.ai Commits
AI: live.arena.drama, the Arena Alert desk's headline and blurb for one measured event (grounded in the facts given; roasts the stream, never the person's identity) (#97)
Changes
@@@ -118,6 +118,9 @@ const PREPARE = {'live.arena.headline'(input) {return { vars: { payload: input } };},++ 'live.arena.drama'(input) {++ return { vars: { payload: input } };++ },'live.clips.confirm'(input) {const clean = (t, n) => String(t || '').replace(/\s+/g, ' ').trim().slice(0, n);return { vars: {@@@ -341,6 +344,12 @@ const POSTPROCESS = {const j = r.json || parseJsonLoose(r.text);return j && j.headline ? { headline: String(j.headline).slice(0, 120) } : null;},++ 'live.arena.drama'(r) {++ const j = r.json || parseJsonLoose(r.text);++ if (!j || !j.headline || !j.blurb) return null;++ const alert = Math.min(5, Math.max(1, Math.round(Number(j.alert) || 1)));++ return { headline: String(j.headline).replace(/\s+/g, ' ').trim().slice(0, 130), blurb: String(j.blurb).replace(/\s+/g, ' ').trim().slice(0, 480), alert };++ },'live.clips.confirm'(r) {const j = r.json || parseJsonLoose(r.text);if (!j || typeof j !== 'object') return null;@@@ -142,6 +142,15 @@ const templates = [user_prompt: "{{json payload}}",default_route: 'live.chat', owner: 'live', metadata: { json_name: 'arena_headline' },},++ {++ key: 'live.arena.drama', name: "Live: an Arena Alert story",++ description: "From arena/drama.js (arena_drama): one measured event on the site (a rage quit, a viewer crash, a meltdown, a beef verdict…) and its facts in; a drama-news headline and blurb out.",++ input_schema: { type: 'object' },++ output_schema: {"type": "object", "additionalProperties": false, "required": ["headline", "blurb", "alert"], "properties": {"headline": {"type": "string", "description": "≤ 110 chars"}, "blurb": {"type": "string", "description": "1-3 sentences, ≤ 420 chars"}, "alert": {"type": "integer", "minimum": 1, "maximum": 5}}},++ system_prompt: "You are the anchor of ARENA ALERT, the streaming site's own drama-news desk: breaking-news hype, tabloid energy, savage roasts, lolcow commentary, the way internet drama channels cover streamers. Every story is about real streamers on this site and comes with FACTS measured by the site. Rules: (1) use only the facts given: never invent an event, a number, a motive, a relationship or an accusation; you may speculate only as an obvious joke framed as a question (\"rage quit?\"). (2) Roast what they did on stream, not who they are: no slurs about race, religion, sexuality, gender or disability, no sexual content, no threats, no doxxing, no self-harm jokes. Swearing is fine. (3) Quotes in the facts are their own words and may be quoted verbatim. Write: headline (≤ 110 chars, ALL the drama, may start with 🚨), blurb (1-3 punchy sentences that state the facts with numbers), alert (1-5: how big this is on this small site). Output only the JSON.",++ user_prompt: "{{json payload}}",++ default_route: 'live.chat', owner: 'live', metadata: { json_name: 'arena_drama' },++ },{key: 'live.clips.confirm', name: "Live: is this chat spike clip-worthy",description: "From auto-clip-job.js (auto_clip_confirm): scene notes, transcript, sounds and chat around a spike.",@@@ -409,6 +418,14 @@ const structured = [steps: [{ kind: 'llm', template: 'live.arena.headline', operation: 'generate', output: 'json', prepare: 'live.arena.headline', postprocess: 'live.arena.headline', params: { max_tokens: 80, temperature: 1.0, timeout_ms: 15000 } }],cache_mode: 'none',},++ {++ key: 'live.arena.drama', name: "Arena Alert story", namespace: 'live',++ description: "arena/drama.js: one measured event (kind, the streamers, the facts, an optional quote) in; a grounded drama-news headline, blurb and alert level out.",++ input_schema: { type: 'object', required: ['kind', 'facts'], properties: { kind: { type: 'string', maxLength: 40 }, streamer: { type: 'string', maxLength: 80 }, other: { type: ['string', 'null'], maxLength: 80 }, facts: { type: 'object' }, quote: { type: ['string', 'null'], maxLength: 400 } } },++ output_schema: {"type": "object", "additionalProperties": false, "required": ["headline", "blurb", "alert"], "properties": {"headline": {"type": "string"}, "blurb": {"type": "string"}, "alert": {"type": "integer", "minimum": 1, "maximum": 5}}},++ steps: [{ kind: 'llm', template: 'live.arena.drama', operation: 'generate', output: 'json', prepare: 'live.arena.drama', postprocess: 'live.arena.drama', params: { max_tokens: 220, temperature: 1.0, timeout_ms: 20000 } }],++ cache_mode: 'none',++ },{key: 'live.clips.confirm', name: "Is this chat spike clip-worthy", namespace: 'live',description: "The prompt Live used to render (auto-clip-job.js): scene notes, timed speech and sounds, and chat around a spike in; clip or not, with a title, out.",@@@ -65,6 +65,7 @@ EXAMPLES['live.viewers.clone'] = { name: 'bob', overview: 'Hypes every build.',EXAMPLES['live.arena.persona'] = { facts: { name: 'Ann', handle: 'ann', category: 'desktop', ratings: { heat: 70 }, things_they_said_on_stream: ['this borrow checker hates me'], roster_rivals: ['bob'] } };EXAMPLES['live.arena.quotes'] = { lines: ['this borrow checker hates me and I hate it back', 'chat you are all backseat compilers', 'I have never been this cooked'] };EXAMPLES['live.arena.headline'] = { kind: 'open', a: 'ann', b: 'bob', line: 'bob streams to his own alt accounts', rematch: false };++EXAMPLES['live.arena.drama'] = { kind: 'rage_quit', streamer: 'bob', other: null, facts: { minutes_live: 6, usual_minutes: 140, last_title: 'ranked grind' }, quote: 'this game is rigged' };EXAMPLES['live.clips.confirm'] = { scene: ['streamer jumps up cheering'], transcript: [{ t: 94, text: 'IT COMPILES' }], sounds: [{ t: 95, label: 'Cheering', confidence: 0.8 }], chat: ['LETS GO', 'poggers'] };EXAMPLES['live.chat.global'] = { window_label: 'past 3 hours', prior_memory: 'croutons are a running joke', recent_labels: ['the crouton war'], messages: [{ mins_ago: 12, where: 'global', author: 'goosely', kind: null, text: 'croutons are soup confetti' }, { mins_ago: 3, where: '#ann', author: 'bob', kind: 'emote', text: 'waves' }] };EXAMPLES['live.chat.profile'] = { subject_kind: 'relay', name: 'KickFan', platform: 'kick', recent_24h: false, seen: 0, prior_memory: '', messages: [{ mins_ago: 2000, author: 'KickFan', text: 'hello from kick' }] };
@@ -118,6 +118,9 @@ const PREPARE = {
@@ -118,6 +118,9 @@ const PREPARE = {
'live.arena.headline'(input) {
'live.arena.headline'(input) {
return { vars: { payload: input } };
return { vars: { payload: input } };
},
},
+ 'live.arena.drama'(input) {
+ return { vars: { payload: input } };
+ },
'live.clips.confirm'(input) {
'live.clips.confirm'(input) {
const clean = (t, n) => String(t || '').replace(/\s+/g, ' ').trim().slice(0, n);
const clean = (t, n) => String(t || '').replace(/\s+/g, ' ').trim().slice(0, n);
return { vars: {
return { vars: {
@@ -341,6 +344,12 @@ const POSTPROCESS = {
@@ -341,6 +344,12 @@ const POSTPROCESS = {
const j = r.json || parseJsonLoose(r.text);
const j = r.json || parseJsonLoose(r.text);
return j && j.headline ? { headline: String(j.headline).slice(0, 120) } : null;
return j && j.headline ? { headline: String(j.headline).slice(0, 120) } : null;
},
},
+ 'live.arena.drama'(r) {
+ const j = r.json || parseJsonLoose(r.text);
+ if (!j || !j.headline || !j.blurb) return null;
+ const alert = Math.min(5, Math.max(1, Math.round(Number(j.alert) || 1)));
+ return { headline: String(j.headline).replace(/\s+/g, ' ').trim().slice(0, 130), blurb: String(j.blurb).replace(/\s+/g, ' ').trim().slice(0, 480), alert };
+ },
'live.clips.confirm'(r) {
'live.clips.confirm'(r) {
const j = r.json || parseJsonLoose(r.text);
const j = r.json || parseJsonLoose(r.text);
if (!j || typeof j !== 'object') return null;
if (!j || typeof j !== 'object') return null;
@@ -142,6 +142,15 @@ const templates = [
@@ -142,6 +142,15 @@ const templates = [
user_prompt: "{{json payload}}",
user_prompt: "{{json payload}}",
default_route: 'live.chat', owner: 'live', metadata: { json_name: 'arena_headline' },
default_route: 'live.chat', owner: 'live', metadata: { json_name: 'arena_headline' },
},
},
+ {
+ key: 'live.arena.drama', name: "Live: an Arena Alert story",
+ description: "From arena/drama.js (arena_drama): one measured event on the site (a rage quit, a viewer crash, a meltdown, a beef verdict…) and its facts in; a drama-news headline and blurb out.",
+ input_schema: { type: 'object' },
+ output_schema: {"type": "object", "additionalProperties": false, "required": ["headline", "blurb", "alert"], "properties": {"headline": {"type": "string", "description": "≤ 110 chars"}, "blurb": {"type": "string", "description": "1-3 sentences, ≤ 420 chars"}, "alert": {"type": "integer", "minimum": 1, "maximum": 5}}},
+ system_prompt: "You are the anchor of ARENA ALERT, the streaming site's own drama-news desk: breaking-news hype, tabloid energy, savage roasts, lolcow commentary, the way internet drama channels cover streamers. Every story is about real streamers on this site and comes with FACTS measured by the site. Rules: (1) use only the facts given: never invent an event, a number, a motive, a relationship or an accusation; you may speculate only as an obvious joke framed as a question (\"rage quit?\"). (2) Roast what they did on stream, not who they are: no slurs about race, religion, sexuality, gender or disability, no sexual content, no threats, no doxxing, no self-harm jokes. Swearing is fine. (3) Quotes in the facts are their own words and may be quoted verbatim. Write: headline (≤ 110 chars, ALL the drama, may start with 🚨), blurb (1-3 punchy sentences that state the facts with numbers), alert (1-5: how big this is on this small site). Output only the JSON.",
+ user_prompt: "{{json payload}}",
+ default_route: 'live.chat', owner: 'live', metadata: { json_name: 'arena_drama' },
+ },
{
{
key: 'live.clips.confirm', name: "Live: is this chat spike clip-worthy",
key: 'live.clips.confirm', name: "Live: is this chat spike clip-worthy",
description: "From auto-clip-job.js (auto_clip_confirm): scene notes, transcript, sounds and chat around a spike.",
description: "From auto-clip-job.js (auto_clip_confirm): scene notes, transcript, sounds and chat around a spike.",
@@ -409,6 +418,14 @@ const structured = [
@@ -409,6 +418,14 @@ const structured = [
steps: [{ kind: 'llm', template: 'live.arena.headline', operation: 'generate', output: 'json', prepare: 'live.arena.headline', postprocess: 'live.arena.headline', params: { max_tokens: 80, temperature: 1.0, timeout_ms: 15000 } }],
steps: [{ kind: 'llm', template: 'live.arena.headline', operation: 'generate', output: 'json', prepare: 'live.arena.headline', postprocess: 'live.arena.headline', params: { max_tokens: 80, temperature: 1.0, timeout_ms: 15000 } }],
cache_mode: 'none',
cache_mode: 'none',
},
},
+ {
+ key: 'live.arena.drama', name: "Arena Alert story", namespace: 'live',
+ description: "arena/drama.js: one measured event (kind, the streamers, the facts, an optional quote) in; a grounded drama-news headline, blurb and alert level out.",
+ input_schema: { type: 'object', required: ['kind', 'facts'], properties: { kind: { type: 'string', maxLength: 40 }, streamer: { type: 'string', maxLength: 80 }, other: { type: ['string', 'null'], maxLength: 80 }, facts: { type: 'object' }, quote: { type: ['string', 'null'], maxLength: 400 } } },
+ output_schema: {"type": "object", "additionalProperties": false, "required": ["headline", "blurb", "alert"], "properties": {"headline": {"type": "string"}, "blurb": {"type": "string"}, "alert": {"type": "integer", "minimum": 1, "maximum": 5}}},
+ steps: [{ kind: 'llm', template: 'live.arena.drama', operation: 'generate', output: 'json', prepare: 'live.arena.drama', postprocess: 'live.arena.drama', params: { max_tokens: 220, temperature: 1.0, timeout_ms: 20000 } }],
+ cache_mode: 'none',
+ },
{
{
key: 'live.clips.confirm', name: "Is this chat spike clip-worthy", namespace: 'live',
key: 'live.clips.confirm', name: "Is this chat spike clip-worthy", namespace: 'live',
description: "The prompt Live used to render (auto-clip-job.js): scene notes, timed speech and sounds, and chat around a spike in; clip or not, with a title, out.",
description: "The prompt Live used to render (auto-clip-job.js): scene notes, timed speech and sounds, and chat around a spike in; clip or not, with a title, out.",
@@ -65,6 +65,7 @@ EXAMPLES['live.viewers.clone'] = { name: 'bob', overview: 'Hypes every build.',
@@ -65,6 +65,7 @@ EXAMPLES['live.viewers.clone'] = { name: 'bob', overview: 'Hypes every build.',
EXAMPLES['live.arena.persona'] = { facts: { name: 'Ann', handle: 'ann', category: 'desktop', ratings: { heat: 70 }, things_they_said_on_stream: ['this borrow checker hates me'], roster_rivals: ['bob'] } };
EXAMPLES['live.arena.persona'] = { facts: { name: 'Ann', handle: 'ann', category: 'desktop', ratings: { heat: 70 }, things_they_said_on_stream: ['this borrow checker hates me'], roster_rivals: ['bob'] } };
EXAMPLES['live.arena.quotes'] = { lines: ['this borrow checker hates me and I hate it back', 'chat you are all backseat compilers', 'I have never been this cooked'] };
EXAMPLES['live.arena.quotes'] = { lines: ['this borrow checker hates me and I hate it back', 'chat you are all backseat compilers', 'I have never been this cooked'] };
EXAMPLES['live.arena.headline'] = { kind: 'open', a: 'ann', b: 'bob', line: 'bob streams to his own alt accounts', rematch: false };
EXAMPLES['live.arena.headline'] = { kind: 'open', a: 'ann', b: 'bob', line: 'bob streams to his own alt accounts', rematch: false };
+EXAMPLES['live.arena.drama'] = { kind: 'rage_quit', streamer: 'bob', other: null, facts: { minutes_live: 6, usual_minutes: 140, last_title: 'ranked grind' }, quote: 'this game is rigged' };
EXAMPLES['live.clips.confirm'] = { scene: ['streamer jumps up cheering'], transcript: [{ t: 94, text: 'IT COMPILES' }], sounds: [{ t: 95, label: 'Cheering', confidence: 0.8 }], chat: ['LETS GO', 'poggers'] };
EXAMPLES['live.clips.confirm'] = { scene: ['streamer jumps up cheering'], transcript: [{ t: 94, text: 'IT COMPILES' }], sounds: [{ t: 95, label: 'Cheering', confidence: 0.8 }], chat: ['LETS GO', 'poggers'] };
EXAMPLES['live.chat.global'] = { window_label: 'past 3 hours', prior_memory: 'croutons are a running joke', recent_labels: ['the crouton war'], messages: [{ mins_ago: 12, where: 'global', author: 'goosely', kind: null, text: 'croutons are soup confetti' }, { mins_ago: 3, where: '#ann', author: 'bob', kind: 'emote', text: 'waves' }] };
EXAMPLES['live.chat.global'] = { window_label: 'past 3 hours', prior_memory: 'croutons are a running joke', recent_labels: ['the crouton war'], messages: [{ mins_ago: 12, where: 'global', author: 'goosely', kind: null, text: 'croutons are soup confetti' }, { mins_ago: 3, where: '#ann', author: 'bob', kind: 'emote', text: 'waves' }] };
EXAMPLES['live.chat.profile'] = { subject_kind: 'relay', name: 'KickFan', platform: 'kick', recent_24h: false, seen: 0, prior_memory: '', messages: [{ mins_ago: 2000, author: 'KickFan', text: 'hello from kick' }] };
EXAMPLES['live.chat.profile'] = { subject_kind: 'relay', name: 'KickFan', platform: 'kick', recent_24h: false, seen: 0, prior_memory: '', messages: [{ mins_ago: 2000, author: 'KickFan', text: 'hello from kick' }] };