← back to Designer Wallcoverings
DW-Agents/dw-agents/HOOKS-API-ARCHITECTURE.md
571 lines
# Shared Hooks API - Architecture & Integration
## System Architecture
```
┌─────────────────────────────────────────────────────────────────┐
│ DW-Agents Ecosystem │
└─────────────────────────────────────────────────────────────────┘
│
┌────────────┴────────────┐
│ │
┌───────────▼──────────┐ ┌──────────▼─────────┐
│ Agent 1 (9800) │ │ Agent 2 (9850) │
│ Marketing │ │ E-commerce │
├──────────────────────┤ ├────────────────────┤
│ import { hooks } │ │ import { hooks } │
│ setupHooksAPI(app) │ │ setupHooksAPI(app) │
└──────────┬───────────┘ └──────────┬─────────┘
│ │
└────────┬────────────────┘
│
┌────────▼─────────┐
│ shared-hooks- │
│ api.ts │
│ │
│ - setupHooksAPI │
│ - executeHook │
│ - hooks.* │
│ - HooksClient │
└────────┬─────────┘
│
┌─────────────────┼─────────────────┐
│ │ │
┌─────▼─────┐ ┌──────▼──────┐ ┌─────▼─────┐
│ Gmail │ │ Slack │ │ Shopify │
│ Hook │ │ Hook │ │ Hook │
└───────────┘ └─────────────┘ └───────────┘
│ │ │
┌────▼────┐ ┌─────▼─────┐ ┌────▼────┐
│ Gmail │ │ Slack │ │Shopify │
│ API │ │ API │ │ API │
└─────────┘ └───────────┘ └─────────┘
```
## Data Flow
### 1. REST API Flow
```
User Request
│
▼
┌─────────────────────────┐
│ POST /api/hooks/slack │
│ { params: {...} } │
└───────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ setupHooksAPI() │
│ - Parse request │
│ - Validate params │
│ - Build args string │
└───────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ executeHook() │
│ - Sanitize hook name │
│ - Build command │
│ - Execute with timeout │
└───────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ node slack-hook.js │
│ - Connect to Slack API │
│ - Send message │
│ - Return result │
└───────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ HookResult │
│ { │
│ success: true, │
│ output: "...", │
│ executionTime: 1234 │
│ } │
└─────────────────────────┘
```
### 2. Programmatic Flow
```
Agent Code
│
await hooks.slack.send('general', 'Hello')
│
▼
┌─────────────────────────┐
│ Convenience Wrapper │
│ hooks.slack.send() │
└───────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ executeHook() │
│ ('slack', 'send ...') │
└───────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ Hook Execution │
└───────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ Return HookResult │
└─────────────────────────┘
```
## Integration Patterns
### Pattern 1: Basic Integration
```typescript
// Minimal setup
import express from 'express';
import { setupHooksAPI } from '../shared-hooks-api';
const app = express();
app.use(express.json());
setupHooksAPI(app); // Done! REST API ready
app.listen(9800);
```
**Result:**
- GET /api/hooks (list all)
- POST /api/hooks/:hookName (execute any hook)
### Pattern 2: Programmatic Integration
```typescript
import { hooks, executeHook } from '../shared-hooks-api';
// In any route or function
app.post('/api/orders', async (req, res) => {
// Use convenience wrappers
await hooks.slack.send('orders', 'New order');
await hooks.gmail.send('team@co.com', 'Order', 'Details');
// Or direct execution
await executeHook('order-processing', req.body.id);
res.json({ success: true });
});
```
### Pattern 3: Type-Safe Client
```typescript
import { HooksClient } from '../shared-hooks-api';
const client = new HooksClient(60000);
// Full type safety and IntelliSense
await client.gmail('send', to, subject, body);
await client.healthCheck('web');
await client.notifyError('critical', 'Down');
```
### Pattern 4: Error Handling
```typescript
import { executeHook, hooks } from '../shared-hooks-api';
try {
await riskyOperation();
} catch (error) {
// Multi-channel error notification
await hooks.errors.notify('critical', error.message);
await hooks.slack.send('alerts', `ERROR: ${error.message}`);
await hooks.twilio.sms('+1234567890', 'ALERT: System error');
}
```
### Pattern 5: Health Monitoring
```typescript
import { HooksClient } from '../shared-hooks-api';
const client = new HooksClient();
setInterval(async () => {
const services = ['web', 'gmail', 'slack', 'shopify'];
for (const service of services) {
const result = await client.healthCheck(service);
if (!result.success) {
await client.notifyError('critical', `${service} down`);
}
}
}, 5 * 60 * 1000); // Every 5 minutes
```
## Module Structure
### Core Module (`shared-hooks-api.ts`)
```typescript
┌──────────────────────────────────────┐
│ shared-hooks-api.ts │
├──────────────────────────────────────┤
│ │
│ Interface HookResult │
│ - success: boolean │
│ - output?: string │
│ - error?: string │
│ - timestamp: string │
│ - executionTime?: number │
│ │
├──────────────────────────────────────┤
│ │
│ executeHook(name, args, timeout) │
│ - Sanitize hook name │
│ - Build command path │
│ - Execute with timeout │
│ - Return HookResult │
│ │
├──────────────────────────────────────┤
│ │
│ setupHooksAPI(app, basePath) │
│ - GET /api/hooks │
│ - GET /api/hooks/:hookName │
│ - POST /api/hooks/:hookName │
│ │
├──────────────────────────────────────┤
│ │
│ hooks { } │
│ - gmail { send, read, search } │
│ - slack { send, listChannels } │
│ - twilio { sms, call } │
│ - health { check, agents } │
│ - orders { process } │
│ - errors { notify } │
│ │
├──────────────────────────────────────┤
│ │
│ class HooksClient │
│ - execute(hook, args) │
│ - gmail(action, ...params) │
│ - slack(action, ...params) │
│ - healthCheck(service) │
│ - processOrder(id) │
│ - notifyError(severity, msg) │
│ │
└──────────────────────────────────────┘
```
## API Endpoints
### GET /api/hooks
```json
{
"success": true,
"hooks": {
"gmail": {
"description": "Gmail API operations",
"examples": ["send to@test.com 'Subject' 'Body'"]
},
"slack": { ... },
...
},
"usage": { ... }
}
```
### GET /api/hooks/:hookName
```json
{
"success": true,
"hook": "gmail",
"info": {
"description": "Gmail API operations",
"examples": [...]
}
}
```
### POST /api/hooks/:hookName
**Request:**
```json
{
"action": "send to@test.com 'Subject' 'Body'",
"timeout": 60000
}
```
**Or:**
```json
{
"params": {
"to": "test@test.com",
"subject": "Subject",
"body": "Body"
}
}
```
**Response:**
```json
{
"success": true,
"output": "Email sent successfully",
"timestamp": "2025-11-12T20:30:00.000Z",
"hookName": "gmail",
"executionTime": 1234
}
```
## Security Model
```
┌──────────────────────────────────┐
│ Agent Request │
└────────────┬─────────────────────┘
│
▼
┌──────────────────────────────────┐
│ Agent Authentication │
│ (requireAuth middleware) │
└────────────┬─────────────────────┘
│
▼
┌──────────────────────────────────┐
│ Rate Limiting │
│ (express-rate-limit) │
└────────────┬─────────────────────┘
│
▼
┌──────────────────────────────────┐
│ shared-hooks-api │
│ - Input sanitization │
│ - Hook name validation │
│ - Timeout protection │
└────────────┬─────────────────────┘
│
▼
┌──────────────────────────────────┐
│ Hook Execution │
│ (sandboxed child process) │
└────────────┬─────────────────────┘
│
▼
┌──────────────────────────────────┐
│ Result with execution metrics │
└──────────────────────────────────┘
```
## Performance Characteristics
| Metric | Value | Notes |
|--------|-------|-------|
| Function Call Overhead | <5ms | Negligible |
| Hook Execution | Varies | Depends on hook and external API |
| Default Timeout | 60s | Configurable per call |
| Max Buffer | 10MB | For hook output |
| Concurrent Calls | Unlimited | No artificial limits |
| Memory Footprint | Minimal | Stateless design |
## Migration Path
### Phase 1: Add Module (No Breaking Changes)
```typescript
// Keep existing code
// Add new module alongside
import { setupHooksAPI } from '../shared-hooks-api';
setupHooksAPI(app);
```
### Phase 2: Start Using (Gradual)
```typescript
// Replace one function at a time
// OLD:
await sendSlackMessage('general', 'Hello');
// NEW:
await hooks.slack.send('general', 'Hello');
```
### Phase 3: Full Migration
```typescript
// Remove all old hook code
// Use only shared-hooks-api
import { hooks } from '../shared-hooks-api';
```
### Phase 4: Cleanup
```typescript
// Delete old helper functions
// Update documentation
// Verify all agents use new module
```
## Testing Strategy
### Unit Tests
```typescript
describe('executeHook', () => {
it('should execute valid hook', async () => {
const result = await executeHook('slack', 'send general "Test"');
expect(result.success).toBe(true);
});
it('should handle errors', async () => {
const result = await executeHook('invalid', 'args');
expect(result.success).toBe(false);
expect(result.error).toBeDefined();
});
it('should timeout long operations', async () => {
const result = await executeHook('slow-hook', '', 100);
expect(result.success).toBe(false);
});
});
```
### Integration Tests
```bash
# Test REST API
curl http://localhost:9800/api/hooks
# Test hook execution
curl -X POST http://localhost:9800/api/hooks/slack \
-d '{"params": {"channel": "test", "message": "Test"}}'
# Test error handling
curl -X POST http://localhost:9800/api/hooks/invalid
```
### End-to-End Tests
```typescript
// Test full workflow
app.post('/test/workflow', async (req, res) => {
// 1. Process order
const order = await hooks.orders.process(req.body.id);
// 2. Notify team
await hooks.slack.send('orders', `Order ${req.body.id}`);
// 3. Email customer
await hooks.gmail.send(req.body.email, 'Confirmed', 'Details');
// 4. Update agents
await executeHook('inter-agent-chat', `broadcast "Order processed"`);
res.json({ success: true });
});
```
## Monitoring & Observability
### Built-in Logging
```javascript
[Hooks API] Executing: node /root/DW-MCP/DW-Hooks/slack-hook.js send general "Hello"
[Hooks API] Success: 1234ms
```
### Metrics to Track
- Hook execution count per hook
- Average execution time per hook
- Success/failure rate
- Timeout frequency
- Error patterns
### Dashboard Integration
```typescript
app.get('/api/hooks/metrics', (req, res) => {
res.json({
totalExecutions: 12345,
successRate: 0.98,
avgExecutionTime: 1234,
topHooks: [
{ name: 'slack', count: 5000 },
{ name: 'gmail', count: 3000 },
{ name: 'order-processing', count: 2000 }
]
});
});
```
## Best Practices
### 1. Always Handle Errors
```typescript
const result = await executeHook('gmail', '...');
if (!result.success) {
await hooks.errors.notify('high', `Failed: ${result.error}`);
}
```
### 2. Use Convenience Wrappers
```typescript
// Good
await hooks.slack.send('general', 'Hello');
// Okay
await executeHook('slack', 'send general "Hello"');
```
### 3. Set Appropriate Timeouts
```typescript
// Short timeout for fast operations
await executeHook('health-check', 'web', 5000);
// Long timeout for complex operations
await executeHook('product-import', 'large-file', 300000);
```
### 4. Add Rate Limiting
```typescript
import rateLimit from 'express-rate-limit';
app.use('/api/hooks', rateLimit({
windowMs: 60000,
max: 30
}));
```
### 5. Protect Endpoints
```typescript
app.use('/api/hooks', requireAuth);
setupHooksAPI(app);
```
## Troubleshooting Guide
| Symptom | Cause | Solution |
|---------|-------|----------|
| "Hook not found" | Typo in hook name | Check spelling, use GET /api/hooks |
| Timeout errors | Slow operation | Increase timeout parameter |
| Permission denied | Not executable | chmod +x hooks/*.js |
| Module not found | Missing deps | npm install |
| Type errors | Wrong import | Use correct import path |
| Empty output | Hook failed silently | Check hook's own logs |
---
**Last Updated:** 2025-11-12
**Version:** 1.0.0
**Status:** Production Ready