Spaces:
Running
Running
VinOS Agent commited on
Commit ·
b11a2d7
1
Parent(s): c62723a
SEO Engine V4: Parametric Advanced Writing constraints (POV, Intent, Tone, Size)
Browse files- database/local_db.json +6 -0
- server.js +32 -24
- skills/seo_writer.js +4 -1
database/local_db.json
CHANGED
|
@@ -25,6 +25,12 @@
|
|
| 25 |
"active_experiments": 0
|
| 26 |
},
|
| 27 |
"telegram_log": [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
{
|
| 29 |
"direction": "OUT",
|
| 30 |
"chatId": "8743583463",
|
|
|
|
| 25 |
"active_experiments": 0
|
| 26 |
},
|
| 27 |
"telegram_log": [
|
| 28 |
+
{
|
| 29 |
+
"direction": "OUT",
|
| 30 |
+
"chatId": "8743583463",
|
| 31 |
+
"text": "<b>VinOS Daily Check-in</b>\nHow is the Token Gashapon project coming along? Ready for the next arbitrage move?",
|
| 32 |
+
"ts": "2026-03-21T19:17:10.784Z"
|
| 33 |
+
},
|
| 34 |
{
|
| 35 |
"direction": "OUT",
|
| 36 |
"chatId": "8743583463",
|
server.js
CHANGED
|
@@ -392,36 +392,44 @@ app.post('/api/telegram-webhook', async (req, res) => {
|
|
| 392 |
}
|
| 393 |
}
|
| 394 |
} else if (userText.toLowerCase().startsWith('/write')) {
|
| 395 |
-
|
|
|
|
| 396 |
|
| 397 |
-
|
| 398 |
-
|
| 399 |
-
let topicIndex = 1;
|
| 400 |
|
| 401 |
let sites = {};
|
| 402 |
try { sites = JSON.parse(process.env.WP_SITES_JSON || "{}"); } catch(e){}
|
| 403 |
const siteKeys = Object.keys(sites);
|
| 404 |
-
|
| 405 |
-
|
| 406 |
-
|
| 407 |
-
|
| 408 |
-
|
| 409 |
-
|
| 410 |
-
|
| 411 |
-
|
| 412 |
-
|
| 413 |
-
|
| 414 |
-
|
| 415 |
-
|
| 416 |
-
|
| 417 |
-
|
| 418 |
-
if (!topic) {
|
| 419 |
-
const siteList = siteKeys.length > 0 ? `\n\n🏢 <b>Available Sites:</b> ${siteKeys.join(', ')}` : '\n\n⚠️ No sites configured in WP_SITES_JSON.';
|
| 420 |
-
await apiCaller.sendTelegramMessage(chatId, `❌ Usage: /write [siteName] [short|medium|dense] [topic]${siteList}`);
|
| 421 |
} else {
|
| 422 |
-
const
|
| 423 |
-
|
| 424 |
-
const
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 425 |
if (articleRes.success) {
|
| 426 |
await apiCaller.sendTelegramMessage(chatId, `✅ <b>Article Generated!</b> Scoring EEAT...`);
|
| 427 |
const scoreRes = await seoWriter.scoreEEAT(articleRes.html);
|
|
|
|
| 392 |
}
|
| 393 |
}
|
| 394 |
} else if (userText.toLowerCase().startsWith('/write')) {
|
| 395 |
+
// Parse arguments smartly handling quotes: /write site "Topic" size "POV" "Intent" "Tone"
|
| 396 |
+
const args = userText.match(/(?:[^\s"']+|"[^"]*"|'[^']*')+/g) || [];
|
| 397 |
|
| 398 |
+
// Remove quotes from matched strings
|
| 399 |
+
const cleanArgs = args.map(arg => arg.replace(/^["'](.*)["']$/, '$1'));
|
|
|
|
| 400 |
|
| 401 |
let sites = {};
|
| 402 |
try { sites = JSON.parse(process.env.WP_SITES_JSON || "{}"); } catch(e){}
|
| 403 |
const siteKeys = Object.keys(sites);
|
| 404 |
+
const defaultSite = siteKeys.length > 0 ? siteKeys[0] : 'None';
|
| 405 |
+
|
| 406 |
+
if (cleanArgs.length < 7) {
|
| 407 |
+
const helpMsg = `⚠️ <b>Missing Parameters for /write</b>\n\n` +
|
| 408 |
+
`To architect an elite SEO article, I need instructions. Please use quotes for multi-word parameters.\n\n` +
|
| 409 |
+
`<b>Structure:</b>\n` +
|
| 410 |
+
`/write [SiteID] "[Topic]" [Size] "[POV]" "[Intent]" "[Tone]"\n\n` +
|
| 411 |
+
`<b>Available Site IDs:</b> ${siteKeys.join(', ') || 'Configure WP_SITES_JSON'}\n` +
|
| 412 |
+
`<b>Sizes:</b> short, medium, dense\n` +
|
| 413 |
+
`<b>POV:</b> "1st person singular", "1st person plural", "2nd person", "3rd person"\n\n` +
|
| 414 |
+
`<b>Example:</b>\n` +
|
| 415 |
+
`/write ${defaultSite} "Agentic Workflow" medium "1st person plural" "Educational" "Authoritative"`;
|
| 416 |
+
|
| 417 |
+
await apiCaller.sendTelegramMessage(chatId, helpMsg);
|
|
|
|
|
|
|
|
|
|
| 418 |
} else {
|
| 419 |
+
const targetSiteId = cleanArgs[1];
|
| 420 |
+
const topic = cleanArgs[2];
|
| 421 |
+
const size = cleanArgs[3].toLowerCase();
|
| 422 |
+
const pov = cleanArgs[4];
|
| 423 |
+
const intent = cleanArgs[5];
|
| 424 |
+
const tone = cleanArgs[6];
|
| 425 |
+
|
| 426 |
+
if (!siteKeys.includes(targetSiteId)) {
|
| 427 |
+
await apiCaller.sendTelegramMessage(chatId, `❌ Unknown Site ID: ${targetSiteId}\nAvailable: ${siteKeys.join(', ')}`);
|
| 428 |
+
return;
|
| 429 |
+
}
|
| 430 |
+
|
| 431 |
+
await apiCaller.sendTelegramMessage(chatId, `📝 <b>SEO Engine:</b> Architecting 100% Unique [${size.toUpperCase()}] Article on "${topic}"...\n<b>Tone:</b> ${tone}\n<b>POV:</b> ${pov}`);
|
| 432 |
+
const articleRes = await seoWriter.generateArticle(size, pov, intent, tone, topic);
|
| 433 |
if (articleRes.success) {
|
| 434 |
await apiCaller.sendTelegramMessage(chatId, `✅ <b>Article Generated!</b> Scoring EEAT...`);
|
| 435 |
const scoreRes = await seoWriter.scoreEEAT(articleRes.html);
|
skills/seo_writer.js
CHANGED
|
@@ -9,7 +9,7 @@ class SeoWriter {
|
|
| 9 |
/**
|
| 10 |
* Generates a complete SEO article including Meta tags and JSON-LD schema.
|
| 11 |
*/
|
| 12 |
-
async generateArticle(size, topic) {
|
| 13 |
console.log(`[SEO Writer] Architecting ${size} article on: ${topic}`);
|
| 14 |
|
| 15 |
let words = "1500 - 2500";
|
|
@@ -23,6 +23,9 @@ Write a comprehensive, EEAT-compliant article about: "${topic}"
|
|
| 23 |
PARAMETERS:
|
| 24 |
- Length: ${words} words.
|
| 25 |
- Images: Minimum of ${minImages} images.
|
|
|
|
|
|
|
|
|
|
| 26 |
|
| 27 |
CRITICAL RULES:
|
| 28 |
1. STRICT HTML ONLY: You MUST format the output entirely in HTML. Use <strong>, <em>, <h2>, <h3>, <ul>, <p>. YOU ARE FORBIDDEN FROM USING MARKDOWN ASTERISKS (**bold**).
|
|
|
|
| 9 |
/**
|
| 10 |
* Generates a complete SEO article including Meta tags and JSON-LD schema.
|
| 11 |
*/
|
| 12 |
+
async generateArticle(size, pov, intent, tone, topic) {
|
| 13 |
console.log(`[SEO Writer] Architecting ${size} article on: ${topic}`);
|
| 14 |
|
| 15 |
let words = "1500 - 2500";
|
|
|
|
| 23 |
PARAMETERS:
|
| 24 |
- Length: ${words} words.
|
| 25 |
- Images: Minimum of ${minImages} images.
|
| 26 |
+
- Point of View (POV): ${pov}
|
| 27 |
+
- Search Intent: ${intent}
|
| 28 |
+
- Tone of Voice: ${tone}
|
| 29 |
|
| 30 |
CRITICAL RULES:
|
| 31 |
1. STRICT HTML ONLY: You MUST format the output entirely in HTML. Use <strong>, <em>, <h2>, <h3>, <ul>, <p>. YOU ARE FORBIDDEN FROM USING MARKDOWN ASTERISKS (**bold**).
|