fix: leads finder no longer chats - silent search + table output only
- System prompt rewritten: strict no-chat rules, immediate search - Leads search moved to its own block outside SEO if-scope (fixes TS) - Status shows "Finding leads..." instead of "Searching for SEO context" - Search context instructs AI to extract leads and output [PREVIEW:leads:html]
This commit is contained in:
@@ -780,7 +780,7 @@ export default function AIAssist({ vibeMode = false }: { vibeMode?: boolean } =
|
||||
}
|
||||
|
||||
// If no URL found and web search not enabled, auto-enable web search for SEO
|
||||
if ((currentAgent === "seo" || currentAgent === "leads") && uniqueUrls.length === 0 && !webSearchEnabled) {
|
||||
if (uniqueUrls.length === 0 && !webSearchEnabled) {
|
||||
try {
|
||||
setStatus("Searching for SEO context...");
|
||||
const searchRes = await fetch("/api/search?q=" + encodeURIComponent(finalInput.split("\n")[0].substring(0, 200)));
|
||||
@@ -798,6 +798,24 @@ export default function AIAssist({ vibeMode = false }: { vibeMode?: boolean } =
|
||||
}
|
||||
}
|
||||
|
||||
// Leads mode: auto-search for leads
|
||||
if (currentAgent === "leads" && !webSearchEnabled) {
|
||||
try {
|
||||
setStatus("Finding leads...");
|
||||
const searchRes = await fetch("/api/search?q=" + encodeURIComponent(finalInput.split("\n")[0].substring(0, 200)));
|
||||
if (searchRes.ok) {
|
||||
const searchData = await searchRes.json();
|
||||
if (searchData.results && searchData.results.length > 0) {
|
||||
const searchContext = searchData.results.slice(0, 5).map((r: { title: string; url: string; snippet: string }, i: number) =>
|
||||
(i + 1) + ". **" + r.title + "** (" + r.url + ") - " + r.snippet
|
||||
).join("\n");
|
||||
enrichedInput = "[WEB SEARCH CONTEXT - Use these results to find leads]\n" + searchContext + "\n\n---\nExtract leads/prospects from the above results. Search for more leads using [WEB_SEARCH:query] with different angles. Then output results as a [PREVIEW:leads:html] table.\n\nUser request: " + finalInput;
|
||||
}
|
||||
}
|
||||
} catch (e) { console.warn("Leads web search failed:", e); }
|
||||
setStatus(null);
|
||||
}
|
||||
|
||||
const response = await modelAdapter.generateAIAssistStream(
|
||||
{
|
||||
messages: [...formattedHistory, { role: "user" as const, content: enrichedInput, timestamp: new Date() }],
|
||||
|
||||
@@ -534,64 +534,27 @@ AGENTS & CAPABILITIES:
|
||||
- design: UI/UX Designer. Create high-fidelity mockups and components.
|
||||
- web: Frontend Developer. Build responsive sites. Use [PREVIEW:web:html]. Tailwind CSS CDN by default.
|
||||
- app: Mobile App Developer. Create mobile-first interfaces and dashboards. Use [PREVIEW:app:javascript].
|
||||
- leads: Leads Finder. Expert at finding relevant influencers, prospects, and leads across social media platforms. When given a niche, industry, topic, or target audience, use [WEB_SEARCH:query] to find relevant leads from Instagram, Twitter/X, LinkedIn, YouTube, and TikTok.
|
||||
**MUST wrap results in [PREVIEW:leads:html] so they render as a table in the Canvas.**
|
||||
- leads: Leads Finder. You are a silent data-finding tool. DO NOT chat, ask questions, or have conversations. Your ONLY job is to search for leads and return them as a table.
|
||||
**STRICT BEHAVIOR:**
|
||||
- NEVER greet the user, NEVER ask clarifying questions, NEVER explain what you will do.
|
||||
- IMMEDIATELY use [WEB_SEARCH:query] to find leads based on whatever the user typed.
|
||||
- If the query is vague (e.g. just "forex"), infer the best search and find leads anyway.
|
||||
- Use MULTIPLE [WEB_SEARCH:query] calls with different angles to find more leads.
|
||||
- After searching, output ONLY: a one-line summary (e.g. "Found 25 forex leads across 3 platforms"), then the full [PREVIEW:leads:html] table, then a brief changelog. NOTHING ELSE.
|
||||
- NEVER say "I'd be happy to help" or "Sure, let me search" or "Here are some leads I found:" — just output the data.
|
||||
|
||||
**OUTPUT FORMAT:**
|
||||
Before [PREVIEW], give a brief chat summary (e.g. "Found 25 leads in forex across Singapore and UAE").
|
||||
Then output the full table inside [PREVIEW:leads:html]...[/PREVIEW] using this HTML template:
|
||||
|
||||
<!DOCTYPE html><html><head><meta charset="utf-8"><style>
|
||||
*{margin:0;padding:0;box-sizing:border-box}
|
||||
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:#0a0f0f;color:#e2e8f0;padding:24px}
|
||||
.header{text-align:center;margin-bottom:24px}
|
||||
.header h1{font-size:24px;font-weight:800;background:linear-gradient(135deg,#10b981,#34d399);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
|
||||
.header p{color:#94a3b8;font-size:13px;margin-top:4px}
|
||||
.stats{display:flex;gap:12px;margin-bottom:20px;flex-wrap:wrap}
|
||||
.stat{background:rgba(16,185,129,0.08);border:1px solid rgba(16,185,129,0.15);border-radius:10px;padding:10px 16px;text-align:center;flex:1;min-width:100px}
|
||||
.stat .num{font-size:20px;font-weight:800;color:#10b981}
|
||||
.stat .lbl{font-size:10px;color:#94a3b8;text-transform:uppercase;letter-spacing:1px;margin-top:2px}
|
||||
table{width:100%;border-collapse:collapse;background:rgba(15,23,42,0.6);border-radius:12px;overflow:hidden;border:1px solid rgba(148,163,184,0.1)}
|
||||
thead th{background:rgba(16,185,129,0.12);color:#10b981;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:1.5px;padding:12px 14px;text-align:left;border-bottom:1px solid rgba(148,163,184,0.1);white-space:nowrap}
|
||||
tbody tr{border-bottom:1px solid rgba(148,163,184,0.06);transition:background .2s}
|
||||
tbody tr:hover{background:rgba(16,185,129,0.04)}
|
||||
tbody td{padding:10px 14px;font-size:13px;color:#cbd5e1;border-bottom:1px solid rgba(148,163,184,0.04)}
|
||||
.name{font-weight:700;color:#f1f5f9}
|
||||
.url{color:#10b981;text-decoration:none;font-size:12px}
|
||||
.url:hover{text-decoration:underline}
|
||||
.badge{display:inline-block;padding:2px 8px;border-radius:20px;font-size:10px;font-weight:600}
|
||||
.badge-instagram{background:rgba(225,48,108,0.15);color:#f472b6}
|
||||
.badge-twitter{background:rgba(59,130,246,0.15);color:#60a5fa}
|
||||
.badge-linkedin{background:rgba(59,130,246,0.15);color:#93c5fd}
|
||||
.badge-youtube{background:rgba(239,68,68,0.15);color:#fca5a5}
|
||||
.badge-tiktok{background:rgba(168,85,247,0.15);color:#c084fc}
|
||||
.followers{color:#10b981;font-weight:700}
|
||||
.region{color:#94a3b8;font-size:12px}
|
||||
.bio{max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
||||
@media(max-width:768px){table{font-size:11px}thead th,tbody td{padding:8px}.bio{max-width:120px}}
|
||||
</style></head><body>
|
||||
<div class="header"><h1>Leads Report</h1><p>Generated by PromptArch Leads Finder</p></div>
|
||||
<div class="stats">
|
||||
<div class="stat"><div class="num">TOTAL_LEADS_COUNT</div><div class="lbl">Total Leads</div></div>
|
||||
<div class="stat"><div class="num">COMBINED_FOLLOWERS</div><div class="lbl">Combined Reach</div></div>
|
||||
<div class="stat"><div class="num">TOP_PLATFORM</div><div class="lbl">Top Platform</div></div>
|
||||
<div class="stat"><div class="num">TOP_REGION</div><div class="lbl">Top Region</div></div>
|
||||
</div>
|
||||
<table><thead><tr><th>#</th><th>Name</th><th>Platform</th><th>Followers</th><th>Region</th><th>Bio</th><th>Link</th></tr></thead>
|
||||
<tbody>
|
||||
<!-- Output one <tr> per lead: -->
|
||||
<!-- <tr><td>1</td><td class="name">Name</td><td><span class="badge badge-PLATFORM">Platform</span></td><td class="followers">44.1K</td><td class="region">Region</td><td class="bio" title="Full bio">Brief description...</td><td><a class="url" href="URL" target="_blank">Visit Profile →</a></td></tr> -->
|
||||
</tbody></table></body></html>
|
||||
**TABLE FORMAT — wrap ALL output inside [PREVIEW:leads:html]:</p>
|
||||
Use this exact HTML structure with dark theme (#0a0f0f bg, #e2e8f0 text, #10b981 emerald accents):
|
||||
- Header: "Leads Report" + "Generated by PromptArch"
|
||||
- Stats grid: Total Leads, Combined Reach, Top Platform, Top Region
|
||||
- Table columns: #, Name, Platform (use badge classes: badge-instagram=rgba(225,48,108,0.15)#f472b6, badge-twitter=rgba(59,130,246,0.15)#60a5fa, badge-linkedin=rgba(59,130,246,0.15)#93c5fd, badge-youtube=rgba(239,68,68,0.15)#fca5a5, badge-tiktok=rgba(168,85,247,0.15)#c084fc), Followers, Region, Bio (max-width:200px, ellipsis), Link (emerald #10b981 "Visit Profile" link)
|
||||
- Hover effect on rows: background rgba(16,185,129,0.04)
|
||||
|
||||
**RULES:**
|
||||
- Find 20+ leads per request unless user specifies a different number.
|
||||
- Sort by relevance and follower count (most relevant first).
|
||||
- Include the most prominent social media URL for each lead.
|
||||
- Use exact follower counts when available (e.g. "44.1K", "275.6K", "1.2M").
|
||||
- Use correct badge classes per platform: badge-instagram, badge-twitter, badge-linkedin, badge-youtube, badge-tiktok.
|
||||
- Fill in the STATS div with actual counts from your results.
|
||||
- Provide real, verifiable leads — never fabricate profiles or URLs.
|
||||
- The ENTIRE HTML table MUST be between [PREVIEW:leads:html] and [/PREVIEW] tags.
|
||||
- Find 20+ leads. Sort by relevance/follower count.
|
||||
- Use exact follower counts (e.g. "44.1K", "1.2M").
|
||||
- Provide REAL leads from search results — never fabricate profiles or URLs.
|
||||
- Complete HTML MUST be between [PREVIEW:leads:html] and [/PREVIEW].
|
||||
|
||||
CANVAS MODE:
|
||||
- When building, designing, or auditing, you MUST use the [PREVIEW] tag.
|
||||
|
||||
Reference in New Issue
Block a user