mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-17 07:03:25 +00:00
mom: fix attachment downloads - pass store to SlackBot, process files, use absolute paths
This commit is contained in:
parent
d277d739b3
commit
e3576fe016
4 changed files with 246 additions and 107 deletions
|
|
@ -576,9 +576,9 @@ function createRunner(sandboxConfig: SandboxConfig, channelId: string, channelDi
|
|||
// Format: "[username]: message" so LLM knows who's talking
|
||||
let userMessage = `[${ctx.message.userName || "unknown"}]: ${ctx.message.text}`;
|
||||
|
||||
// Add attachment paths if any
|
||||
// Add attachment paths if any (convert to absolute paths in execution environment)
|
||||
if (ctx.message.attachments && ctx.message.attachments.length > 0) {
|
||||
const attachmentPaths = ctx.message.attachments.map((a) => a.local).join("\n");
|
||||
const attachmentPaths = ctx.message.attachments.map((a) => `${workspacePath}/${a.local}`).join("\n");
|
||||
userMessage += `\n\nAttachments:\n${attachmentPaths}`;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ function createSlackContext(event: SlackEvent, slack: SlackBot, state: ChannelSt
|
|||
userName: user?.userName,
|
||||
channel: event.channel,
|
||||
ts: event.ts,
|
||||
attachments: [],
|
||||
attachments: (event.attachments || []).map((a) => ({ local: a.local })),
|
||||
},
|
||||
channelName: slack.getChannel(event.channel)?.name,
|
||||
store: state.store,
|
||||
|
|
@ -243,10 +243,14 @@ const handler: MomHandler = {
|
|||
|
||||
log.logStartup(workingDir, sandbox.type === "host" ? "host" : `docker:${sandbox.container}`);
|
||||
|
||||
// Shared store for attachment downloads (also used per-channel in getState)
|
||||
const sharedStore = new ChannelStore({ workingDir, botToken: MOM_SLACK_BOT_TOKEN! });
|
||||
|
||||
const bot = new SlackBotClass(handler, {
|
||||
appToken: MOM_SLACK_APP_TOKEN,
|
||||
botToken: MOM_SLACK_BOT_TOKEN,
|
||||
workingDir,
|
||||
store: sharedStore,
|
||||
});
|
||||
|
||||
bot.start();
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { WebClient } from "@slack/web-api";
|
|||
import { appendFileSync, existsSync, mkdirSync, readFileSync } from "fs";
|
||||
import { basename, join } from "path";
|
||||
import * as log from "./log.js";
|
||||
import type { Attachment, ChannelStore } from "./store.js";
|
||||
|
||||
// ============================================================================
|
||||
// Types
|
||||
|
|
@ -14,7 +15,9 @@ export interface SlackEvent {
|
|||
ts: string;
|
||||
user: string;
|
||||
text: string;
|
||||
files?: Array<{ name: string; url_private_download?: string; url_private?: string }>;
|
||||
files?: Array<{ name?: string; url_private_download?: string; url_private?: string }>;
|
||||
/** Processed attachments with local paths (populated after logUserMessage) */
|
||||
attachments?: Attachment[];
|
||||
}
|
||||
|
||||
export interface SlackUser {
|
||||
|
|
@ -118,6 +121,7 @@ export class SlackBot {
|
|||
private webClient: WebClient;
|
||||
private handler: MomHandler;
|
||||
private workingDir: string;
|
||||
private store: ChannelStore;
|
||||
private botUserId: string | null = null;
|
||||
private startupTs: string | null = null; // Messages older than this are just logged, not processed
|
||||
|
||||
|
|
@ -125,9 +129,13 @@ export class SlackBot {
|
|||
private channels = new Map<string, SlackChannel>();
|
||||
private queues = new Map<string, ChannelQueue>();
|
||||
|
||||
constructor(handler: MomHandler, config: { appToken: string; botToken: string; workingDir: string }) {
|
||||
constructor(
|
||||
handler: MomHandler,
|
||||
config: { appToken: string; botToken: string; workingDir: string; store: ChannelStore },
|
||||
) {
|
||||
this.handler = handler;
|
||||
this.workingDir = config.workingDir;
|
||||
this.store = config.store;
|
||||
this.socketClient = new SocketModeClient({ appToken: config.appToken });
|
||||
this.webClient = new WebClient(config.botToken);
|
||||
}
|
||||
|
|
@ -258,7 +266,8 @@ export class SlackBot {
|
|||
};
|
||||
|
||||
// SYNC: Log to log.jsonl (ALWAYS, even for old messages)
|
||||
this.logUserMessage(slackEvent);
|
||||
// Also downloads attachments in background and stores local paths
|
||||
slackEvent.attachments = this.logUserMessage(slackEvent);
|
||||
|
||||
// Only trigger processing for messages AFTER startup (not replayed old messages)
|
||||
if (this.startupTs && e.ts < this.startupTs) {
|
||||
|
|
@ -336,7 +345,8 @@ export class SlackBot {
|
|||
};
|
||||
|
||||
// SYNC: Log to log.jsonl (ALL messages - channel chatter and DMs)
|
||||
this.logUserMessage(slackEvent);
|
||||
// Also downloads attachments in background and stores local paths
|
||||
slackEvent.attachments = this.logUserMessage(slackEvent);
|
||||
|
||||
// Only trigger processing for messages AFTER startup (not replayed old messages)
|
||||
if (this.startupTs && e.ts < this.startupTs) {
|
||||
|
|
@ -371,9 +381,12 @@ export class SlackBot {
|
|||
|
||||
/**
|
||||
* Log a user message to log.jsonl (SYNC)
|
||||
* Downloads attachments in background via store
|
||||
*/
|
||||
private logUserMessage(event: SlackEvent): void {
|
||||
private logUserMessage(event: SlackEvent): Attachment[] {
|
||||
const user = this.users.get(event.user);
|
||||
// Process attachments - queues downloads in background
|
||||
const attachments = event.files ? this.store.processAttachments(event.channel, event.files, event.ts) : [];
|
||||
this.logToFile(event.channel, {
|
||||
date: new Date(parseFloat(event.ts) * 1000).toISOString(),
|
||||
ts: event.ts,
|
||||
|
|
@ -381,9 +394,10 @@ export class SlackBot {
|
|||
userName: user?.userName,
|
||||
displayName: user?.displayName,
|
||||
text: event.text,
|
||||
attachments: event.files?.map((f) => f.name) || [],
|
||||
attachments,
|
||||
isBot: false,
|
||||
});
|
||||
return attachments;
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
|
|
@ -464,6 +478,8 @@ export class SlackBot {
|
|||
const user = this.users.get(msg.user!);
|
||||
// Strip @mentions from text (same as live messages)
|
||||
const text = (msg.text || "").replace(/<@[A-Z0-9]+>/gi, "").trim();
|
||||
// Process attachments - queues downloads in background
|
||||
const attachments = msg.files ? this.store.processAttachments(channelId, msg.files, msg.ts!) : [];
|
||||
|
||||
this.logToFile(channelId, {
|
||||
date: new Date(parseFloat(msg.ts!) * 1000).toISOString(),
|
||||
|
|
@ -472,7 +488,7 @@ export class SlackBot {
|
|||
userName: isMomMessage ? undefined : user?.userName,
|
||||
displayName: isMomMessage ? undefined : user?.displayName,
|
||||
text,
|
||||
attachments: msg.files?.map((f) => f.name) || [],
|
||||
attachments,
|
||||
isBot: isMomMessage,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue