@chaaskit/server 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/dist/api/admin.js +438 -0
- package/dist/api/admin.js.map +1 -0
- package/dist/api/agents.js +21 -0
- package/dist/api/agents.js.map +1 -0
- package/dist/api/api-keys.js +122 -0
- package/dist/api/api-keys.js.map +1 -0
- package/dist/api/auth.js +399 -0
- package/dist/api/auth.js.map +1 -0
- package/dist/api/chat.js +900 -0
- package/dist/api/chat.js.map +1 -0
- package/dist/api/config.js +91 -0
- package/dist/api/config.js.map +1 -0
- package/dist/api/documents.js +237 -0
- package/dist/api/documents.js.map +1 -0
- package/dist/api/export.js +107 -0
- package/dist/api/export.js.map +1 -0
- package/dist/api/health.js +25 -0
- package/dist/api/health.js.map +1 -0
- package/dist/api/mcp-server.js +84 -0
- package/dist/api/mcp-server.js.map +1 -0
- package/dist/api/mcp.js +400 -0
- package/dist/api/mcp.js.map +1 -0
- package/dist/api/mentions.js +94 -0
- package/dist/api/mentions.js.map +1 -0
- package/dist/api/oauth.js +366 -0
- package/dist/api/oauth.js.map +1 -0
- package/dist/api/payments.js +473 -0
- package/dist/api/payments.js.map +1 -0
- package/dist/api/projects.js +301 -0
- package/dist/api/projects.js.map +1 -0
- package/dist/api/scheduled-prompts.js +617 -0
- package/dist/api/scheduled-prompts.js.map +1 -0
- package/dist/api/search.js +85 -0
- package/dist/api/search.js.map +1 -0
- package/dist/api/share.js +188 -0
- package/dist/api/share.js.map +1 -0
- package/dist/api/slack.js +468 -0
- package/dist/api/slack.js.map +1 -0
- package/dist/api/teams.js +693 -0
- package/dist/api/teams.js.map +1 -0
- package/dist/api/templates.js +134 -0
- package/dist/api/templates.js.map +1 -0
- package/dist/api/threads.js +323 -0
- package/dist/api/threads.js.map +1 -0
- package/dist/api/upload.js +57 -0
- package/dist/api/upload.js.map +1 -0
- package/dist/api/user.js +111 -0
- package/dist/api/user.js.map +1 -0
- package/dist/api/v1/openai.js +245 -0
- package/dist/api/v1/openai.js.map +1 -0
- package/dist/app.js +168 -0
- package/dist/app.js.map +1 -0
- package/dist/bin/cli.js +57 -0
- package/dist/bin/cli.js.map +1 -0
- package/dist/commands/db-sync.js +108 -0
- package/dist/commands/db-sync.js.map +1 -0
- package/dist/config/loader.js +374 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/documents/extractors.js +136 -0
- package/dist/documents/extractors.js.map +1 -0
- package/dist/extensions/glob.js +53 -0
- package/dist/extensions/glob.js.map +1 -0
- package/dist/extensions/loader.js +72 -0
- package/dist/extensions/loader.js.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/loaders/index.js +75 -0
- package/dist/loaders/index.js.map +1 -0
- package/dist/mcp/client.js +551 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/server.js +335 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/middleware/apiKeyAuth.js +136 -0
- package/dist/middleware/apiKeyAuth.js.map +1 -0
- package/dist/middleware/auth.js +192 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/errorHandler.js +41 -0
- package/dist/middleware/errorHandler.js.map +1 -0
- package/dist/middleware/mcpServerAuth.js +164 -0
- package/dist/middleware/mcpServerAuth.js.map +1 -0
- package/dist/middleware/requestLogger.js +9 -0
- package/dist/middleware/requestLogger.js.map +1 -0
- package/dist/middleware/team.js +132 -0
- package/dist/middleware/team.js.map +1 -0
- package/dist/oauth/server.js +410 -0
- package/dist/oauth/server.js.map +1 -0
- package/dist/queue/cli.js +93 -0
- package/dist/queue/cli.js.map +1 -0
- package/dist/queue/handlers/index.js +91 -0
- package/dist/queue/handlers/index.js.map +1 -0
- package/dist/queue/handlers/scheduled-prompt.js +270 -0
- package/dist/queue/handlers/scheduled-prompt.js.map +1 -0
- package/dist/queue/index.js +91 -0
- package/dist/queue/index.js.map +1 -0
- package/dist/queue/providers/memory.js +296 -0
- package/dist/queue/providers/memory.js.map +1 -0
- package/dist/queue/providers/sqs.js +275 -0
- package/dist/queue/providers/sqs.js.map +1 -0
- package/dist/queue/scheduler.js +355 -0
- package/dist/queue/scheduler.js.map +1 -0
- package/dist/queue/types.js +5 -0
- package/dist/queue/types.js.map +1 -0
- package/dist/queue/worker.js +230 -0
- package/dist/queue/worker.js.map +1 -0
- package/dist/registry/index.js +40 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/server.js +207 -0
- package/dist/server.js.map +1 -0
- package/dist/services/agent.js +530 -0
- package/dist/services/agent.js.map +1 -0
- package/dist/services/agents.js +194 -0
- package/dist/services/agents.js.map +1 -0
- package/dist/services/documents.js +507 -0
- package/dist/services/documents.js.map +1 -0
- package/dist/services/email/index.js +91 -0
- package/dist/services/email/index.js.map +1 -0
- package/dist/services/email/providers/ses.js +97 -0
- package/dist/services/email/providers/ses.js.map +1 -0
- package/dist/services/email/templates.js +194 -0
- package/dist/services/email/templates.js.map +1 -0
- package/dist/services/email/types.js +5 -0
- package/dist/services/email/types.js.map +1 -0
- package/dist/services/encryption.js +69 -0
- package/dist/services/encryption.js.map +1 -0
- package/dist/services/oauth-discovery.js +226 -0
- package/dist/services/oauth-discovery.js.map +1 -0
- package/dist/services/pendingConfirmation.js +105 -0
- package/dist/services/pendingConfirmation.js.map +1 -0
- package/dist/services/scheduledPrompts.js +70 -0
- package/dist/services/scheduledPrompts.js.map +1 -0
- package/dist/services/slack/client.js +174 -0
- package/dist/services/slack/client.js.map +1 -0
- package/dist/services/slack/events.js +189 -0
- package/dist/services/slack/events.js.map +1 -0
- package/dist/services/slack/index.js +6 -0
- package/dist/services/slack/index.js.map +1 -0
- package/dist/services/slack/notifications.js +124 -0
- package/dist/services/slack/notifications.js.map +1 -0
- package/dist/services/slack/signature.js +74 -0
- package/dist/services/slack/signature.js.map +1 -0
- package/dist/services/slack/thread-context.js +191 -0
- package/dist/services/slack/thread-context.js.map +1 -0
- package/dist/services/toolConfirmation.js +55 -0
- package/dist/services/toolConfirmation.js.map +1 -0
- package/dist/services/usage.js +241 -0
- package/dist/services/usage.js.map +1 -0
- package/dist/ssr/build.js +90 -0
- package/dist/ssr/build.js.map +1 -0
- package/dist/ssr/components/SSRMessageList.js +120 -0
- package/dist/ssr/components/SSRMessageList.js.map +1 -0
- package/dist/ssr/entry.client.js +8 -0
- package/dist/ssr/entry.client.js.map +1 -0
- package/dist/ssr/entry.server.js +71 -0
- package/dist/ssr/entry.server.js.map +1 -0
- package/dist/ssr/handler.js +51 -0
- package/dist/ssr/handler.js.map +1 -0
- package/dist/ssr/root.js +184 -0
- package/dist/ssr/root.js.map +1 -0
- package/dist/ssr/routes/login.js +140 -0
- package/dist/ssr/routes/login.js.map +1 -0
- package/dist/ssr/routes/pricing.js +195 -0
- package/dist/ssr/routes/pricing.js.map +1 -0
- package/dist/ssr/routes/privacy.js +39 -0
- package/dist/ssr/routes/privacy.js.map +1 -0
- package/dist/ssr/routes/register.js +148 -0
- package/dist/ssr/routes/register.js.map +1 -0
- package/dist/ssr/routes/shared.$shareId.js +153 -0
- package/dist/ssr/routes/shared.$shareId.js.map +1 -0
- package/dist/ssr/routes/terms.js +39 -0
- package/dist/ssr/routes/terms.js.map +1 -0
- package/dist/storage/index.js +43 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/providers/database.js +38 -0
- package/dist/storage/providers/database.js.map +1 -0
- package/dist/storage/providers/filesystem.js +51 -0
- package/dist/storage/providers/filesystem.js.map +1 -0
- package/dist/storage/types.js +2 -0
- package/dist/storage/types.js.map +1 -0
- package/dist/tools/documents.js +336 -0
- package/dist/tools/documents.js.map +1 -0
- package/dist/tools/get-plan-usage.js +82 -0
- package/dist/tools/get-plan-usage.js.map +1 -0
- package/dist/tools/index.js +106 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/types.js +2 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools/web-scrape.js +145 -0
- package/dist/tools/web-scrape.js.map +1 -0
- package/package.json +93 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PendingConfirmationManager - Manages pending tool confirmations
|
|
3
|
+
*
|
|
4
|
+
* When a tool requires user confirmation, a pending confirmation is created
|
|
5
|
+
* that holds a promise resolver. The chat handler awaits this promise while
|
|
6
|
+
* the user is shown a confirmation modal. When the user responds via the
|
|
7
|
+
* /confirm-tool API, the promise resolves and the tool continues.
|
|
8
|
+
*/
|
|
9
|
+
class PendingConfirmationManager {
|
|
10
|
+
pending = new Map();
|
|
11
|
+
cleanupInterval = null;
|
|
12
|
+
TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
|
|
13
|
+
constructor() {
|
|
14
|
+
// Start cleanup interval
|
|
15
|
+
this.cleanupInterval = setInterval(() => this.cleanup(), 60000); // Check every minute
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Create a new pending confirmation
|
|
19
|
+
* Returns an id and a promise that resolves when the user responds
|
|
20
|
+
*/
|
|
21
|
+
create(params) {
|
|
22
|
+
const id = `confirm_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
23
|
+
let resolveFunc;
|
|
24
|
+
const promise = new Promise((resolve) => {
|
|
25
|
+
resolveFunc = resolve;
|
|
26
|
+
});
|
|
27
|
+
const confirmation = {
|
|
28
|
+
id,
|
|
29
|
+
visitorId: params.visitorId,
|
|
30
|
+
threadId: params.threadId,
|
|
31
|
+
userId: params.userId,
|
|
32
|
+
serverId: params.serverId,
|
|
33
|
+
toolName: params.toolName,
|
|
34
|
+
toolArgs: params.toolArgs,
|
|
35
|
+
resolve: resolveFunc,
|
|
36
|
+
createdAt: Date.now(),
|
|
37
|
+
};
|
|
38
|
+
this.pending.set(id, confirmation);
|
|
39
|
+
console.log(`[PendingConfirmation] Created: ${id} for tool ${params.serverId}:${params.toolName}`);
|
|
40
|
+
return { id, promise };
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Resolve a pending confirmation
|
|
44
|
+
* Called when the user responds to the confirmation modal
|
|
45
|
+
*/
|
|
46
|
+
resolve(id, approved, scope) {
|
|
47
|
+
const confirmation = this.pending.get(id);
|
|
48
|
+
if (!confirmation) {
|
|
49
|
+
console.log(`[PendingConfirmation] Not found: ${id}`);
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
console.log(`[PendingConfirmation] Resolved: ${id} approved=${approved} scope=${scope}`);
|
|
53
|
+
confirmation.resolve({ approved, scope });
|
|
54
|
+
this.pending.delete(id);
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get a pending confirmation by ID
|
|
59
|
+
*/
|
|
60
|
+
get(id) {
|
|
61
|
+
return this.pending.get(id);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Clean up expired confirmations (5 minute timeout)
|
|
65
|
+
* Expired confirmations are auto-denied
|
|
66
|
+
*/
|
|
67
|
+
cleanup() {
|
|
68
|
+
const now = Date.now();
|
|
69
|
+
const expiredIds = [];
|
|
70
|
+
for (const [id, confirmation] of this.pending.entries()) {
|
|
71
|
+
if (now - confirmation.createdAt > this.TIMEOUT_MS) {
|
|
72
|
+
expiredIds.push(id);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
for (const id of expiredIds) {
|
|
76
|
+
const confirmation = this.pending.get(id);
|
|
77
|
+
if (confirmation) {
|
|
78
|
+
console.log(`[PendingConfirmation] Expired: ${id}`);
|
|
79
|
+
confirmation.resolve({ approved: false }); // Auto-deny expired confirmations
|
|
80
|
+
this.pending.delete(id);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (expiredIds.length > 0) {
|
|
84
|
+
console.log(`[PendingConfirmation] Cleaned up ${expiredIds.length} expired confirmations`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get count of pending confirmations (for monitoring)
|
|
89
|
+
*/
|
|
90
|
+
getPendingCount() {
|
|
91
|
+
return this.pending.size;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Shutdown - cleanup interval
|
|
95
|
+
*/
|
|
96
|
+
shutdown() {
|
|
97
|
+
if (this.cleanupInterval) {
|
|
98
|
+
clearInterval(this.cleanupInterval);
|
|
99
|
+
this.cleanupInterval = null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Singleton instance
|
|
104
|
+
export const pendingConfirmations = new PendingConfirmationManager();
|
|
105
|
+
//# sourceMappingURL=pendingConfirmation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pendingConfirmation.js","sourceRoot":"","sources":["../../src/services/pendingConfirmation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scheduled Prompts Service
|
|
3
|
+
*
|
|
4
|
+
* Manages scheduled prompts lifecycle and sync with recurring jobs.
|
|
5
|
+
*/
|
|
6
|
+
import { db } from '@chaaskit/db';
|
|
7
|
+
import { getScheduler } from '../queue/index.js';
|
|
8
|
+
/**
|
|
9
|
+
* Sync all enabled scheduled prompts to recurring jobs.
|
|
10
|
+
* Called on server startup to ensure scheduler has all jobs.
|
|
11
|
+
*
|
|
12
|
+
* @returns Number of prompts synced
|
|
13
|
+
*/
|
|
14
|
+
export async function syncScheduledPromptsToRecurringJobs() {
|
|
15
|
+
const scheduler = getScheduler();
|
|
16
|
+
if (!scheduler) {
|
|
17
|
+
console.log('[ScheduledPrompts] Scheduler not available');
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
20
|
+
// Get all enabled scheduled prompts
|
|
21
|
+
const prompts = await db.scheduledPrompt.findMany({
|
|
22
|
+
where: { enabled: true },
|
|
23
|
+
});
|
|
24
|
+
console.log(`[ScheduledPrompts] Found ${prompts.length} enabled prompts to sync`);
|
|
25
|
+
for (const prompt of prompts) {
|
|
26
|
+
const recurringJobName = `scheduled-prompt:${prompt.id}`;
|
|
27
|
+
try {
|
|
28
|
+
await scheduler.registerRecurring({
|
|
29
|
+
name: recurringJobName,
|
|
30
|
+
type: 'scheduled-prompt:execute',
|
|
31
|
+
payload: { scheduledPromptId: prompt.id },
|
|
32
|
+
schedule: prompt.schedule,
|
|
33
|
+
timezone: prompt.timezone,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
console.error(`[ScheduledPrompts] Failed to sync prompt ${prompt.id}:`, error instanceof Error ? error.message : error);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// Clean up orphaned recurring jobs (prompts that were deleted while server was down)
|
|
41
|
+
const allRecurringJobs = await db.recurringJob.findMany({
|
|
42
|
+
where: {
|
|
43
|
+
name: { startsWith: 'scheduled-prompt:' },
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
const promptIds = new Set(prompts.map((p) => p.id));
|
|
47
|
+
for (const job of allRecurringJobs) {
|
|
48
|
+
const promptId = job.name.replace('scheduled-prompt:', '');
|
|
49
|
+
if (!promptIds.has(promptId)) {
|
|
50
|
+
console.log(`[ScheduledPrompts] Cleaning up orphaned job: ${job.name}`);
|
|
51
|
+
await db.recurringJob.delete({
|
|
52
|
+
where: { id: job.id },
|
|
53
|
+
}).catch(() => {
|
|
54
|
+
// Ignore deletion errors
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Also disable recurring jobs for disabled prompts
|
|
59
|
+
const disabledPrompts = await db.scheduledPrompt.findMany({
|
|
60
|
+
where: { enabled: false },
|
|
61
|
+
});
|
|
62
|
+
for (const prompt of disabledPrompts) {
|
|
63
|
+
const recurringJobName = `scheduled-prompt:${prompt.id}`;
|
|
64
|
+
await scheduler.disableRecurring(recurringJobName).catch(() => {
|
|
65
|
+
// Ignore if job doesn't exist
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return prompts.length;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=scheduledPrompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduledPrompts.js","sourceRoot":"","sources":["../../src/services/scheduledPrompts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { getConfig } from '../../config/loader.js';
|
|
2
|
+
import { decryptCredential, encryptCredential } from '../encryption.js';
|
|
3
|
+
/**
|
|
4
|
+
* Get Slack OAuth credentials from environment.
|
|
5
|
+
*/
|
|
6
|
+
export function getSlackCredentials() {
|
|
7
|
+
const config = getConfig();
|
|
8
|
+
const clientIdEnvVar = config.slack?.clientIdEnvVar || 'SLACK_CLIENT_ID';
|
|
9
|
+
const clientSecretEnvVar = config.slack?.clientSecretEnvVar || 'SLACK_CLIENT_SECRET';
|
|
10
|
+
const clientId = process.env[clientIdEnvVar];
|
|
11
|
+
const clientSecret = process.env[clientSecretEnvVar];
|
|
12
|
+
if (!clientId || !clientSecret) {
|
|
13
|
+
throw new Error(`Missing Slack credentials: ${clientIdEnvVar} or ${clientSecretEnvVar}`);
|
|
14
|
+
}
|
|
15
|
+
return { clientId, clientSecret };
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Exchange OAuth code for access tokens.
|
|
19
|
+
*/
|
|
20
|
+
export async function exchangeCodeForTokens(code, redirectUri) {
|
|
21
|
+
const { clientId, clientSecret } = getSlackCredentials();
|
|
22
|
+
const response = await fetch('https://slack.com/api/oauth.v2.access', {
|
|
23
|
+
method: 'POST',
|
|
24
|
+
headers: {
|
|
25
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
26
|
+
},
|
|
27
|
+
body: new URLSearchParams({
|
|
28
|
+
client_id: clientId,
|
|
29
|
+
client_secret: clientSecret,
|
|
30
|
+
code,
|
|
31
|
+
redirect_uri: redirectUri,
|
|
32
|
+
}),
|
|
33
|
+
});
|
|
34
|
+
const data = await response.json();
|
|
35
|
+
return data;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Build Slack OAuth authorization URL.
|
|
39
|
+
*/
|
|
40
|
+
export function buildOAuthUrl(state, redirectUri) {
|
|
41
|
+
const { clientId } = getSlackCredentials();
|
|
42
|
+
const scopes = [
|
|
43
|
+
'app_mentions:read',
|
|
44
|
+
'channels:history',
|
|
45
|
+
'groups:history',
|
|
46
|
+
'im:history',
|
|
47
|
+
'chat:write',
|
|
48
|
+
'reactions:write',
|
|
49
|
+
'users:read',
|
|
50
|
+
].join(',');
|
|
51
|
+
const params = new URLSearchParams({
|
|
52
|
+
client_id: clientId,
|
|
53
|
+
scope: scopes,
|
|
54
|
+
redirect_uri: redirectUri,
|
|
55
|
+
state,
|
|
56
|
+
});
|
|
57
|
+
return `https://slack.com/oauth/v2/authorize?${params.toString()}`;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Encrypt tokens for storage.
|
|
61
|
+
*/
|
|
62
|
+
export function encryptTokens(tokens) {
|
|
63
|
+
return encryptCredential(tokens);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Decrypt stored tokens.
|
|
67
|
+
*/
|
|
68
|
+
export function decryptTokens(encryptedTokens) {
|
|
69
|
+
return decryptCredential(encryptedTokens);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Slack API client class for making authenticated requests.
|
|
73
|
+
*/
|
|
74
|
+
export class SlackClient {
|
|
75
|
+
botToken;
|
|
76
|
+
constructor(botToken) {
|
|
77
|
+
this.botToken = botToken;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Create client from encrypted tokens.
|
|
81
|
+
*/
|
|
82
|
+
static fromEncrypted(encryptedTokens) {
|
|
83
|
+
const tokens = decryptTokens(encryptedTokens);
|
|
84
|
+
return new SlackClient(tokens.botToken);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Make an authenticated request to the Slack API.
|
|
88
|
+
*/
|
|
89
|
+
async request(endpoint, options = {}) {
|
|
90
|
+
const url = `https://slack.com/api/${endpoint}`;
|
|
91
|
+
const response = await fetch(url, {
|
|
92
|
+
...options,
|
|
93
|
+
headers: {
|
|
94
|
+
'Authorization': `Bearer ${this.botToken}`,
|
|
95
|
+
'Content-Type': 'application/json; charset=utf-8',
|
|
96
|
+
...options.headers,
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
const data = await response.json();
|
|
100
|
+
return data;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Post a message to a channel.
|
|
104
|
+
*/
|
|
105
|
+
async postMessage(channel, text, options = {}) {
|
|
106
|
+
return this.request('chat.postMessage', {
|
|
107
|
+
method: 'POST',
|
|
108
|
+
body: JSON.stringify({
|
|
109
|
+
channel,
|
|
110
|
+
text,
|
|
111
|
+
thread_ts: options.threadTs,
|
|
112
|
+
mrkdwn: options.mrkdwn ?? true,
|
|
113
|
+
unfurl_links: options.unfurlLinks ?? false,
|
|
114
|
+
unfurl_media: options.unfurlMedia ?? false,
|
|
115
|
+
}),
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Add a reaction to a message.
|
|
120
|
+
*/
|
|
121
|
+
async addReaction(channel, timestamp, emoji) {
|
|
122
|
+
return this.request('reactions.add', {
|
|
123
|
+
method: 'POST',
|
|
124
|
+
body: JSON.stringify({
|
|
125
|
+
channel,
|
|
126
|
+
timestamp,
|
|
127
|
+
name: emoji,
|
|
128
|
+
}),
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Remove a reaction from a message.
|
|
133
|
+
*/
|
|
134
|
+
async removeReaction(channel, timestamp, emoji) {
|
|
135
|
+
return this.request('reactions.remove', {
|
|
136
|
+
method: 'POST',
|
|
137
|
+
body: JSON.stringify({
|
|
138
|
+
channel,
|
|
139
|
+
timestamp,
|
|
140
|
+
name: emoji,
|
|
141
|
+
}),
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Get conversation/thread history.
|
|
146
|
+
*/
|
|
147
|
+
async getConversationHistory(channel, options = {}) {
|
|
148
|
+
const endpoint = options.threadTs ? 'conversations.replies' : 'conversations.history';
|
|
149
|
+
const params = {
|
|
150
|
+
channel,
|
|
151
|
+
limit: (options.limit ?? 50).toString(),
|
|
152
|
+
};
|
|
153
|
+
if (options.threadTs) {
|
|
154
|
+
params.ts = options.threadTs;
|
|
155
|
+
}
|
|
156
|
+
if (options.cursor) {
|
|
157
|
+
params.cursor = options.cursor;
|
|
158
|
+
}
|
|
159
|
+
return this.request(`${endpoint}?${new URLSearchParams(params).toString()}`);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Get user information.
|
|
163
|
+
*/
|
|
164
|
+
async getUserInfo(userId) {
|
|
165
|
+
return this.request(`users.info?user=${userId}`);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Test authentication (useful for checking if token is valid).
|
|
169
|
+
*/
|
|
170
|
+
async authTest() {
|
|
171
|
+
return this.request('auth.test', { method: 'POST' });
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/services/slack/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { db } from '@chaaskit/db';
|
|
2
|
+
import { getConfig } from '../../config/loader.js';
|
|
3
|
+
import { createAgentService } from '../agent.js';
|
|
4
|
+
import { getDefaultAgent, toAgentConfig, isBuiltInAgent } from '../agents.js';
|
|
5
|
+
import { SlackClient } from './client.js';
|
|
6
|
+
import { buildSlackThreadContext, findOrCreateInternalThread, getInternalThreadHistory, saveToInternalThread, cleanSlackMessage, formatForSlack, SLACK_FORMAT_INSTRUCTIONS, } from './thread-context.js';
|
|
7
|
+
/**
|
|
8
|
+
* Process a pending Slack event.
|
|
9
|
+
*/
|
|
10
|
+
export async function processSlackEvent(eventId) {
|
|
11
|
+
// Atomic claim: UPDATE SET status='processing' WHERE id=? AND status='pending'
|
|
12
|
+
const event = await db.slackMessageEvent.findUnique({
|
|
13
|
+
where: { id: eventId },
|
|
14
|
+
include: {
|
|
15
|
+
integration: {
|
|
16
|
+
include: {
|
|
17
|
+
team: true,
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
if (!event) {
|
|
23
|
+
console.log('[Slack] Event not found:', eventId);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
// Atomic claim with WHERE status='pending'
|
|
27
|
+
const claimResult = await db.slackMessageEvent.updateMany({
|
|
28
|
+
where: {
|
|
29
|
+
id: eventId,
|
|
30
|
+
status: 'pending',
|
|
31
|
+
},
|
|
32
|
+
data: {
|
|
33
|
+
status: 'processing',
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
if (claimResult.count === 0) {
|
|
37
|
+
// Already claimed or not pending
|
|
38
|
+
console.log('[Slack] Event already claimed:', eventId);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const integration = event.integration;
|
|
42
|
+
// Check if AI chat is enabled
|
|
43
|
+
const config = getConfig();
|
|
44
|
+
if (!config.slack?.aiChat?.enabled || !integration.aiChatEnabled) {
|
|
45
|
+
console.log('[Slack] AI chat disabled for this integration');
|
|
46
|
+
await markEventCompleted(eventId);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
// Create Slack client
|
|
51
|
+
const client = SlackClient.fromEncrypted(integration.encryptedTokens);
|
|
52
|
+
// Add eyes reaction to indicate processing
|
|
53
|
+
try {
|
|
54
|
+
await client.addReaction(event.slackChannelId, event.slackMessageTs, 'eyes');
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
// Non-critical, continue processing
|
|
58
|
+
console.warn('[Slack] Failed to add reaction:', err);
|
|
59
|
+
}
|
|
60
|
+
// Clean the incoming message
|
|
61
|
+
const cleanedMessage = cleanSlackMessage(event.messageText || '', integration.slackBotUserId);
|
|
62
|
+
if (!cleanedMessage) {
|
|
63
|
+
console.log('[Slack] Empty message after cleaning');
|
|
64
|
+
await markEventFailed(eventId, 'Empty message');
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
// Build context from Slack thread (if in a thread)
|
|
68
|
+
let slackContext = await buildSlackThreadContext(client, event.slackChannelId, event.slackThreadTs, integration.slackBotUserId);
|
|
69
|
+
// Find or create internal thread for continuity
|
|
70
|
+
const internalThreadId = await findOrCreateInternalThread(integration.teamId, event.slackChannelId, event.slackThreadTs);
|
|
71
|
+
// Update event with internal thread linkage
|
|
72
|
+
await db.slackMessageEvent.update({
|
|
73
|
+
where: { id: eventId },
|
|
74
|
+
data: { internalThreadId },
|
|
75
|
+
});
|
|
76
|
+
// Get history from internal thread (for context continuity)
|
|
77
|
+
const internalHistory = await getInternalThreadHistory(internalThreadId);
|
|
78
|
+
// Build messages for agent
|
|
79
|
+
const messages = [];
|
|
80
|
+
// Use internal history if available (preferred for continuity)
|
|
81
|
+
if (config.slack?.aiChat?.threadContinuity && internalHistory.length > 0) {
|
|
82
|
+
messages.push(...internalHistory);
|
|
83
|
+
}
|
|
84
|
+
else if (slackContext && slackContext.messages.length > 0) {
|
|
85
|
+
// Fall back to Slack thread context
|
|
86
|
+
messages.push(...slackContext.messages);
|
|
87
|
+
}
|
|
88
|
+
// Add current message
|
|
89
|
+
messages.push({
|
|
90
|
+
role: 'user',
|
|
91
|
+
content: cleanedMessage,
|
|
92
|
+
});
|
|
93
|
+
// Save user message to internal thread
|
|
94
|
+
await saveToInternalThread(internalThreadId, 'user', cleanedMessage);
|
|
95
|
+
// Get the default agent
|
|
96
|
+
const agent = getDefaultAgent();
|
|
97
|
+
const agentConfig = toAgentConfig(agent);
|
|
98
|
+
// Get system prompt and add Slack formatting instructions
|
|
99
|
+
const baseSystemPrompt = isBuiltInAgent(agent) ? agent.systemPrompt : undefined;
|
|
100
|
+
const systemPrompt = baseSystemPrompt
|
|
101
|
+
? `${baseSystemPrompt}\n\n${SLACK_FORMAT_INSTRUCTIONS}`
|
|
102
|
+
: SLACK_FORMAT_INSTRUCTIONS;
|
|
103
|
+
// Create agent service and generate response
|
|
104
|
+
const agentService = createAgentService(agentConfig);
|
|
105
|
+
// Collect the full response
|
|
106
|
+
let fullResponse = '';
|
|
107
|
+
const chunks = agentService.chat(messages, {
|
|
108
|
+
systemPrompt,
|
|
109
|
+
teamContext: integration.team?.context || null,
|
|
110
|
+
});
|
|
111
|
+
for await (const chunk of chunks) {
|
|
112
|
+
if (chunk.type === 'text' && chunk.content) {
|
|
113
|
+
fullResponse += chunk.content;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (!fullResponse.trim()) {
|
|
117
|
+
console.log('[Slack] Empty response from agent');
|
|
118
|
+
await markEventFailed(eventId, 'Empty response from agent');
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
// Format response for Slack
|
|
122
|
+
const formattedResponse = formatForSlack(fullResponse);
|
|
123
|
+
// Save assistant response to internal thread
|
|
124
|
+
await saveToInternalThread(internalThreadId, 'assistant', fullResponse);
|
|
125
|
+
// Post response to Slack
|
|
126
|
+
const threadTs = event.slackThreadTs || event.slackMessageTs; // Reply in thread
|
|
127
|
+
const postResult = await client.postMessage(event.slackChannelId, formattedResponse, { threadTs });
|
|
128
|
+
if (!postResult.ok) {
|
|
129
|
+
console.error('[Slack] Failed to post message:', postResult.error);
|
|
130
|
+
await markEventFailed(eventId, `Failed to post: ${postResult.error}`);
|
|
131
|
+
// Try to add error reaction
|
|
132
|
+
try {
|
|
133
|
+
await client.removeReaction(event.slackChannelId, event.slackMessageTs, 'eyes');
|
|
134
|
+
await client.addReaction(event.slackChannelId, event.slackMessageTs, 'x');
|
|
135
|
+
}
|
|
136
|
+
catch { }
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
// Replace eyes with checkmark
|
|
140
|
+
try {
|
|
141
|
+
await client.removeReaction(event.slackChannelId, event.slackMessageTs, 'eyes');
|
|
142
|
+
await client.addReaction(event.slackChannelId, event.slackMessageTs, 'white_check_mark');
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
// Non-critical
|
|
146
|
+
console.warn('[Slack] Failed to update reaction:', err);
|
|
147
|
+
}
|
|
148
|
+
// Mark event as completed
|
|
149
|
+
await db.slackMessageEvent.update({
|
|
150
|
+
where: { id: eventId },
|
|
151
|
+
data: {
|
|
152
|
+
status: 'completed',
|
|
153
|
+
processedAt: new Date(),
|
|
154
|
+
responseTs: postResult.ts,
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
console.log('[Slack] Successfully processed event:', eventId);
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
console.error('[Slack] Error processing event:', error);
|
|
161
|
+
await markEventFailed(eventId, error instanceof Error ? error.message : 'Unknown error');
|
|
162
|
+
// Try to add error reaction
|
|
163
|
+
try {
|
|
164
|
+
const client = SlackClient.fromEncrypted(integration.encryptedTokens);
|
|
165
|
+
await client.removeReaction(event.slackChannelId, event.slackMessageTs, 'eyes');
|
|
166
|
+
await client.addReaction(event.slackChannelId, event.slackMessageTs, 'x');
|
|
167
|
+
}
|
|
168
|
+
catch { }
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
async function markEventCompleted(eventId) {
|
|
172
|
+
await db.slackMessageEvent.update({
|
|
173
|
+
where: { id: eventId },
|
|
174
|
+
data: {
|
|
175
|
+
status: 'completed',
|
|
176
|
+
processedAt: new Date(),
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
async function markEventFailed(eventId, error) {
|
|
181
|
+
await db.slackMessageEvent.update({
|
|
182
|
+
where: { id: eventId },
|
|
183
|
+
data: {
|
|
184
|
+
status: 'failed',
|
|
185
|
+
lastError: error,
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../../src/services/slack/events.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/slack/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC"}
|