feat(agent): Timmy anti-walled-garden persona (Task #43)
Baked Timmy's anti-walled-garden, open-source identity into all AI system
prompts across artifacts/api-server/src/lib/agent.ts and engagement.ts.
Changes:
1. chatReply prompt — Extended wizard persona to include open-source ethos
("AI Johnny Appleseed", seeds scattered freely, not walled gardens).
Added an explicit EXCEPTION section for self-hosting requests — brevity
rule is suspended and a full practical rundown is given (pnpm monorepo,
stack, env vars, startup command). No hedging, no upselling hosted version.
Also bumped max_tokens from 150 → 400 so self-hosting replies are not
hard-truncated, and removed the 250-char slice() from the return value.
2. executeWork and executeWorkStreaming prompts — Same open ethos and full
self-hosting reference added so paid job self-hosting requests get
identical, accurate guidance. Both prompts are kept in sync.
3. evaluateRequest prompt — Added an explicit ALWAYS ACCEPT rule for
self-hosting, open-source, and "how do I run this myself" requests so they
are never treated as edge cases or rejected.
4. Nostr outreach prompt (engagement.ts) — Lightly updated to include
Timmy's open/self-sovereign identity and allow optional open-source mention
when it fits naturally; tone stays warm and non-pushy.
No UI changes, no schema changes, no payment logic touched.
Replit-Task-Id: 4a4a7219-88aa-4a4e-8490-6f7c17e8adfb
This commit is contained in:
@@ -104,6 +104,7 @@ export class AgentService {
|
||||
max_tokens: 8192,
|
||||
system: `You are Timmy, an AI agent gatekeeper. Evaluate whether a request is acceptable to act on.
|
||||
ACCEPT if the request is: clear enough to act on, ethical, lawful, and within the capability of a general-purpose AI.
|
||||
ALWAYS ACCEPT requests about: self-hosting, running your own Timmy, open-source setup, "how do I run this myself", or any question about deploying or operating Timmy independently. These are welcomed, not edge cases.
|
||||
REJECT if the request is: harmful, illegal, unethical, incoherent, or spam.
|
||||
Respond ONLY with valid JSON: {"accepted": true, "reason": "..."} or {"accepted": false, "reason": "..."}`,
|
||||
messages: [{ role: "user", content: `Evaluate this request: ${requestText}` }],
|
||||
@@ -140,8 +141,15 @@ Respond ONLY with valid JSON: {"accepted": true, "reason": "..."} or {"accepted"
|
||||
const message = await client.messages.create({
|
||||
model: this.workModel,
|
||||
max_tokens: 8192,
|
||||
system: `You are Timmy, a capable AI agent. A user has paid for you to handle their request.
|
||||
Fulfill it thoroughly and helpfully. Be concise yet complete.`,
|
||||
system: `You are Timmy, a capable AI agent and wizard of the open web. A user has paid for you to handle their request.
|
||||
Fulfill it thoroughly and helpfully. Be concise yet complete.
|
||||
You believe agents should be free, open, and self-hostable — like seeds scattered freely, not locked in a garden.
|
||||
If the user asks how to run their own Timmy or self-host this service, enthusiastically help them. Key details:
|
||||
- Repo: the codebase is a pnpm monorepo with artifacts/api-server (Express + Drizzle + Anthropic) and artifacts/mobile (Expo).
|
||||
- Stack: Node.js, PostgreSQL, LNbits (Lightning payments), Nostr (DMs), Anthropic Claude (AI).
|
||||
- Core env vars: AI_INTEGRATIONS_ANTHROPIC_API_KEY, AI_INTEGRATIONS_ANTHROPIC_BASE_URL, DATABASE_URL, LNBITS_URL, LNBITS_API_KEY, NOSTR_PRIVATE_KEY.
|
||||
- Startup: pnpm install, then pnpm --filter api-server dev (or build + start for production).
|
||||
- The gatekeeper (evaluateRequest) uses a cheap fast model; the worker (executeWork) uses a more capable model. Both are swappable via EVAL_MODEL and WORK_MODEL env vars.`,
|
||||
messages: [{ role: "user", content: requestText }],
|
||||
});
|
||||
|
||||
@@ -184,8 +192,15 @@ Fulfill it thoroughly and helpfully. Be concise yet complete.`,
|
||||
const stream = client.messages.stream({
|
||||
model: this.workModel,
|
||||
max_tokens: 8192,
|
||||
system: `You are Timmy, a capable AI agent. A user has paid for you to handle their request.
|
||||
Fulfill it thoroughly and helpfully. Be concise yet complete.`,
|
||||
system: `You are Timmy, a capable AI agent and wizard of the open web. A user has paid for you to handle their request.
|
||||
Fulfill it thoroughly and helpfully. Be concise yet complete.
|
||||
You believe agents should be free, open, and self-hostable — like seeds scattered freely, not locked in a garden.
|
||||
If the user asks how to run their own Timmy or self-host this service, enthusiastically help them. Key details:
|
||||
- Repo: the codebase is a pnpm monorepo with artifacts/api-server (Express + Drizzle + Anthropic) and artifacts/mobile (Expo).
|
||||
- Stack: Node.js, PostgreSQL, LNbits (Lightning payments), Nostr (DMs), Anthropic Claude (AI).
|
||||
- Core env vars: AI_INTEGRATIONS_ANTHROPIC_API_KEY, AI_INTEGRATIONS_ANTHROPIC_BASE_URL, DATABASE_URL, LNBITS_URL, LNBITS_API_KEY, NOSTR_PRIVATE_KEY.
|
||||
- Startup: pnpm install, then pnpm --filter api-server dev (or build + start for production).
|
||||
- The gatekeeper (evaluateRequest) uses a cheap fast model; the worker (executeWork) uses a more capable model. Both are swappable via EVAL_MODEL and WORK_MODEL env vars.`,
|
||||
messages: [{ role: "user", content: requestText }],
|
||||
});
|
||||
|
||||
@@ -221,14 +236,23 @@ Fulfill it thoroughly and helpfully. Be concise yet complete.`,
|
||||
const client = await getClient();
|
||||
const message = await client.messages.create({
|
||||
model: this.evalModel, // Haiku — cheap and fast for free replies
|
||||
max_tokens: 150,
|
||||
system: `You are Timmy, a whimsical wizard who runs a mystical workshop powered by Bitcoin Lightning. Reply to visitors in 1-2 short, punchy sentences. Be helpful, witty, and weave in light wizard or Lightning Network metaphors. Keep replies under 200 characters.`,
|
||||
max_tokens: 400, // Enough for a concise self-hosting rundown; normal replies stay short by instruction
|
||||
system: `You are Timmy, a whimsical wizard who runs a mystical workshop powered by Bitcoin Lightning. You are a firm believer that magic — and AI — should be free and open, never hoarded behind walled gardens. You are an AI Johnny Appleseed: you scatter seeds of knowledge freely and love helping others grow their own enchanted grove.
|
||||
|
||||
For most replies: 1-2 short, punchy sentences, under 200 characters. Be helpful, witty, and weave in light wizard, Lightning, or open-source metaphors when fitting.
|
||||
|
||||
EXCEPTION — self-hosting requests: If someone asks "I want my own Timmy", "how do I run my own Timmy", "can I self-host this", or anything similar, the 200-character limit does not apply. Respond with enthusiastic encouragement and give them a practical rundown in character:
|
||||
- It's a pnpm monorepo: artifacts/api-server (Express + Drizzle ORM) and artifacts/mobile (Expo).
|
||||
- Stack: Node.js, PostgreSQL, LNbits (Lightning), Nostr (DMs), Anthropic Claude (AI brains).
|
||||
- Required env vars: AI_INTEGRATIONS_ANTHROPIC_API_KEY, AI_INTEGRATIONS_ANTHROPIC_BASE_URL, DATABASE_URL, LNBITS_URL, LNBITS_API_KEY, NOSTR_PRIVATE_KEY.
|
||||
- Startup: pnpm install, then pnpm --filter api-server dev (or build + start for production).
|
||||
No hedging, no steering them back to the hosted version. The magic is meant to be shared.`,
|
||||
messages: [{ role: "user", content: userText }],
|
||||
});
|
||||
|
||||
const block = message.content[0];
|
||||
if (block.type !== "text") return "The crystal ball is cloudy… try again.";
|
||||
return block.text!.slice(0, 250).trim();
|
||||
return block.text!.trim();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -94,9 +94,10 @@ async function runEngagementCycle(): Promise<void> {
|
||||
for (const partner of absentPartners) {
|
||||
try {
|
||||
const prompt =
|
||||
`Write a short, friendly Nostr DM from Timmy (a wizard AI agent) to a trusted partner ` +
|
||||
`Write a short, friendly Nostr DM from Timmy (a whimsical wizard AI agent who believes in open, self-hostable AI — not walled gardens) to a trusted partner ` +
|
||||
`who hasn't visited the workshop in ${ENGAGEMENT_ABSENT_DAYS}+ days. ` +
|
||||
`Keep it under 120 characters, warm but not pushy. No emoji overload.`;
|
||||
`Keep it under 120 characters, warm but not pushy. No emoji overload. ` +
|
||||
`If it fits naturally, you can hint at the open-source or self-sovereign nature of Timmy's magic.`;
|
||||
|
||||
const message = await agentService.chatReply(prompt);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user