thepopebot 1.1.2 → 1.2.3
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/README.md +1 -1
- package/api/index.js +72 -165
- package/bin/cli.js +36 -6
- package/bin/local.sh +31 -0
- package/bin/postinstall.js +6 -2
- package/config/index.js +2 -11
- package/config/instrumentation.js +17 -5
- package/lib/actions.js +7 -6
- package/lib/ai/agent.js +36 -0
- package/lib/ai/index.js +274 -0
- package/lib/ai/model.js +67 -0
- package/lib/ai/tools.js +49 -0
- package/lib/auth/actions.js +28 -0
- package/lib/auth/config.js +45 -0
- package/lib/auth/index.js +27 -0
- package/lib/auth/middleware.js +30 -0
- package/lib/channels/base.js +56 -0
- package/lib/channels/index.js +15 -0
- package/lib/channels/telegram.js +146 -0
- package/lib/chat/actions.js +239 -0
- package/lib/chat/api.js +103 -0
- package/lib/chat/components/app-sidebar.js +161 -0
- package/lib/chat/components/app-sidebar.jsx +214 -0
- package/lib/chat/components/chat-header.js +9 -0
- package/lib/chat/components/chat-header.jsx +14 -0
- package/lib/chat/components/chat-input.js +230 -0
- package/lib/chat/components/chat-input.jsx +232 -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 +70 -0
- package/lib/chat/components/chat-page.jsx +89 -0
- package/lib/chat/components/chat.js +78 -0
- package/lib/chat/components/chat.jsx +91 -0
- package/lib/chat/components/chats-page.js +170 -0
- package/lib/chat/components/chats-page.jsx +203 -0
- package/lib/chat/components/crons-page.js +144 -0
- package/lib/chat/components/crons-page.jsx +204 -0
- package/lib/chat/components/greeting.js +11 -0
- package/lib/chat/components/greeting.jsx +14 -0
- package/lib/chat/components/icons.js +518 -0
- package/lib/chat/components/icons.jsx +482 -0
- package/lib/chat/components/index.js +19 -0
- package/lib/chat/components/message.js +66 -0
- package/lib/chat/components/message.jsx +92 -0
- package/lib/chat/components/messages.js +63 -0
- package/lib/chat/components/messages.jsx +72 -0
- package/lib/chat/components/notifications-page.js +54 -0
- package/lib/chat/components/notifications-page.jsx +83 -0
- package/lib/chat/components/page-layout.js +21 -0
- package/lib/chat/components/page-layout.jsx +28 -0
- package/lib/chat/components/settings-layout.js +37 -0
- package/lib/chat/components/settings-layout.jsx +51 -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 +54 -0
- package/lib/chat/components/sidebar-history-item.jsx +50 -0
- package/lib/chat/components/sidebar-history.js +92 -0
- package/lib/chat/components/sidebar-history.jsx +132 -0
- package/lib/chat/components/sidebar-user-nav.js +59 -0
- package/lib/chat/components/sidebar-user-nav.jsx +69 -0
- package/lib/chat/components/swarm-page.js +250 -0
- package/lib/chat/components/swarm-page.jsx +356 -0
- package/lib/chat/components/triggers-page.js +121 -0
- package/lib/chat/components/triggers-page.jsx +177 -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/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/utils.js +11 -0
- package/lib/cron.js +7 -8
- package/lib/db/api-keys.js +160 -0
- package/lib/db/chats.js +129 -0
- package/lib/db/index.js +106 -0
- package/lib/db/notifications.js +99 -0
- package/lib/db/schema.js +51 -0
- package/lib/db/users.js +89 -0
- package/lib/paths.js +23 -17
- package/lib/tools/create-job.js +3 -3
- package/lib/tools/github.js +145 -1
- package/lib/tools/openai.js +1 -1
- package/lib/tools/telegram.js +4 -3
- package/lib/triggers.js +6 -7
- package/lib/utils/render-md.js +6 -6
- package/package.json +43 -6
- package/setup/lib/auth.mjs +22 -9
- package/setup/lib/prerequisites.mjs +10 -3
- package/setup/lib/telegram-verify.mjs +3 -16
- package/setup/setup-telegram.mjs +31 -62
- package/setup/setup.mjs +58 -98
- package/templates/.dockerignore +5 -0
- package/templates/.env.example +18 -2
- package/templates/.github/workflows/auto-merge.yml +1 -1
- package/templates/.github/workflows/build-image.yml +6 -4
- package/templates/.github/workflows/notify-job-failed.yml +2 -2
- package/templates/.github/workflows/notify-pr-complete.yml +2 -2
- package/templates/.github/workflows/run-job.yml +24 -10
- package/templates/CLAUDE.md +5 -3
- package/templates/app/api/auth/[...nextauth]/route.js +1 -0
- package/templates/app/api/chat/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 +81 -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 +7 -0
- package/templates/app/globals.css +66 -0
- package/templates/app/layout.js +9 -2
- package/templates/app/login/page.js +15 -0
- package/templates/app/notifications/page.js +7 -0
- package/templates/app/page.js +6 -30
- package/templates/app/settings/layout.js +7 -0
- package/templates/app/settings/page.js +5 -0
- package/templates/app/settings/secrets/page.js +5 -0
- package/templates/app/swarm/page.js +7 -0
- package/templates/app/triggers/page.js +7 -0
- package/templates/config/CRONS.json +2 -2
- package/templates/config/TRIGGERS.json +2 -2
- package/templates/docker/event_handler/Dockerfile +19 -0
- package/templates/docker/{entrypoint.sh → job/entrypoint.sh} +4 -4
- package/templates/docker/runner/Dockerfile +38 -0
- package/templates/docker/runner/entrypoint.sh +41 -0
- package/templates/docker-compose.yml +52 -0
- package/templates/instrumentation.js +6 -1
- package/templates/middleware.js +1 -0
- package/templates/postcss.config.mjs +5 -0
- package/lib/claude/conversation.js +0 -76
- package/lib/claude/index.js +0 -142
- package/lib/claude/tools.js +0 -54
- /package/templates/docker/{Dockerfile → job/Dockerfile} +0 -0
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* In-memory conversation history management per Telegram chat.
|
|
3
|
-
* - Keyed by chat_id
|
|
4
|
-
* - 30-minute TTL per conversation
|
|
5
|
-
* - Max 20 messages per conversation
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const MAX_MESSAGES = 20;
|
|
9
|
-
const TTL_MS = 30 * 60 * 1000; // 30 minutes
|
|
10
|
-
const CLEANUP_INTERVAL_MS = 5 * 60 * 1000; // 5 minutes
|
|
11
|
-
|
|
12
|
-
// Map<chatId, { messages: Array, lastAccess: number }>
|
|
13
|
-
const conversations = new Map();
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Get conversation history for a chat
|
|
17
|
-
* @param {string} chatId - Telegram chat ID
|
|
18
|
-
* @returns {Array} - Message history array
|
|
19
|
-
*/
|
|
20
|
-
function getHistory(chatId) {
|
|
21
|
-
const entry = conversations.get(chatId);
|
|
22
|
-
if (!entry) return [];
|
|
23
|
-
|
|
24
|
-
// Check if expired
|
|
25
|
-
if (Date.now() - entry.lastAccess > TTL_MS) {
|
|
26
|
-
conversations.delete(chatId);
|
|
27
|
-
return [];
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
entry.lastAccess = Date.now();
|
|
31
|
-
return entry.messages;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Update conversation history for a chat
|
|
36
|
-
* @param {string} chatId - Telegram chat ID
|
|
37
|
-
* @param {Array} messages - New message history
|
|
38
|
-
*/
|
|
39
|
-
function updateHistory(chatId, messages) {
|
|
40
|
-
// Trim to max messages (keep most recent)
|
|
41
|
-
const trimmed = messages.slice(-MAX_MESSAGES);
|
|
42
|
-
|
|
43
|
-
conversations.set(chatId, {
|
|
44
|
-
messages: trimmed,
|
|
45
|
-
lastAccess: Date.now(),
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Clear conversation history for a chat
|
|
51
|
-
* @param {string} chatId - Telegram chat ID
|
|
52
|
-
*/
|
|
53
|
-
function clearHistory(chatId) {
|
|
54
|
-
conversations.delete(chatId);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Clean up expired conversations
|
|
59
|
-
*/
|
|
60
|
-
function cleanupExpired() {
|
|
61
|
-
const now = Date.now();
|
|
62
|
-
for (const [chatId, entry] of conversations) {
|
|
63
|
-
if (now - entry.lastAccess > TTL_MS) {
|
|
64
|
-
conversations.delete(chatId);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Start cleanup interval
|
|
70
|
-
setInterval(cleanupExpired, CLEANUP_INTERVAL_MS);
|
|
71
|
-
|
|
72
|
-
module.exports = {
|
|
73
|
-
getHistory,
|
|
74
|
-
updateHistory,
|
|
75
|
-
clearHistory,
|
|
76
|
-
};
|
package/lib/claude/index.js
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
const paths = require('../paths');
|
|
2
|
-
const { render_md } = require('../utils/render-md');
|
|
3
|
-
|
|
4
|
-
const DEFAULT_MODEL = 'claude-sonnet-4-20250514';
|
|
5
|
-
|
|
6
|
-
// Web search tool definition (Anthropic built-in)
|
|
7
|
-
const WEB_SEARCH_TOOL = {
|
|
8
|
-
type: 'web_search_20250305',
|
|
9
|
-
name: 'web_search',
|
|
10
|
-
max_uses: 5,
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Get Anthropic API key from environment
|
|
15
|
-
* @returns {string} API key
|
|
16
|
-
*/
|
|
17
|
-
function getApiKey() {
|
|
18
|
-
if (process.env.ANTHROPIC_API_KEY) {
|
|
19
|
-
return process.env.ANTHROPIC_API_KEY;
|
|
20
|
-
}
|
|
21
|
-
throw new Error('ANTHROPIC_API_KEY environment variable is required');
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Call Claude API
|
|
26
|
-
* @param {Array} messages - Conversation messages
|
|
27
|
-
* @param {Array} tools - Tool definitions
|
|
28
|
-
* @returns {Promise<Object>} API response
|
|
29
|
-
*/
|
|
30
|
-
async function callClaude(messages, tools) {
|
|
31
|
-
const apiKey = getApiKey();
|
|
32
|
-
const model = process.env.EVENT_HANDLER_MODEL || DEFAULT_MODEL;
|
|
33
|
-
const systemPrompt = render_md(paths.chatbotMd);
|
|
34
|
-
|
|
35
|
-
// Combine user tools with web search
|
|
36
|
-
const allTools = [WEB_SEARCH_TOOL, ...tools];
|
|
37
|
-
|
|
38
|
-
const response = await fetch('https://api.anthropic.com/v1/messages', {
|
|
39
|
-
method: 'POST',
|
|
40
|
-
headers: {
|
|
41
|
-
'Content-Type': 'application/json',
|
|
42
|
-
'x-api-key': apiKey,
|
|
43
|
-
'anthropic-version': '2023-06-01',
|
|
44
|
-
'anthropic-beta': 'web-search-2025-03-05',
|
|
45
|
-
},
|
|
46
|
-
body: JSON.stringify({
|
|
47
|
-
model,
|
|
48
|
-
max_tokens: 4096,
|
|
49
|
-
system: systemPrompt,
|
|
50
|
-
messages,
|
|
51
|
-
tools: allTools,
|
|
52
|
-
}),
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
if (!response.ok) {
|
|
56
|
-
const error = await response.text();
|
|
57
|
-
throw new Error(`Claude API error: ${response.status} ${error}`);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return response.json();
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Process a conversation turn with Claude, handling tool calls
|
|
65
|
-
* @param {string} userMessage - User's message
|
|
66
|
-
* @param {Array} history - Conversation history
|
|
67
|
-
* @param {Array} toolDefinitions - Available tools
|
|
68
|
-
* @param {Object} toolExecutors - Tool executor functions
|
|
69
|
-
* @returns {Promise<{response: string, history: Array}>}
|
|
70
|
-
*/
|
|
71
|
-
async function chat(userMessage, history, toolDefinitions, toolExecutors) {
|
|
72
|
-
// Add user message to history
|
|
73
|
-
const messages = [...history, { role: 'user', content: userMessage }];
|
|
74
|
-
|
|
75
|
-
let response = await callClaude(messages, toolDefinitions);
|
|
76
|
-
let assistantContent = response.content;
|
|
77
|
-
|
|
78
|
-
// Add assistant response to history
|
|
79
|
-
messages.push({ role: 'assistant', content: assistantContent });
|
|
80
|
-
|
|
81
|
-
// Handle tool use loop
|
|
82
|
-
while (response.stop_reason === 'tool_use') {
|
|
83
|
-
const toolResults = [];
|
|
84
|
-
|
|
85
|
-
for (const block of assistantContent) {
|
|
86
|
-
if (block.type === 'tool_use') {
|
|
87
|
-
// Skip web_search - it's a server-side tool executed by Anthropic
|
|
88
|
-
if (block.name === 'web_search') {
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const executor = toolExecutors[block.name];
|
|
93
|
-
let result;
|
|
94
|
-
|
|
95
|
-
if (executor) {
|
|
96
|
-
try {
|
|
97
|
-
result = await executor(block.input);
|
|
98
|
-
} catch (err) {
|
|
99
|
-
result = { error: err.message };
|
|
100
|
-
}
|
|
101
|
-
} else {
|
|
102
|
-
result = { error: `Unknown tool: ${block.name}` };
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
toolResults.push({
|
|
106
|
-
type: 'tool_result',
|
|
107
|
-
tool_use_id: block.id,
|
|
108
|
-
content: JSON.stringify(result),
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// If no client-side tools to execute, we're done
|
|
114
|
-
if (toolResults.length === 0) {
|
|
115
|
-
break;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Add tool results to messages
|
|
119
|
-
messages.push({ role: 'user', content: toolResults });
|
|
120
|
-
|
|
121
|
-
// Get next response from Claude
|
|
122
|
-
response = await callClaude(messages, toolDefinitions);
|
|
123
|
-
assistantContent = response.content;
|
|
124
|
-
|
|
125
|
-
// Add new assistant response to history
|
|
126
|
-
messages.push({ role: 'assistant', content: assistantContent });
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Extract text response
|
|
130
|
-
const textBlocks = assistantContent.filter((block) => block.type === 'text');
|
|
131
|
-
const responseText = textBlocks.map((block) => block.text).join('\n');
|
|
132
|
-
|
|
133
|
-
return {
|
|
134
|
-
response: responseText,
|
|
135
|
-
history: messages,
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
module.exports = {
|
|
140
|
-
chat,
|
|
141
|
-
getApiKey,
|
|
142
|
-
};
|
package/lib/claude/tools.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
const { createJob } = require('../tools/create-job');
|
|
2
|
-
const { getJobStatus } = require('../tools/github');
|
|
3
|
-
|
|
4
|
-
const toolDefinitions = [
|
|
5
|
-
{
|
|
6
|
-
name: 'create_job',
|
|
7
|
-
description:
|
|
8
|
-
'Create an autonomous job for thepopebot to execute. Use this tool liberally - if the user asks for ANY task to be done, create a job. Jobs can handle code changes, file updates, research tasks, web scraping, data analysis, or anything requiring autonomous work. When the user explicitly asks for a job, ALWAYS use this tool. Returns the job ID and branch name.',
|
|
9
|
-
input_schema: {
|
|
10
|
-
type: 'object',
|
|
11
|
-
properties: {
|
|
12
|
-
job_description: {
|
|
13
|
-
type: 'string',
|
|
14
|
-
description:
|
|
15
|
-
'Detailed job description including context and requirements. Be specific about what needs to be done.',
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
required: ['job_description'],
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
name: 'get_job_status',
|
|
23
|
-
description:
|
|
24
|
-
'Check status of running jobs. Returns list of active workflow runs with timing and current step. Use when user asks about job progress, running jobs, or job status.',
|
|
25
|
-
input_schema: {
|
|
26
|
-
type: 'object',
|
|
27
|
-
properties: {
|
|
28
|
-
job_id: {
|
|
29
|
-
type: 'string',
|
|
30
|
-
description:
|
|
31
|
-
'Optional: specific job ID to check. If omitted, returns all running jobs.',
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
required: [],
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
];
|
|
38
|
-
|
|
39
|
-
const toolExecutors = {
|
|
40
|
-
create_job: async (input) => {
|
|
41
|
-
const result = await createJob(input.job_description);
|
|
42
|
-
return {
|
|
43
|
-
success: true,
|
|
44
|
-
job_id: result.job_id,
|
|
45
|
-
branch: result.branch,
|
|
46
|
-
};
|
|
47
|
-
},
|
|
48
|
-
get_job_status: async (input) => {
|
|
49
|
-
const result = await getJobStatus(input.job_id);
|
|
50
|
-
return result;
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
module.exports = { toolDefinitions, toolExecutors };
|
|
File without changes
|