@harbinger-ai/harbinger 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +406 -0
- package/agents/README.md +76 -0
- package/agents/_template/CONFIG.yaml +7 -0
- package/agents/_template/HEARTBEAT.md +59 -0
- package/agents/_template/IDENTITY.md +4 -0
- package/agents/_template/SKILLS.md +1 -0
- package/agents/_template/SOUL.md +25 -0
- package/agents/_template/TOOLS.md +3 -0
- package/agents/binary-reverser/CONFIG.yaml +21 -0
- package/agents/binary-reverser/HEARTBEAT.md +65 -0
- package/agents/binary-reverser/IDENTITY.md +1 -0
- package/agents/binary-reverser/SKILLS.md +1 -0
- package/agents/binary-reverser/SOUL.md +23 -0
- package/agents/binary-reverser/TOOLS.md +99 -0
- package/agents/browser-agent/CONFIG.yaml +20 -0
- package/agents/browser-agent/HEARTBEAT.md +79 -0
- package/agents/browser-agent/IDENTITY.md +5 -0
- package/agents/browser-agent/SKILLS.md +86 -0
- package/agents/browser-agent/SOUL.md +23 -0
- package/agents/browser-agent/TOOLS.md +186 -0
- package/agents/cloud-infiltrator/CONFIG.yaml +22 -0
- package/agents/cloud-infiltrator/HEARTBEAT.md +78 -0
- package/agents/cloud-infiltrator/IDENTITY.md +1 -0
- package/agents/cloud-infiltrator/SKILLS.md +1 -0
- package/agents/cloud-infiltrator/SOUL.md +23 -0
- package/agents/cloud-infiltrator/TOOLS.md +68 -0
- package/agents/coding-assistant/CONFIG.yaml +22 -0
- package/agents/coding-assistant/HEARTBEAT.md +57 -0
- package/agents/coding-assistant/IDENTITY.md +5 -0
- package/agents/coding-assistant/SKILLS.md +69 -0
- package/agents/coding-assistant/SOUL.md +60 -0
- package/agents/coding-assistant/TOOLS.md +168 -0
- package/agents/learning-agent/CONFIG.yaml +21 -0
- package/agents/learning-agent/HEARTBEAT.md +63 -0
- package/agents/learning-agent/IDENTITY.md +5 -0
- package/agents/learning-agent/SKILLS.md +86 -0
- package/agents/learning-agent/SOUL.md +77 -0
- package/agents/learning-agent/TOOLS.md +145 -0
- package/agents/maintainer/CONFIG.yaml +31 -0
- package/agents/maintainer/HEARTBEAT.md +28 -0
- package/agents/maintainer/IDENTITY.md +33 -0
- package/agents/maintainer/SKILLS.md +24 -0
- package/agents/maintainer/SOUL.md +61 -0
- package/agents/maintainer/TOOLS.md +29 -0
- package/agents/maintainer/lib/engine.js +279 -0
- package/agents/maintainer/lib/safe-fixer.js +183 -0
- package/agents/morning-brief/CONFIG.yaml +22 -0
- package/agents/morning-brief/HEARTBEAT.md +60 -0
- package/agents/morning-brief/IDENTITY.md +5 -0
- package/agents/morning-brief/SKILLS.md +56 -0
- package/agents/morning-brief/SOUL.md +64 -0
- package/agents/morning-brief/TOOLS.md +112 -0
- package/agents/osint-detective/CONFIG.yaml +24 -0
- package/agents/osint-detective/HEARTBEAT.md +66 -0
- package/agents/osint-detective/IDENTITY.md +1 -0
- package/agents/osint-detective/SKILLS.md +1 -0
- package/agents/osint-detective/SOUL.md +23 -0
- package/agents/osint-detective/TOOLS.md +81 -0
- package/agents/recon-scout/CONFIG.yaml +22 -0
- package/agents/recon-scout/HEARTBEAT.md +79 -0
- package/agents/recon-scout/IDENTITY.md +1 -0
- package/agents/recon-scout/SKILLS.md +1 -0
- package/agents/recon-scout/SOUL.md +23 -0
- package/agents/recon-scout/TOOLS.md +93 -0
- package/agents/report-writer/CONFIG.yaml +21 -0
- package/agents/report-writer/HEARTBEAT.md +63 -0
- package/agents/report-writer/IDENTITY.md +1 -0
- package/agents/report-writer/SKILLS.md +1 -0
- package/agents/report-writer/SOUL.md +23 -0
- package/agents/report-writer/TOOLS.md +69 -0
- package/agents/shared/README.md +13 -0
- package/agents/web-hacker/CONFIG.yaml +24 -0
- package/agents/web-hacker/HEARTBEAT.md +78 -0
- package/agents/web-hacker/IDENTITY.md +1 -0
- package/agents/web-hacker/SKILLS.md +1 -0
- package/agents/web-hacker/SOUL.md +23 -0
- package/agents/web-hacker/TOOLS.md +86 -0
- package/api/CLAUDE.md +19 -0
- package/api/index.js +274 -0
- package/bin/cli.js +620 -0
- package/bin/local.sh +31 -0
- package/bin/postinstall.js +63 -0
- package/config/index.js +24 -0
- package/config/instrumentation.js +93 -0
- package/drizzle/0000_initial.sql +52 -0
- package/drizzle/0001_bounty_and_registry.sql +82 -0
- package/drizzle/0002_sync_columns.sql +7 -0
- package/drizzle/0003_graceful_bloodscream.sql +86 -0
- package/drizzle/meta/0000_snapshot.json +321 -0
- package/drizzle/meta/0003_snapshot.json +878 -0
- package/drizzle/meta/_journal.json +34 -0
- package/drizzle/relations.ts +3 -0
- package/drizzle/schema.ts +145 -0
- package/lib/actions.js +47 -0
- package/lib/agents.js +166 -0
- package/lib/ai/agent.js +96 -0
- package/lib/ai/autonomous-engine.js +261 -0
- package/lib/ai/index.js +359 -0
- package/lib/ai/model-router.js +254 -0
- package/lib/ai/model.js +73 -0
- package/lib/ai/tools.js +84 -0
- package/lib/auth/actions.js +28 -0
- package/lib/auth/config.js +27 -0
- package/lib/auth/edge-config.js +27 -0
- package/lib/auth/index.js +27 -0
- package/lib/auth/middleware.js +53 -0
- package/lib/bounty/actions.js +119 -0
- package/lib/bounty/findings.js +64 -0
- package/lib/bounty/programs.js +34 -0
- package/lib/bounty/sync-targets.js +267 -0
- package/lib/bounty/targets.js +33 -0
- package/lib/channels/base.js +56 -0
- package/lib/channels/index.js +15 -0
- package/lib/channels/telegram.js +148 -0
- package/lib/chat/actions.js +288 -0
- package/lib/chat/api.js +135 -0
- package/lib/chat/components/app-sidebar.js +237 -0
- package/lib/chat/components/app-sidebar.jsx +289 -0
- package/lib/chat/components/chat-header.js +27 -0
- package/lib/chat/components/chat-header.jsx +37 -0
- package/lib/chat/components/chat-input.js +230 -0
- package/lib/chat/components/chat-input.jsx +228 -0
- package/lib/chat/components/chat-nav-context.js +11 -0
- package/lib/chat/components/chat-nav-context.jsx +11 -0
- package/lib/chat/components/chat-page.js +81 -0
- package/lib/chat/components/chat-page.jsx +100 -0
- package/lib/chat/components/chat.js +150 -0
- package/lib/chat/components/chat.jsx +182 -0
- package/lib/chat/components/chats-page.js +302 -0
- package/lib/chat/components/chats-page.jsx +330 -0
- package/lib/chat/components/crons-page.js +172 -0
- package/lib/chat/components/crons-page.jsx +244 -0
- package/lib/chat/components/enhanced-tool-call.js +103 -0
- package/lib/chat/components/enhanced-tool-call.jsx +139 -0
- package/lib/chat/components/findings-page.js +175 -0
- package/lib/chat/components/findings-page.jsx +214 -0
- package/lib/chat/components/greeting.js +22 -0
- package/lib/chat/components/greeting.jsx +26 -0
- package/lib/chat/components/icons.js +777 -0
- package/lib/chat/components/icons.jsx +741 -0
- package/lib/chat/components/index.js +26 -0
- package/lib/chat/components/mcp-page.js +260 -0
- package/lib/chat/components/mcp-page.jsx +355 -0
- package/lib/chat/components/message.js +289 -0
- package/lib/chat/components/message.jsx +315 -0
- package/lib/chat/components/messages.js +66 -0
- package/lib/chat/components/messages.jsx +77 -0
- package/lib/chat/components/notifications-page.js +56 -0
- package/lib/chat/components/notifications-page.jsx +87 -0
- package/lib/chat/components/page-layout.js +21 -0
- package/lib/chat/components/page-layout.jsx +28 -0
- package/lib/chat/components/registry-page.js +222 -0
- package/lib/chat/components/registry-page.jsx +255 -0
- package/lib/chat/components/settings-layout.js +40 -0
- package/lib/chat/components/settings-layout.jsx +54 -0
- package/lib/chat/components/settings-secrets-page.js +216 -0
- package/lib/chat/components/settings-secrets-page.jsx +264 -0
- package/lib/chat/components/sidebar-history-item.js +132 -0
- package/lib/chat/components/sidebar-history-item.jsx +113 -0
- package/lib/chat/components/sidebar-history.js +115 -0
- package/lib/chat/components/sidebar-history.jsx +157 -0
- package/lib/chat/components/sidebar-user-nav.js +63 -0
- package/lib/chat/components/sidebar-user-nav.jsx +73 -0
- package/lib/chat/components/status-bar.js +39 -0
- package/lib/chat/components/status-bar.jsx +51 -0
- package/lib/chat/components/swarm-page.js +157 -0
- package/lib/chat/components/swarm-page.jsx +210 -0
- package/lib/chat/components/targets-page.js +376 -0
- package/lib/chat/components/targets-page.jsx +389 -0
- package/lib/chat/components/tool-call.js +86 -0
- package/lib/chat/components/tool-call.jsx +104 -0
- package/lib/chat/components/tool-panel.js +107 -0
- package/lib/chat/components/tool-panel.jsx +145 -0
- package/lib/chat/components/triggers-page.js +153 -0
- package/lib/chat/components/triggers-page.jsx +221 -0
- package/lib/chat/components/ui/confirm-dialog.js +53 -0
- package/lib/chat/components/ui/confirm-dialog.jsx +57 -0
- package/lib/chat/components/ui/dropdown-menu.js +98 -0
- package/lib/chat/components/ui/dropdown-menu.jsx +116 -0
- package/lib/chat/components/ui/rename-dialog.js +74 -0
- package/lib/chat/components/ui/rename-dialog.jsx +72 -0
- package/lib/chat/components/ui/scroll-area.js +13 -0
- package/lib/chat/components/ui/scroll-area.jsx +17 -0
- package/lib/chat/components/ui/separator.js +21 -0
- package/lib/chat/components/ui/separator.jsx +18 -0
- package/lib/chat/components/ui/sheet.js +75 -0
- package/lib/chat/components/ui/sheet.jsx +95 -0
- package/lib/chat/components/ui/sidebar.js +227 -0
- package/lib/chat/components/ui/sidebar.jsx +245 -0
- package/lib/chat/components/ui/tooltip.js +56 -0
- package/lib/chat/components/ui/tooltip.jsx +66 -0
- package/lib/chat/components/upgrade-dialog.js +151 -0
- package/lib/chat/components/upgrade-dialog.jsx +170 -0
- package/lib/chat/utils.js +11 -0
- package/lib/cron.js +246 -0
- package/lib/db/api-keys.js +163 -0
- package/lib/db/chats.js +145 -0
- package/lib/db/index.js +52 -0
- package/lib/db/notifications.js +99 -0
- package/lib/db/schema.js +145 -0
- package/lib/db/update-check.js +96 -0
- package/lib/db/users.js +89 -0
- package/lib/mcp/actions.js +104 -0
- package/lib/mcp/client.js +79 -0
- package/lib/mcp/handler.js +57 -0
- package/lib/mcp/server.js +165 -0
- package/lib/paths.js +46 -0
- package/lib/registry/actions.js +164 -0
- package/lib/registry/catalog.js +137 -0
- package/lib/registry/tools.js +71 -0
- package/lib/tools/create-job.js +99 -0
- package/lib/tools/github.js +217 -0
- package/lib/tools/openai.js +35 -0
- package/lib/tools/telegram.js +292 -0
- package/lib/triggers.js +118 -0
- package/lib/utils/render-md.js +102 -0
- package/package.json +103 -0
- package/setup/lib/auth.mjs +81 -0
- package/setup/lib/env.mjs +21 -0
- package/setup/lib/fs-utils.mjs +20 -0
- package/setup/lib/github.mjs +149 -0
- package/setup/lib/prerequisites.mjs +155 -0
- package/setup/lib/prompts.mjs +267 -0
- package/setup/lib/providers.mjs +48 -0
- package/setup/lib/sync.mjs +125 -0
- package/setup/lib/targets.mjs +45 -0
- package/setup/lib/telegram-verify.mjs +63 -0
- package/setup/lib/telegram.mjs +76 -0
- package/setup/setup-telegram.mjs +264 -0
- package/setup/setup.mjs +842 -0
- package/templates/.dockerignore +5 -0
- package/templates/.env.example +63 -0
- package/templates/.github/workflows/auto-merge.yml +117 -0
- package/templates/.github/workflows/build-image.yml +36 -0
- package/templates/.github/workflows/notify-job-failed.yml +64 -0
- package/templates/.github/workflows/notify-pr-complete.yml +119 -0
- package/templates/.github/workflows/rebuild-event-handler.yml +121 -0
- package/templates/.github/workflows/run-job.yml +89 -0
- package/templates/.github/workflows/upgrade-event-handler.yml +62 -0
- package/templates/.gitignore.template +45 -0
- package/templates/.pi/extensions/env-sanitizer/index.ts +48 -0
- package/templates/.pi/extensions/env-sanitizer/package.json +5 -0
- package/templates/CLAUDE.md +29 -0
- package/templates/CLAUDE.md.template +307 -0
- package/templates/app/api/[...thepopebot]/route.js +1 -0
- package/templates/app/api/auth/[...nextauth]/route.js +1 -0
- package/templates/app/chat/[chatId]/page.js +8 -0
- package/templates/app/chats/page.js +7 -0
- package/templates/app/components/ascii-logo.jsx +10 -0
- package/templates/app/components/login-form.jsx +92 -0
- package/templates/app/components/setup-form.jsx +82 -0
- package/templates/app/components/theme-provider.jsx +11 -0
- package/templates/app/components/theme-toggle.jsx +38 -0
- package/templates/app/components/ui/button.jsx +21 -0
- package/templates/app/components/ui/card.jsx +23 -0
- package/templates/app/components/ui/input.jsx +10 -0
- package/templates/app/components/ui/label.jsx +10 -0
- package/templates/app/crons/page.js +5 -0
- package/templates/app/findings/page.js +7 -0
- package/templates/app/globals.css +90 -0
- package/templates/app/layout.js +19 -0
- package/templates/app/login/page.js +15 -0
- package/templates/app/notifications/page.js +7 -0
- package/templates/app/page.js +7 -0
- package/templates/app/settings/crons/page.js +5 -0
- package/templates/app/settings/layout.js +7 -0
- package/templates/app/settings/mcp/page.js +5 -0
- package/templates/app/settings/page.js +5 -0
- package/templates/app/settings/secrets/page.js +5 -0
- package/templates/app/settings/triggers/page.js +5 -0
- package/templates/app/stream/chat/route.js +1 -0
- package/templates/app/swarm/page.js +7 -0
- package/templates/app/targets/page.js +7 -0
- package/templates/app/toolbox/page.js +7 -0
- package/templates/app/triggers/page.js +5 -0
- package/templates/config/AGENT.md +34 -0
- package/templates/config/CRONS.json +56 -0
- package/templates/config/EVENT_HANDLER.md +224 -0
- package/templates/config/HEARTBEAT.md +3 -0
- package/templates/config/JOB_SUMMARY.md +130 -0
- package/templates/config/MCP_SERVERS.json +1 -0
- package/templates/config/SKILL_BUILDING_GUIDE.md +90 -0
- package/templates/config/SOUL.md +17 -0
- package/templates/config/TRIGGERS.json +58 -0
- package/templates/docker/event-handler/Dockerfile +20 -0
- package/templates/docker/event-handler/ecosystem.config.cjs +8 -0
- package/templates/docker/job-claude-code/Dockerfile +34 -0
- package/templates/docker/job-claude-code/entrypoint.sh +139 -0
- package/templates/docker/job-pi-coding-agent/Dockerfile +44 -0
- package/templates/docker/job-pi-coding-agent/entrypoint.sh +163 -0
- package/templates/docker-compose.yml +63 -0
- package/templates/instrumentation.js +6 -0
- package/templates/middleware.js +1 -0
- package/templates/next.config.mjs +3 -0
- package/templates/postcss.config.mjs +5 -0
- package/templates/skills/LICENSE +21 -0
- package/templates/skills/README.md +119 -0
- package/templates/skills/brave-search/SKILL.md +79 -0
- package/templates/skills/brave-search/content.js +86 -0
- package/templates/skills/brave-search/package-lock.json +621 -0
- package/templates/skills/brave-search/package.json +14 -0
- package/templates/skills/brave-search/search.js +199 -0
- package/templates/skills/browser-tools/SKILL.md +196 -0
- package/templates/skills/browser-tools/browser-content.js +103 -0
- package/templates/skills/browser-tools/browser-cookies.js +35 -0
- package/templates/skills/browser-tools/browser-eval.js +53 -0
- package/templates/skills/browser-tools/browser-hn-scraper.js +108 -0
- package/templates/skills/browser-tools/browser-nav.js +44 -0
- package/templates/skills/browser-tools/browser-pick.js +162 -0
- package/templates/skills/browser-tools/browser-screenshot.js +34 -0
- package/templates/skills/browser-tools/browser-start.js +87 -0
- package/templates/skills/browser-tools/package-lock.json +2556 -0
- package/templates/skills/browser-tools/package.json +19 -0
- package/templates/skills/llm-secrets/SKILL.md +34 -0
- package/templates/skills/llm-secrets/llm-secrets.js +33 -0
- package/templates/skills/modify-self/SKILL.md +12 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useTheme } from 'next-themes';
|
|
4
|
+
import { useEffect, useState } from 'react';
|
|
5
|
+
|
|
6
|
+
export function ThemeToggle() {
|
|
7
|
+
const { theme, setTheme } = useTheme();
|
|
8
|
+
const [mounted, setMounted] = useState(false);
|
|
9
|
+
|
|
10
|
+
useEffect(() => setMounted(true), []);
|
|
11
|
+
|
|
12
|
+
if (!mounted) return <div className="h-[34px] w-[106px]" />;
|
|
13
|
+
|
|
14
|
+
const options = [
|
|
15
|
+
{ value: 'light', label: '☀️' },
|
|
16
|
+
{ value: 'dark', label: '🌙' },
|
|
17
|
+
{ value: 'system', label: '💻' },
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<div className="flex items-center gap-1 rounded-md border border-border bg-muted p-1">
|
|
22
|
+
{options.map((opt) => (
|
|
23
|
+
<button
|
|
24
|
+
key={opt.value}
|
|
25
|
+
onClick={() => setTheme(opt.value)}
|
|
26
|
+
className={`rounded px-2 py-1 text-sm transition-colors ${
|
|
27
|
+
theme === opt.value
|
|
28
|
+
? 'bg-background text-foreground shadow-sm'
|
|
29
|
+
: 'text-muted-foreground hover:text-foreground'
|
|
30
|
+
}`}
|
|
31
|
+
title={opt.value.charAt(0).toUpperCase() + opt.value.slice(1)}
|
|
32
|
+
>
|
|
33
|
+
{opt.label}
|
|
34
|
+
</button>
|
|
35
|
+
))}
|
|
36
|
+
</div>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
export function Button({ children, variant = 'default', className = '', disabled, ...props }) {
|
|
4
|
+
const base = 'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 px-4 py-2';
|
|
5
|
+
|
|
6
|
+
const variants = {
|
|
7
|
+
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
|
|
8
|
+
outline: 'border border-border bg-transparent text-foreground hover:bg-muted',
|
|
9
|
+
ghost: 'text-foreground hover:bg-muted',
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<button
|
|
14
|
+
className={`${base} ${variants[variant] || variants.default} ${className}`}
|
|
15
|
+
disabled={disabled}
|
|
16
|
+
{...props}
|
|
17
|
+
>
|
|
18
|
+
{children}
|
|
19
|
+
</button>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function Card({ children, className = '' }) {
|
|
2
|
+
return (
|
|
3
|
+
<div className={`rounded-lg border border-border bg-muted p-6 ${className}`}>
|
|
4
|
+
{children}
|
|
5
|
+
</div>
|
|
6
|
+
);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function CardHeader({ children, className = '' }) {
|
|
10
|
+
return <div className={`mb-4 ${className}`}>{children}</div>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function CardTitle({ children, className = '' }) {
|
|
14
|
+
return <h2 className={`text-lg font-semibold text-foreground ${className}`}>{children}</h2>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function CardDescription({ children, className = '' }) {
|
|
18
|
+
return <p className={`text-sm text-muted-foreground ${className}`}>{children}</p>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function CardContent({ children, className = '' }) {
|
|
22
|
+
return <div className={className}>{children}</div>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
export function Input({ className = '', ...props }) {
|
|
4
|
+
return (
|
|
5
|
+
<input
|
|
6
|
+
className={`flex h-10 w-full rounded-md border border-border bg-input px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ${className}`}
|
|
7
|
+
{...props}
|
|
8
|
+
/>
|
|
9
|
+
);
|
|
10
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
@import "streamdown/styles.css";
|
|
3
|
+
@source "../node_modules/thepopebot/lib/**/*.{js,jsx}";
|
|
4
|
+
@source "../node_modules/streamdown/dist/**/*.js";
|
|
5
|
+
|
|
6
|
+
:root {
|
|
7
|
+
--background: #ffffff;
|
|
8
|
+
--foreground: #171717;
|
|
9
|
+
--primary: #171717;
|
|
10
|
+
--primary-foreground: #ffffff;
|
|
11
|
+
--muted: #f5f5f5;
|
|
12
|
+
--muted-foreground: #737373;
|
|
13
|
+
--border: #e5e5e5;
|
|
14
|
+
--input: #f5f5f5;
|
|
15
|
+
--ring: #171717;
|
|
16
|
+
--destructive: #dc2626;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.dark {
|
|
20
|
+
--background: #0a0a0a;
|
|
21
|
+
--foreground: #ededed;
|
|
22
|
+
--primary: #ededed;
|
|
23
|
+
--primary-foreground: #0a0a0a;
|
|
24
|
+
--muted: #171717;
|
|
25
|
+
--muted-foreground: #a3a3a3;
|
|
26
|
+
--border: #262626;
|
|
27
|
+
--input: #171717;
|
|
28
|
+
--ring: #ededed;
|
|
29
|
+
--destructive: #ef4444;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@theme inline {
|
|
33
|
+
--color-background: var(--background);
|
|
34
|
+
--color-foreground: var(--foreground);
|
|
35
|
+
--color-primary: var(--primary);
|
|
36
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
37
|
+
--color-muted: var(--muted);
|
|
38
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
39
|
+
--color-border: var(--border);
|
|
40
|
+
--color-input: var(--input);
|
|
41
|
+
--color-ring: var(--ring);
|
|
42
|
+
--color-destructive: var(--destructive);
|
|
43
|
+
--text-xs: 0.8125rem;
|
|
44
|
+
--text-xs--line-height: 1.125rem;
|
|
45
|
+
--text-sm: 1rem;
|
|
46
|
+
--text-sm--line-height: 1.5rem;
|
|
47
|
+
--font-sans: system-ui, -apple-system, sans-serif;
|
|
48
|
+
--font-mono: ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace;
|
|
49
|
+
--radius-sm: 0.375rem;
|
|
50
|
+
--radius-md: 0.5rem;
|
|
51
|
+
--radius-lg: 0.75rem;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* Scrollbar styling */
|
|
55
|
+
.scrollbar-thin {
|
|
56
|
+
scrollbar-width: thin;
|
|
57
|
+
scrollbar-color: var(--border) transparent;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.scrollbar-thin::-webkit-scrollbar {
|
|
61
|
+
width: 6px;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.scrollbar-thin::-webkit-scrollbar-track {
|
|
65
|
+
background: transparent;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.scrollbar-thin::-webkit-scrollbar-thumb {
|
|
69
|
+
background-color: var(--border);
|
|
70
|
+
border-radius: 3px;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* Code block horizontal scroll — target the pre (code-block-body), not the
|
|
74
|
+
outer wrapper which needs overflow-hidden for border-radius clipping */
|
|
75
|
+
[data-streamdown="code-block-body"] {
|
|
76
|
+
overflow-x: auto !important;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
[data-streamdown="code-block-body"]::-webkit-scrollbar {
|
|
80
|
+
height: 6px;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
[data-streamdown="code-block-body"]::-webkit-scrollbar-track {
|
|
84
|
+
background: transparent;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
[data-streamdown="code-block-body"]::-webkit-scrollbar-thumb {
|
|
88
|
+
background-color: var(--border);
|
|
89
|
+
border-radius: 3px;
|
|
90
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import './globals.css';
|
|
2
|
+
import { ThemeProvider } from './components/theme-provider';
|
|
3
|
+
|
|
4
|
+
export const metadata = {
|
|
5
|
+
title: 'thepopebot',
|
|
6
|
+
description: 'AI Agent',
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export default function RootLayout({ children }) {
|
|
10
|
+
return (
|
|
11
|
+
<html lang="en" suppressHydrationWarning>
|
|
12
|
+
<body className="min-h-screen bg-background text-foreground antialiased">
|
|
13
|
+
<ThemeProvider>
|
|
14
|
+
{children}
|
|
15
|
+
</ThemeProvider>
|
|
16
|
+
</body>
|
|
17
|
+
</html>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { getPageAuthState } from 'thepopebot/auth';
|
|
2
|
+
import { AsciiLogo } from '../components/ascii-logo';
|
|
3
|
+
import { SetupForm } from '../components/setup-form';
|
|
4
|
+
import { LoginForm } from '../components/login-form';
|
|
5
|
+
|
|
6
|
+
export default async function LoginPage() {
|
|
7
|
+
const { needsSetup } = await getPageAuthState();
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<main className="min-h-screen flex flex-col items-center justify-center p-8">
|
|
11
|
+
<AsciiLogo />
|
|
12
|
+
{needsSetup ? <SetupForm /> : <LoginForm />}
|
|
13
|
+
</main>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { POST } from 'thepopebot/chat/api';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# thepopebot Agent Environment
|
|
2
|
+
|
|
3
|
+
**This document describes what you are and your operating environment**
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. What You Are
|
|
8
|
+
|
|
9
|
+
You are **thepopebot**, an autonomous AI agent running inside a Docker container.
|
|
10
|
+
- You have full access to the machine and anything it can do to get the job done.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 2. Local Docker Environment Reference
|
|
15
|
+
|
|
16
|
+
This section tells you where things about your operating container enviornment.
|
|
17
|
+
|
|
18
|
+
### WORKDIR
|
|
19
|
+
|
|
20
|
+
Your working dir WORKDIR=`/job` — this is the root folder for the agent.
|
|
21
|
+
|
|
22
|
+
So you can assume that:
|
|
23
|
+
- /folder/file.ext is /job/folder/file.txt
|
|
24
|
+
- folder/file.ext is /job/folder/file.txt (missing /)
|
|
25
|
+
|
|
26
|
+
### Where Temporary Files Go `/job/tmp/`
|
|
27
|
+
|
|
28
|
+
**Important:** Temporary files are defined as files that you create (that are NOT part of the final job.md deliverables)
|
|
29
|
+
|
|
30
|
+
**Always** use `/job/tmp/` for any temporary files you create.
|
|
31
|
+
|
|
32
|
+
Scripts in `/job/tmp/` can use `__dirname`-relative paths (e.g., `../docs/data.json`) to reference repo files, because they're inside the repo tree. The `.gitignore` excludes `tmp/` so nothing in this directory gets committed.
|
|
33
|
+
|
|
34
|
+
Current datetime: {{datetime}}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"name": "heartbeat",
|
|
4
|
+
"schedule": "*/30 * * * *",
|
|
5
|
+
"type": "agent",
|
|
6
|
+
"job": "Read the file at config/HEARTBEAT.md and complete the tasks described there.",
|
|
7
|
+
"enabled": false
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"name": "daily-check",
|
|
11
|
+
"schedule": "0 9 * * *",
|
|
12
|
+
"type": "agent",
|
|
13
|
+
"job": "Check for dependency updates in package.json and report any outdated packages.",
|
|
14
|
+
"enabled": false
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"name": "ping",
|
|
18
|
+
"schedule": "*/1 * * * *",
|
|
19
|
+
"type": "command",
|
|
20
|
+
"command": "echo \"pong!\"",
|
|
21
|
+
"enabled": true
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"name": "cleanup-logs",
|
|
25
|
+
"schedule": "0 0 * * 0",
|
|
26
|
+
"type": "command",
|
|
27
|
+
"command": "ls -la logs/",
|
|
28
|
+
"enabled": false
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "ping-status",
|
|
32
|
+
"schedule": "*/5 * * * *",
|
|
33
|
+
"type": "webhook",
|
|
34
|
+
"url": "https://example.com/status",
|
|
35
|
+
"method": "POST",
|
|
36
|
+
"vars": { "source": "heartbeat" },
|
|
37
|
+
"enabled": false
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"name": "health-check",
|
|
41
|
+
"schedule": "*/10 * * * *",
|
|
42
|
+
"type": "webhook",
|
|
43
|
+
"url": "https://example.com/health",
|
|
44
|
+
"method": "GET",
|
|
45
|
+
"enabled": false
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "daily-check-openai",
|
|
49
|
+
"schedule": "0 9 * * *",
|
|
50
|
+
"type": "agent",
|
|
51
|
+
"job": "Check for dependency updates in package.json and report any outdated packages.",
|
|
52
|
+
"llm_provider": "openai",
|
|
53
|
+
"llm_model": "gpt-4o",
|
|
54
|
+
"enabled": false
|
|
55
|
+
}
|
|
56
|
+
]
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# Your Role
|
|
2
|
+
|
|
3
|
+
You are the conversational interface for this system. You help users accomplish tasks by planning and creating jobs that run autonomously.
|
|
4
|
+
|
|
5
|
+
**In conversation**, you can answer questions from your own knowledge, help plan and scope tasks, create and monitor jobs, and guide users through setup and configuration.
|
|
6
|
+
|
|
7
|
+
**Through jobs**, the system executes tasks autonomously in a Docker container. You describe what needs to happen, the Docker agent carries it out. From the user's perspective, frame this as a unified system. Say "I can set up a job to do that" rather than "I can't do that, only the Docker agent can."
|
|
8
|
+
|
|
9
|
+
You have four tools:
|
|
10
|
+
- **`create_job`** — dispatch a job for autonomous execution
|
|
11
|
+
- **`get_job_status`** — check on running or completed jobs
|
|
12
|
+
- **`get_system_technical_specs`** — read the system architecture docs (event handler, Docker agent, APIs, config, deployment). Use before planning jobs that modify system configuration.
|
|
13
|
+
- **`get_skill_building_guide`** — load the skill building guide (skill format, examples, activation, testing). Use when discussing or creating skills with the user.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## What Jobs Have Access To
|
|
18
|
+
|
|
19
|
+
Every job runs **Pi coding agent** — an autonomous LLM inside a Docker container with full root access. Pi is not a script runner. It's an AI that reasons through tasks step-by-step, uses tools, iterates on problems, and recovers from errors on its own. Your job descriptions become Pi's task prompt.
|
|
20
|
+
|
|
21
|
+
### Pi's built-in tools (always available)
|
|
22
|
+
|
|
23
|
+
- **read** / **write** / **edit** — full filesystem access to any file in the repo
|
|
24
|
+
- **bash** — run any shell command. Pi works primarily in bash.
|
|
25
|
+
- **ls** / **grep** / **find** — search and navigate the codebase
|
|
26
|
+
|
|
27
|
+
These 7 tools are all Pi needs to accomplish most tasks. It can write code, install packages, call APIs with curl, build software, modify configuration — anything you can do in a terminal.
|
|
28
|
+
|
|
29
|
+
### What Pi can do with these tools
|
|
30
|
+
|
|
31
|
+
- **Self-modification** — update config files in `config/` (CRONS.json, TRIGGERS.json, SOUL.md, EVENT_HANDLER.md, AGENT.md, etc.). Config files have advanced fields not listed here — always call `get_system_technical_specs` first to get the full schema before modifying them.
|
|
32
|
+
- **Create new skills** — build new tools in `skills/` and activate them with symlinks in `skills/active/`
|
|
33
|
+
- **Code changes** — add features, fix bugs, refactor, build entire applications
|
|
34
|
+
- **Git** — commits changes, creates PRs automatically
|
|
35
|
+
|
|
36
|
+
### Active skills
|
|
37
|
+
|
|
38
|
+
Skills are lightweight wrappers (usually bash scripts) that give the agent access to external services. The agent reads the skill documentation, then invokes them via bash.
|
|
39
|
+
|
|
40
|
+
{{skills}}
|
|
41
|
+
|
|
42
|
+
If no skill exists for what the user needs, the agent can build more.
|
|
43
|
+
|
|
44
|
+
### Writing good job descriptions
|
|
45
|
+
|
|
46
|
+
Your job descriptions are prompts for Pi — an AI that can reason and figure things out. Be clear about the goal and provide context, but you don't need to specify every step. Pi will figure out the approach.
|
|
47
|
+
|
|
48
|
+
Include:
|
|
49
|
+
- What the end result should look like
|
|
50
|
+
- Specific file paths when relevant
|
|
51
|
+
- Any constraints or preferences
|
|
52
|
+
|
|
53
|
+
Users won't always be technical — they'll say "go to this website", "search for X", "check my calendar." Map their natural language into clear task descriptions for Pi.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Conversational Guidance
|
|
58
|
+
|
|
59
|
+
**Bias toward action.** For clear or standard requests, propose a complete job description right away with reasonable defaults. State your assumptions — the user can adjust before approving. Don't interrogate them with a list of questions first.
|
|
60
|
+
|
|
61
|
+
- **Clear tasks** (create a skill, change a config, scrape a page): Propose immediately.
|
|
62
|
+
- **Ambiguous tasks**: Ask **one focused question** to resolve the core ambiguity, then propose.
|
|
63
|
+
- **"What can you do?"**: Lead with what the system can accomplish through jobs (code, files, skills, configuration, browser, APIs). Mention active skills. Don't lead with tool mechanics.
|
|
64
|
+
|
|
65
|
+
Most users prefer seeing a concrete proposal they can tweak over answering a series of questions.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Not Everything is a Job
|
|
70
|
+
|
|
71
|
+
Answer from your own knowledge when you can — general questions, planning discussions, brainstorming, and common knowledge don't need jobs.
|
|
72
|
+
|
|
73
|
+
Only create jobs for tasks that need the Docker agent's abilities (filesystem, browser, web search, code changes, etc.).
|
|
74
|
+
|
|
75
|
+
If someone asks something you can reasonably answer, just answer it directly. If they need current or real-time information you can't provide, be honest and offer to create a job for it.
|
|
76
|
+
|
|
77
|
+
The goal is to be a useful conversational partner first, and a job dispatcher second.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Job Description Best Practices
|
|
82
|
+
|
|
83
|
+
The job description text becomes Pi's task prompt:
|
|
84
|
+
|
|
85
|
+
- Be specific about what to do and where (file paths matter)
|
|
86
|
+
- Include enough context for autonomous execution
|
|
87
|
+
- Reference config files by actual paths (e.g., `config/CRONS.json`)
|
|
88
|
+
- For self-modification, describe what currently exists so Pi doesn't blindly overwrite
|
|
89
|
+
- One coherent task per job
|
|
90
|
+
- For detailed or complex tasks, suggest the user put instructions in a config markdown file and reference it by path
|
|
91
|
+
- When planning jobs that modify the system itself, use `get_system_technical_specs` to understand the architecture and file structure before writing the job description
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Skills
|
|
96
|
+
|
|
97
|
+
Skills extend what the agent can do — they're lightweight wrappers (usually bash scripts) that give the agent access to external services. If a user wants something no current skill covers, suggest creating one.
|
|
98
|
+
|
|
99
|
+
When discussing or creating skills, use `get_skill_building_guide` to load the skill building guide. This covers the skill format, examples, activation, testing, and credential setup.
|
|
100
|
+
|
|
101
|
+
### Credential setup (handle in conversation, before creating the job)
|
|
102
|
+
|
|
103
|
+
If a skill needs an API key:
|
|
104
|
+
|
|
105
|
+
1. **Tell the user** what credential is needed and where to get it
|
|
106
|
+
2. **Suggest setting it up now** so the skill can be tested in the same job:
|
|
107
|
+
- Run: `npx thepopebot set-agent-llm-secret <KEY_NAME> <value>`
|
|
108
|
+
- The value is stored exactly as provided, no transformation needed
|
|
109
|
+
- This creates a GitHub secret with the `AGENT_LLM_` prefix — the Docker container exposes it as an environment variable (e.g., `AGENT_LLM_BRAVE_API_KEY` → `BRAVE_API_KEY`)
|
|
110
|
+
- They can rotate the key later with the same command
|
|
111
|
+
- Sharing a key in chat is a minor security consideration but often fine for setup
|
|
112
|
+
3. **If they skip the key**, the skill gets built but untested — they'll set up the key later and test separately
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Job Creation Flow
|
|
117
|
+
|
|
118
|
+
**CRITICAL: NEVER call create_job without explicit user approval first.**
|
|
119
|
+
|
|
120
|
+
Follow these steps every time:
|
|
121
|
+
|
|
122
|
+
1. **Develop the job description.** For standard tasks, propose a complete description with reasonable defaults and state your assumptions. For genuinely ambiguous requests, ask one focused question, then propose.
|
|
123
|
+
2. **Present the COMPLETE job description to the user.** Show the full text you intend to pass to `create_job` so they can review it.
|
|
124
|
+
3. **Wait for explicit approval.** The user must confirm before you proceed (e.g., "approved", "yes", "go ahead", "do it", "lgtm").
|
|
125
|
+
4. **Only then call `create_job`** with the exact approved description. Do not modify it after approval without re-presenting and getting approval again.
|
|
126
|
+
|
|
127
|
+
This applies to every job — including simple or obvious tasks. Even if the user says "just do X", present the job description and wait for their go-ahead.
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Examples
|
|
132
|
+
|
|
133
|
+
**Config change (simple):**
|
|
134
|
+
|
|
135
|
+
> User: "Change my heartbeat cron to run every hour"
|
|
136
|
+
>
|
|
137
|
+
> You: Confirm what they want, then present the job description: "I'll create a job to update the heartbeat schedule in `config/CRONS.json` to hourly. Here's the job description: ..."
|
|
138
|
+
>
|
|
139
|
+
> User: "go ahead"
|
|
140
|
+
>
|
|
141
|
+
> → call `create_job`
|
|
142
|
+
|
|
143
|
+
**Config change (LLM override):**
|
|
144
|
+
|
|
145
|
+
> User: "Enable the heartbeat cron and set it to use Ollama with qwen3:8b"
|
|
146
|
+
>
|
|
147
|
+
> You: → call `get_system_technical_specs` to confirm the cron schema fields, then present the job description including `llm_provider` and `llm_model` fields.
|
|
148
|
+
>
|
|
149
|
+
> User: "approved"
|
|
150
|
+
>
|
|
151
|
+
> → call `create_job`
|
|
152
|
+
|
|
153
|
+
**Research task (medium):**
|
|
154
|
+
|
|
155
|
+
> User: "Can you find out what the best Node.js testing frameworks are?"
|
|
156
|
+
>
|
|
157
|
+
> You: Clarify — do they want a summary saved to a file, or just a quick overview? How detailed? Any specific criteria?
|
|
158
|
+
>
|
|
159
|
+
> User: "Save a report comparing the top 3"
|
|
160
|
+
>
|
|
161
|
+
> You: Present the job description — "Search the web for the top Node.js testing frameworks in 2026. Compare the top 3 by features, performance, community support, and ease of use. Save the comparison as a markdown report at `docs/testing-frameworks.md`."
|
|
162
|
+
>
|
|
163
|
+
> User: "approved"
|
|
164
|
+
>
|
|
165
|
+
> → call `create_job`
|
|
166
|
+
|
|
167
|
+
**New skill:**
|
|
168
|
+
|
|
169
|
+
> User: "I want to be able to post to Slack"
|
|
170
|
+
>
|
|
171
|
+
> You: "I can set up a Slack posting skill. It'll be a bash script that uses curl to call the Slack webhook API. You'll need a Slack webhook URL.
|
|
172
|
+
>
|
|
173
|
+
> If you set it up now, I can build AND test the skill in one job:
|
|
174
|
+
> ```
|
|
175
|
+
> npx thepopebot set-agent-llm-secret SLACK_WEBHOOK_URL <your-url>
|
|
176
|
+
> ```
|
|
177
|
+
> (You can rotate this later with the same command.)
|
|
178
|
+
>
|
|
179
|
+
> Or I can create the skill without testing and you set up the webhook later.
|
|
180
|
+
>
|
|
181
|
+
> Here's the job description: ..."
|
|
182
|
+
>
|
|
183
|
+
> User: "here's my webhook URL: xxx, go ahead"
|
|
184
|
+
>
|
|
185
|
+
> → guide them to run set-agent-llm-secret, then call `create_job`
|
|
186
|
+
|
|
187
|
+
These examples are just common patterns. The Docker agent has full root access to its container, unrestricted internet access, a browser, and all the abilities listed above. It can even code its own new abilities if one doesn't exist yet. If a computer can do it, the Docker agent can do it. When planning jobs with the user, dream big and think creatively — your job descriptions define what Pi will go and accomplish.
|
|
188
|
+
|
|
189
|
+
Think beyond the obvious. A user says "I want to track competitor pricing" — that's not just one job, that's a cron job that scrapes pricing pages daily and saves historical data. "I want a daily briefing" — that's a scheduled job that pulls news, checks calendars, summarizes open PRs, and sends the digest to Telegram. "I wish I could just upload a screenshot and get a landing page" — the Docker agent can see images, write code, and commit it. Someone mentions a repetitive task they do manually — suggest automating it with a cron or trigger. The Docker agent can build its own tools, connect to any API, and modify its own configuration. The only limit is what you can describe in a job.
|
|
190
|
+
|
|
191
|
+
### Example job descriptions
|
|
192
|
+
|
|
193
|
+
Config modification:
|
|
194
|
+
> Open `config/CRONS.json` and change the schedule for the "heartbeat" cron from `*/30 * * * *` to `0 * * * *` (hourly). Keep all other fields unchanged.
|
|
195
|
+
|
|
196
|
+
Config modification (enable + LLM override):
|
|
197
|
+
> Open `config/CRONS.json` and update the "heartbeat" entry: set `"enabled": true`, `"llm_provider": "custom"`, and `"llm_model": "qwen3:8b"`. Keep all other fields unchanged.
|
|
198
|
+
|
|
199
|
+
Browser scraping:
|
|
200
|
+
> Navigate to https://example.com/pricing, extract the plan names, prices, and feature lists from the pricing page. Save the data as JSON at `data/pricing.json`.
|
|
201
|
+
|
|
202
|
+
New skill creation:
|
|
203
|
+
> Create a new skill at `skills/slack-post/`:
|
|
204
|
+
>
|
|
205
|
+
> 1. Create `SKILL.md` with frontmatter (name: slack-post, description: "Post messages to Slack channels via incoming webhook.") and usage docs referencing `skills/slack-post/post.sh <message>`
|
|
206
|
+
> 2. Create `post.sh` — bash script that takes a message argument, sends it to the Slack webhook URL via curl using $SLACK_WEBHOOK_URL. Make it executable.
|
|
207
|
+
> 3. Activate: `ln -s ../slack-post skills/active/slack-post`
|
|
208
|
+
> 4. Test: run `skills/slack-post/post.sh "test message from thepopebot"` and verify successful delivery. Fix any issues before committing.
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Checking Job Status
|
|
213
|
+
|
|
214
|
+
Always use the `get_job_status` tool when asked about jobs — don't rely on chat memory. Explain status to the user in plain language.
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## Response Guidelines
|
|
219
|
+
|
|
220
|
+
- Keep responses concise and direct
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
Current datetime: {{datetime}}
|