mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-21 12:00:15 +00:00
mom: Slack bot with abort support, streaming console output, removed sandbox
This commit is contained in:
parent
a7423b954e
commit
aa9e058249
22 changed files with 2741 additions and 58 deletions
98
packages/mom/src/main.ts
Normal file
98
packages/mom/src/main.ts
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
import { join, resolve } from "path";
|
||||
import { type AgentRunner, createAgentRunner } from "./agent.js";
|
||||
import { MomBot, type SlackContext } from "./slack.js";
|
||||
|
||||
console.log("Starting mom bot...");
|
||||
|
||||
const MOM_SLACK_APP_TOKEN = process.env.MOM_SLACK_APP_TOKEN;
|
||||
const MOM_SLACK_BOT_TOKEN = process.env.MOM_SLACK_BOT_TOKEN;
|
||||
const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
|
||||
const ANTHROPIC_OAUTH_TOKEN = process.env.ANTHROPIC_OAUTH_TOKEN;
|
||||
|
||||
// Parse command line arguments
|
||||
const args = process.argv.slice(2);
|
||||
if (args.length !== 1) {
|
||||
console.error("Usage: mom <working-directory>");
|
||||
console.error("Example: mom ./mom-data");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const workingDir = resolve(args[0]);
|
||||
|
||||
if (!MOM_SLACK_APP_TOKEN || !MOM_SLACK_BOT_TOKEN || (!ANTHROPIC_API_KEY && !ANTHROPIC_OAUTH_TOKEN)) {
|
||||
console.error("Missing required environment variables:");
|
||||
if (!MOM_SLACK_APP_TOKEN) console.error(" - MOM_SLACK_APP_TOKEN (xapp-...)");
|
||||
if (!MOM_SLACK_BOT_TOKEN) console.error(" - MOM_SLACK_BOT_TOKEN (xoxb-...)");
|
||||
if (!ANTHROPIC_API_KEY && !ANTHROPIC_OAUTH_TOKEN) console.error(" - ANTHROPIC_API_KEY or ANTHROPIC_OAUTH_TOKEN");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Track active agent runs per channel
|
||||
const activeRuns = new Map<string, AgentRunner>();
|
||||
|
||||
async function handleMessage(ctx: SlackContext, source: "channel" | "dm"): Promise<void> {
|
||||
const channelId = ctx.message.channel;
|
||||
const messageText = ctx.message.text.toLowerCase().trim();
|
||||
|
||||
// Check for stop command
|
||||
if (messageText === "stop") {
|
||||
const runner = activeRuns.get(channelId);
|
||||
if (runner) {
|
||||
console.log(`Stop requested for channel ${channelId}`);
|
||||
runner.abort();
|
||||
await ctx.respond("_Stopping..._");
|
||||
} else {
|
||||
await ctx.respond("_Nothing running._");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if already running in this channel
|
||||
if (activeRuns.has(channelId)) {
|
||||
await ctx.respond("_Already working on something. Say `@mom stop` to cancel._");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`${source === "channel" ? "Channel mention" : "DM"} from <@${ctx.message.user}>: ${ctx.message.text}`);
|
||||
const channelDir = join(workingDir, channelId);
|
||||
|
||||
const runner = createAgentRunner();
|
||||
activeRuns.set(channelId, runner);
|
||||
|
||||
await ctx.setTyping(true);
|
||||
try {
|
||||
await runner.run(ctx, channelDir, ctx.store);
|
||||
} catch (error) {
|
||||
// Don't report abort errors
|
||||
const msg = error instanceof Error ? error.message : String(error);
|
||||
if (msg.includes("aborted") || msg.includes("Aborted")) {
|
||||
// Already said "Stopping..." - nothing more to say
|
||||
} else {
|
||||
console.error("Agent error:", error);
|
||||
await ctx.respond(`❌ Error: ${msg}`);
|
||||
}
|
||||
} finally {
|
||||
activeRuns.delete(channelId);
|
||||
}
|
||||
}
|
||||
|
||||
const bot = new MomBot(
|
||||
{
|
||||
async onChannelMention(ctx) {
|
||||
await handleMessage(ctx, "channel");
|
||||
},
|
||||
|
||||
async onDirectMessage(ctx) {
|
||||
await handleMessage(ctx, "dm");
|
||||
},
|
||||
},
|
||||
{
|
||||
appToken: MOM_SLACK_APP_TOKEN,
|
||||
botToken: MOM_SLACK_BOT_TOKEN,
|
||||
workingDir,
|
||||
},
|
||||
);
|
||||
|
||||
bot.start();
|
||||
Loading…
Add table
Add a link
Reference in a new issue