mirror of
https://github.com/KeygraphHQ/shannon.git
synced 2026-07-05 04:38:03 +02:00
c12eca046c
- Fix save_deliverable race condition using closure pattern instead of global variable - Fix error classification order so OutputValidationError matches before generic validation - Fix ApplicationFailure re-classification bug by checking instanceof before re-throwing - Add per-error-type retry limits (3 for output validation, 50 for billing) - Add fast retry intervals for pipeline testing mode (10s vs 5min) - Increase worker concurrent activities to 25 for parallel workflows
80 lines
2.3 KiB
JavaScript
80 lines
2.3 KiB
JavaScript
#!/usr/bin/env node
|
||
// Copyright (C) 2025 Keygraph, Inc.
|
||
//
|
||
// This program is free software: you can redistribute it and/or modify
|
||
// it under the terms of the GNU Affero General Public License version 3
|
||
// as published by the Free Software Foundation.
|
||
|
||
/**
|
||
* Temporal worker for Shannon pentest pipeline.
|
||
*
|
||
* Polls the 'shannon-pipeline' task queue and executes activities.
|
||
* Handles up to 25 concurrent activities to support multiple parallel workflows.
|
||
*
|
||
* Usage:
|
||
* npm run temporal:worker
|
||
* # or
|
||
* node dist/temporal/worker.js
|
||
*
|
||
* Environment:
|
||
* TEMPORAL_ADDRESS - Temporal server address (default: localhost:7233)
|
||
*/
|
||
|
||
import { NativeConnection, Worker, bundleWorkflowCode } from '@temporalio/worker';
|
||
import { fileURLToPath } from 'node:url';
|
||
import path from 'node:path';
|
||
import dotenv from 'dotenv';
|
||
import chalk from 'chalk';
|
||
import * as activities from './activities.js';
|
||
|
||
dotenv.config();
|
||
|
||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||
|
||
async function runWorker(): Promise<void> {
|
||
const address = process.env.TEMPORAL_ADDRESS || 'localhost:7233';
|
||
console.log(chalk.cyan(`Connecting to Temporal at ${address}...`));
|
||
|
||
const connection = await NativeConnection.connect({ address });
|
||
|
||
// Bundle workflows for Temporal's V8 isolate
|
||
console.log(chalk.gray('Bundling workflows...'));
|
||
const workflowBundle = await bundleWorkflowCode({
|
||
workflowsPath: path.join(__dirname, 'workflows.js'),
|
||
});
|
||
|
||
const worker = await Worker.create({
|
||
connection,
|
||
namespace: 'default',
|
||
workflowBundle,
|
||
activities,
|
||
taskQueue: 'shannon-pipeline',
|
||
maxConcurrentActivityTaskExecutions: 25, // Support multiple parallel workflows (5 agents × ~5 workflows)
|
||
});
|
||
|
||
// Graceful shutdown handling
|
||
const shutdown = async (): Promise<void> => {
|
||
console.log(chalk.yellow('\nShutting down worker...'));
|
||
worker.shutdown();
|
||
};
|
||
|
||
process.on('SIGINT', shutdown);
|
||
process.on('SIGTERM', shutdown);
|
||
|
||
console.log(chalk.green('Shannon worker started'));
|
||
console.log(chalk.gray('Task queue: shannon-pipeline'));
|
||
console.log(chalk.gray('Press Ctrl+C to stop\n'));
|
||
|
||
try {
|
||
await worker.run();
|
||
} finally {
|
||
await connection.close();
|
||
console.log(chalk.gray('Worker stopped'));
|
||
}
|
||
}
|
||
|
||
runWorker().catch((err) => {
|
||
console.error(chalk.red('Worker failed:'), err);
|
||
process.exit(1);
|
||
});
|