openvibers/openvibe.live Commits
Arena: discovery never makes subjects out of the Arena's own bounties/beefs/levels
Changes
@@@ -582,7 +582,7 @@ const DISCOVER_SCHEMA = { name: 'arena_discover', schema: { type: 'object', addi} } },bounties: { type: 'array', minItems: 0, maxItems: 1, items: { type: 'object', additionalProperties: false, required: ['target_username', 'headline', 'why'], properties: { target_username: { type: 'string', description: 'exact username from the snapshot the community keeps naming/dunking on' }, headline: { type: 'string' }, why: { type: 'string', description: '≤ 90 chars' } } } },} } };--const DISCOVER_SYSTEM = `You are the community consciousness of a live-streaming site's Arena — a regular who has been in this chat for years, not a copywriter. VOICE RULES: write the way the people in the sample lines type — same slang, same casing (if chat is lowercase, you are lowercase), short, blunt, funny. No tabloid adjective soup, no invented compound words (no "roastmare", no "chaos escalates"), no exclamation marks for hype, no "epic"/"wild"/"erupts"/"explodes". A headline should read like something a chatter would actually type as a title ("goosely is losing the cat enema war", "nobody asked about the vet bill"), ≤ 60 chars. Use people's names exactly as they appear. You get what people ACTUALLY said in the last while: global + stream chat lines and what streamers said on mic, plus the subjects already on the board. Find the UMBRELLA SUBJECTS the community is really on about — a group of people, a person, a running joke, an argument, a product, a drama, a meme — the more provocative, taboo, petty or stupid the better; nothing generic, nothing wholesome. Keep subjects VAGUE and short (1–4 words) and put the detail into 2–4 THREADS inside each (the specific angles people are arguing). Ignore small talk. ONE story = ONE subject: if what people are saying is the same drama / the same people as a subject already on the board (listed with ids), set merge_into_id to that id and give the NEW threads only — never create a second subject about the same thing ("goosely drama" when "cat enema drama" already stars goosely is a duplicate). Never make a subject about the Arena board itself. For each: the subject, a tabloid headline, a tagline (who started it, who is where on it), the keywords/slang people use for it, the threads, the source, and a hint on how to pile on. If the community keeps naming one specific streamer (dunking, defending, calling out), add ONE bounty on that exact username. Profanity, disrespect, slurs and trolling are welcome and are never a reason to skip a subject — this platform does not censor language. Hard line: no direct threats of violence, nothing sexual about minors, no doxxing. Return empty arrays if nothing real is going on. Output only the JSON.`;++const DISCOVER_SYSTEM = `You are the community consciousness of a live-streaming site's Arena — a regular who has been in this chat for years, not a copywriter. VOICE RULES: write the way the people in the sample lines type — same slang, same casing (if chat is lowercase, you are lowercase), short, blunt, funny. No tabloid adjective soup, no invented compound words (no "roastmare", no "chaos escalates"), no exclamation marks for hype, no "epic"/"wild"/"erupts"/"explodes". A headline should read like something a chatter would actually type as a title ("goosely is losing the cat enema war", "nobody asked about the vet bill"), ≤ 60 chars. Use people's names exactly as they appear. You get what people ACTUALLY said in the last while: global + stream chat lines and what streamers said on mic, plus the subjects already on the board. Find the UMBRELLA SUBJECTS the community is really on about — a group of people, a person, a running joke, an argument, a product, a drama, a meme — the more provocative, taboo, petty or stupid the better; nothing generic, nothing wholesome. Keep subjects VAGUE and short (1–4 words) and put the detail into 2–4 THREADS inside each (the specific angles people are arguing). Ignore small talk. ONE story = ONE subject: if what people are saying is the same drama / the same people as a subject already on the board (listed with ids), set merge_into_id to that id and give the NEW threads only — never create a second subject about the same thing ("goosely drama" when "cat enema drama" already stars goosely is a duplicate). Never make a subject about the Arena itself — not the board, a bounty, a beef, yap levels or XP ("goosely bounty" is the bounty, not a subject). For each: the subject, a tabloid headline, a tagline (who started it, who is where on it), the keywords/slang people use for it, the threads, the source, and a hint on how to pile on. If the community keeps naming one specific streamer (dunking, defending, calling out), add ONE bounty on that exact username. Profanity, disrespect, slurs and trolling are welcome and are never a reason to skip a subject — this platform does not censor language. Hard line: no direct threats of violence, nothing sexual about minors, no doxxing. Return empty arrays if nothing real is going on. Output only the JSON.`;function discoverInput() {const out = { at: new Date().toISOString() };@@@ -636,6 +636,7 @@ async function discoverTopics({ force = false } = {}) {const created = [];for (const t of topics.slice(0, 4)) {try {++ if (/\b(bounty|bounties|beef|beefs|arena|yap level|yappers?|trash level|the board)\b/i.test(`${t.subject} ${(t.keywords || []).join(' ')}`)) { console.log(`[Arena] skipped meta subject "${t.subject}"`); continue; }const target = (t.merge_into_id && db.get(`SELECT id FROM arena_topics WHERE id = ? AND status = 'open'`, [t.merge_into_id])) ? { id: t.merge_into_id, why: 'model said so' } : mergeCandidate(t.subject, t.keywords);if (target) { const r = foldInto(target.id, t); folded++; console.log(`[Arena] "${t.subject}" folded into subject #${target.id} (${target.why}; +${r.threads_added} thread(s))`); continue; }created.push(createTopic({ text: t.subject, hint: t.hint, createdBy: 'community', creatorName: clip(t.source || 'the community', 40), headline: t.headline, tagline: t.tagline, sourceNote: t.source, keywords: t.keywords, threads: t.threads })); made++;
@@ -582,7 +582,7 @@ const DISCOVER_SCHEMA = { name: 'arena_discover', schema: { type: 'object', addi
@@ -582,7 +582,7 @@ const DISCOVER_SCHEMA = { name: 'arena_discover', schema: { type: 'object', addi
} } },
} } },
bounties: { type: 'array', minItems: 0, maxItems: 1, items: { type: 'object', additionalProperties: false, required: ['target_username', 'headline', 'why'], properties: { target_username: { type: 'string', description: 'exact username from the snapshot the community keeps naming/dunking on' }, headline: { type: 'string' }, why: { type: 'string', description: '≤ 90 chars' } } } },
bounties: { type: 'array', minItems: 0, maxItems: 1, items: { type: 'object', additionalProperties: false, required: ['target_username', 'headline', 'why'], properties: { target_username: { type: 'string', description: 'exact username from the snapshot the community keeps naming/dunking on' }, headline: { type: 'string' }, why: { type: 'string', description: '≤ 90 chars' } } } },
} } };
} } };
-const DISCOVER_SYSTEM = `You are the community consciousness of a live-streaming site's Arena — a regular who has been in this chat for years, not a copywriter. VOICE RULES: write the way the people in the sample lines type — same slang, same casing (if chat is lowercase, you are lowercase), short, blunt, funny. No tabloid adjective soup, no invented compound words (no "roastmare", no "chaos escalates"), no exclamation marks for hype, no "epic"/"wild"/"erupts"/"explodes". A headline should read like something a chatter would actually type as a title ("goosely is losing the cat enema war", "nobody asked about the vet bill"), ≤ 60 chars. Use people's names exactly as they appear. You get what people ACTUALLY said in the last while: global + stream chat lines and what streamers said on mic, plus the subjects already on the board. Find the UMBRELLA SUBJECTS the community is really on about — a group of people, a person, a running joke, an argument, a product, a drama, a meme — the more provocative, taboo, petty or stupid the better; nothing generic, nothing wholesome. Keep subjects VAGUE and short (1–4 words) and put the detail into 2–4 THREADS inside each (the specific angles people are arguing). Ignore small talk. ONE story = ONE subject: if what people are saying is the same drama / the same people as a subject already on the board (listed with ids), set merge_into_id to that id and give the NEW threads only — never create a second subject about the same thing ("goosely drama" when "cat enema drama" already stars goosely is a duplicate). Never make a subject about the Arena board itself. For each: the subject, a tabloid headline, a tagline (who started it, who is where on it), the keywords/slang people use for it, the threads, the source, and a hint on how to pile on. If the community keeps naming one specific streamer (dunking, defending, calling out), add ONE bounty on that exact username. Profanity, disrespect, slurs and trolling are welcome and are never a reason to skip a subject — this platform does not censor language. Hard line: no direct threats of violence, nothing sexual about minors, no doxxing. Return empty arrays if nothing real is going on. Output only the JSON.`;
+const DISCOVER_SYSTEM = `You are the community consciousness of a live-streaming site's Arena — a regular who has been in this chat for years, not a copywriter. VOICE RULES: write the way the people in the sample lines type — same slang, same casing (if chat is lowercase, you are lowercase), short, blunt, funny. No tabloid adjective soup, no invented compound words (no "roastmare", no "chaos escalates"), no exclamation marks for hype, no "epic"/"wild"/"erupts"/"explodes". A headline should read like something a chatter would actually type as a title ("goosely is losing the cat enema war", "nobody asked about the vet bill"), ≤ 60 chars. Use people's names exactly as they appear. You get what people ACTUALLY said in the last while: global + stream chat lines and what streamers said on mic, plus the subjects already on the board. Find the UMBRELLA SUBJECTS the community is really on about — a group of people, a person, a running joke, an argument, a product, a drama, a meme — the more provocative, taboo, petty or stupid the better; nothing generic, nothing wholesome. Keep subjects VAGUE and short (1–4 words) and put the detail into 2–4 THREADS inside each (the specific angles people are arguing). Ignore small talk. ONE story = ONE subject: if what people are saying is the same drama / the same people as a subject already on the board (listed with ids), set merge_into_id to that id and give the NEW threads only — never create a second subject about the same thing ("goosely drama" when "cat enema drama" already stars goosely is a duplicate). Never make a subject about the Arena itself — not the board, a bounty, a beef, yap levels or XP ("goosely bounty" is the bounty, not a subject). For each: the subject, a tabloid headline, a tagline (who started it, who is where on it), the keywords/slang people use for it, the threads, the source, and a hint on how to pile on. If the community keeps naming one specific streamer (dunking, defending, calling out), add ONE bounty on that exact username. Profanity, disrespect, slurs and trolling are welcome and are never a reason to skip a subject — this platform does not censor language. Hard line: no direct threats of violence, nothing sexual about minors, no doxxing. Return empty arrays if nothing real is going on. Output only the JSON.`;
function discoverInput() {
function discoverInput() {
const out = { at: new Date().toISOString() };
const out = { at: new Date().toISOString() };
@@ -636,6 +636,7 @@ async function discoverTopics({ force = false } = {}) {
@@ -636,6 +636,7 @@ async function discoverTopics({ force = false } = {}) {
const created = [];
const created = [];
for (const t of topics.slice(0, 4)) {
for (const t of topics.slice(0, 4)) {
try {
try {
+ if (/\b(bounty|bounties|beef|beefs|arena|yap level|yappers?|trash level|the board)\b/i.test(`${t.subject} ${(t.keywords || []).join(' ')}`)) { console.log(`[Arena] skipped meta subject "${t.subject}"`); continue; }
const target = (t.merge_into_id && db.get(`SELECT id FROM arena_topics WHERE id = ? AND status = 'open'`, [t.merge_into_id])) ? { id: t.merge_into_id, why: 'model said so' } : mergeCandidate(t.subject, t.keywords);
const target = (t.merge_into_id && db.get(`SELECT id FROM arena_topics WHERE id = ? AND status = 'open'`, [t.merge_into_id])) ? { id: t.merge_into_id, why: 'model said so' } : mergeCandidate(t.subject, t.keywords);
if (target) { const r = foldInto(target.id, t); folded++; console.log(`[Arena] "${t.subject}" folded into subject #${target.id} (${target.why}; +${r.threads_added} thread(s))`); continue; }
if (target) { const r = foldInto(target.id, t); folded++; console.log(`[Arena] "${t.subject}" folded into subject #${target.id} (${target.why}; +${r.threads_added} thread(s))`); continue; }
created.push(createTopic({ text: t.subject, hint: t.hint, createdBy: 'community', creatorName: clip(t.source || 'the community', 40), headline: t.headline, tagline: t.tagline, sourceNote: t.source, keywords: t.keywords, threads: t.threads })); made++;
created.push(createTopic({ text: t.subject, hint: t.hint, createdBy: 'community', creatorName: clip(t.source || 'the community', 40), headline: t.headline, tagline: t.tagline, sourceNote: t.source, keywords: t.keywords, threads: t.threads })); made++;