-
Notifications
You must be signed in to change notification settings - Fork 0
Architecture
Mundo edited this page Apr 7, 2026
·
2 revisions
Oh My Workers uses a multi-agent architecture powered by LangChain and Claude. Each task is handled by a chain of specialized agents, each with a single responsibility.
| Layer | Technology |
|---|---|
| Runtime | Node.js + TypeScript |
| AI Framework | LangChain + LangGraph |
| LLM | Claude Sonnet (via @langchain/anthropic) |
| Database | PostgreSQL (Neon) via pg
|
| News Search | Tavily API (@tavily/core) |
| Messaging | Telegram Bot API |
Gmail SMTP via nodemailer
|
|
| Scheduling |
node-cron / GitHub Actions |
| Validation | Zod |
src/
├── agent/
│ ├── index.ts # WorkCoordinator — orchestrates all agents
│ ├── prompt.ts # System prompts for all agents
│ ├── cleanup.agent.ts # Stale record deletion
│ ├── github.agent.ts # GitHub activity fetching
│ ├── manual-kpi.agent.ts # Interactive KPI input
│ ├── diary.agent.ts # KPI report generation
│ ├── news-search.agent.ts # Tavily AI news search
│ ├── news-curator.agent.ts # LLM-powered news curation
│ └── news-telegram.agent.ts # Telegram news delivery
├── tools/ # DynamicStructuredTool implementations
│ ├── news-search.tool.ts # Tavily search integration
│ ├── news-curator.tool.ts # Article curation logic
│ ├── news-telegram.tool.ts # Telegram message formatting
│ └── ... # GitHub, cleanup, diary tools
├── storage/
│ ├── own-db.ts # Main DB: kpi, diary, cleanup_log, ai_news
│ └── company-db.ts # Company DB: stale record cleanup
├── schemas/index.ts # Zod type definitions
├── jobs/scheduler.ts # node-cron configuration
├── constants/index.ts # Config values
├── utils/logger.ts # Logging helpers
└── index.ts # Entry point + CLI flags
.github/workflows/
├── cleanup.yml # Daily 5pm cleanup
├── daily-kpi.yml # Manual KPI trigger (workflow_dispatch)
├── seed-mock-users.yml # Daily 4:30pm mock data seeding
└── morning-quiz.yml # Daily 8am AI news digest
Each agent follows the same pattern:
- Agent — LangChain agent with a specific system prompt and one tool
-
Tool —
DynamicStructuredToolwith a Zod schema defining inputs/outputs - Prompt — focused system prompt that tells the LLM exactly what to do
// Example: news search agent
const llm = new ChatAnthropic({ model: DEFAULT_LLM, temperature: 0 })
export const newsSearchAgent = createAgent({
model: llm,
tools: [newsSearchTool],
systemPrompt: NEWS_SEARCH_PROMPT,
middleware: [toolCallLimitMiddleware({ runLimit: 1, exitBehavior: 'end' })],
})The toolCallLimitMiddleware ensures each agent makes exactly one tool call and exits — keeping costs predictable.
The WorkCoordinator class in src/agent/index.ts orchestrates multi-step pipelines:
- Runs agents sequentially when outputs feed into the next step
- Runs agents in parallel (via
Promise.allSettled) when independent - Handles errors gracefully — one agent failing doesn't crash the pipeline
- Sends Telegram alerts on failures
-
Promise.allSettled()for parallel operations (independent failures don't cancel each other) - Telegram error notifications for critical failures
- Parse error retry logic with configurable limits
- DB connection cleanup on exit