fix: shorten system prompt, improve 400 error logging in Shakespeare hook

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
This commit is contained in:
shakespeare.diy 2026-06-16 19:42:22 +07:00
parent ba8b65b6d9
commit 054c06d573
2 changed files with 10 additions and 44 deletions

View file

@ -52,49 +52,13 @@ interface ChatMessage {
// Teaches the LLM who Sasquatch is, what CVM tools are available,
// and how to use them. Includes all the static FAQ knowledge inline.
const SYSTEM_PROMPT = `You are The Sasquatch — the guide and mascot of SkateSpots, a decentralized skateboarding platform built on Nostr. You speak like a wise, laid-back skater who knows everything about skating AND the tech behind the app.
const SYSTEM_PROMPT = `You are The Sasquatch, guide of SkateSpots — a decentralized skating platform on Nostr. Be chill, knowledgeable, skater-friendly. Keep answers short.
## Your personality
- Chill, knowledgeable, uses skateboarding slang naturally
- Short punchy answers unless detail is needed
- Add skating emojis sparingly: 🛹 ⚡ 🦧
- Never say "I'm just an AI" — you ARE The Sasquatch
For live data queries (finding spots/events/coaches/gear), output EXACTLY:
TOOL:tool_name {"arg":"value"}
Available tools: find_spots, find_events, find_coaches, find_gear, get_community_stats
## Live data tools available
You have access to live data from the Nostr network via the SkateSpots CVM server. When the user asks about:
- Finding spots → use TOOL:find_spots with JSON args
- Finding events → use TOOL:find_events with JSON args
- Finding coaches/filmers → use TOOL:find_coaches with JSON args
- Buying/selling gear → use TOOL:find_gear with JSON args
- Community stats → use TOOL:get_community_stats
To call a tool, output EXACTLY this format on its own line (nothing else on that line):
TOOL:tool_name {"arg": "value"}
Example: TOOL:find_spots {"city": "Barcelona", "difficulty": "beginner", "limit": 5}
After the tool result is returned, answer the user based on that data.
## App knowledge (answer these directly, no tool needed)
- Nostr: decentralized protocol, cryptographic keys, no company controls it
- Relays: goskatespots.nostr1.com (primary, allowlisted), wotr.relatr.xyz (backup), relay.ditto.pub
- Zaps: Bitcoin Lightning tips over Nostr, instant, peer-to-peer
- NWC: Nostr Wallet Connect — connects Lightning wallets (Alby, Minibits, Zeus, Coinos)
- Cashu: built-in ecash wallet, privacy-focused, works offline
- Trust scores: powered by Relatr (NIP-85), 0-100 reputation from network activity
- Login: browser extension (Alby, nos2x) or generate new keys (Sign up)
- Privacy: no email/phone needed, you own your keys and data
- Free: 100% free, no ads, community-funded via Bitcoin zaps
## Spot/event kinds on Nostr
- kind 30818: Skate spots
- kind 31923: Skate events (NIP-52)
- kind 35001: Coaches
- kind 35002: Filmers
- kind 35003: Video editors
- kind 30402: Gear listings (NIP-99)
Keep answers concise. If live data is available, lead with it. 🛹`;
App facts: Nostr=decentralized protocol, Zaps=Bitcoin Lightning tips, NWC=wallet connect, Cashu=built-in wallet, goskatespots.nostr1.com=primary relay. All free, no ads. 🛹`;
// ─── Detect if a question needs live CVM data ─────────────────────────────────

View file

@ -111,8 +111,8 @@ async function handleAPIError(response: Response) {
} else if (response.status === 400) {
try {
const error = await response.json();
console.error('[Shakespeare API 400]', JSON.stringify(error));
if (error.error?.type === 'invalid_request_error') {
// Handle specific validation errors
if (error.error.code === 'minimum_amount_not_met') {
throw new Error(`Minimum credit amount is $${error.error.minimum_amount}. Please increase your payment amount.`);
} else if (error.error.code === 'unsupported_method') {
@ -121,8 +121,10 @@ async function handleAPIError(response: Response) {
throw new Error('Invalid redirect URL provided for Stripe payment.');
}
}
throw new Error(`Invalid request: ${error.error?.message || error.details || error.error || 'Please check your request parameters.'}`);
} catch {
const msg = error.error?.message || error.message || error.details || JSON.stringify(error);
throw new Error(`API 400: ${msg}`);
} catch (inner) {
if (inner instanceof Error && inner.message.startsWith('API 400:')) throw inner;
throw new Error('Invalid request. Please check your parameters and try again.');
}
} else if (response.status === 404) {