testchimp-runner-core 0.0.21 → 0.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/VISION_DIAGNOSTICS_IMPROVEMENTS.md +336 -0
- package/dist/credit-usage-service.d.ts +9 -0
- package/dist/credit-usage-service.d.ts.map +1 -1
- package/dist/credit-usage-service.js +20 -5
- package/dist/credit-usage-service.js.map +1 -1
- package/dist/execution-service.d.ts +7 -2
- package/dist/execution-service.d.ts.map +1 -1
- package/dist/execution-service.js +91 -36
- package/dist/execution-service.js.map +1 -1
- package/dist/index.d.ts +30 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +91 -26
- package/dist/index.js.map +1 -1
- package/dist/llm-facade.d.ts +64 -8
- package/dist/llm-facade.d.ts.map +1 -1
- package/dist/llm-facade.js +361 -109
- package/dist/llm-facade.js.map +1 -1
- package/dist/llm-provider.d.ts +39 -0
- package/dist/llm-provider.d.ts.map +1 -0
- package/dist/llm-provider.js +7 -0
- package/dist/llm-provider.js.map +1 -0
- package/dist/model-constants.d.ts +21 -0
- package/dist/model-constants.d.ts.map +1 -0
- package/dist/model-constants.js +24 -0
- package/dist/model-constants.js.map +1 -0
- package/dist/orchestrator/index.d.ts +8 -0
- package/dist/orchestrator/index.d.ts.map +1 -0
- package/dist/orchestrator/index.js +23 -0
- package/dist/orchestrator/index.js.map +1 -0
- package/dist/orchestrator/orchestrator-agent.d.ts +66 -0
- package/dist/orchestrator/orchestrator-agent.d.ts.map +1 -0
- package/dist/orchestrator/orchestrator-agent.js +855 -0
- package/dist/orchestrator/orchestrator-agent.js.map +1 -0
- package/dist/orchestrator/tool-registry.d.ts +74 -0
- package/dist/orchestrator/tool-registry.d.ts.map +1 -0
- package/dist/orchestrator/tool-registry.js +131 -0
- package/dist/orchestrator/tool-registry.js.map +1 -0
- package/dist/orchestrator/tools/check-page-ready.d.ts +13 -0
- package/dist/orchestrator/tools/check-page-ready.d.ts.map +1 -0
- package/dist/orchestrator/tools/check-page-ready.js +72 -0
- package/dist/orchestrator/tools/check-page-ready.js.map +1 -0
- package/dist/orchestrator/tools/extract-data.d.ts +13 -0
- package/dist/orchestrator/tools/extract-data.d.ts.map +1 -0
- package/dist/orchestrator/tools/extract-data.js +84 -0
- package/dist/orchestrator/tools/extract-data.js.map +1 -0
- package/dist/orchestrator/tools/index.d.ts +10 -0
- package/dist/orchestrator/tools/index.d.ts.map +1 -0
- package/dist/orchestrator/tools/index.js +18 -0
- package/dist/orchestrator/tools/index.js.map +1 -0
- package/dist/orchestrator/tools/inspect-page.d.ts +13 -0
- package/dist/orchestrator/tools/inspect-page.d.ts.map +1 -0
- package/dist/orchestrator/tools/inspect-page.js +39 -0
- package/dist/orchestrator/tools/inspect-page.js.map +1 -0
- package/dist/orchestrator/tools/recall-history.d.ts +13 -0
- package/dist/orchestrator/tools/recall-history.d.ts.map +1 -0
- package/dist/orchestrator/tools/recall-history.js +64 -0
- package/dist/orchestrator/tools/recall-history.js.map +1 -0
- package/dist/orchestrator/tools/take-screenshot.d.ts +15 -0
- package/dist/orchestrator/tools/take-screenshot.d.ts.map +1 -0
- package/dist/orchestrator/tools/take-screenshot.js +112 -0
- package/dist/orchestrator/tools/take-screenshot.js.map +1 -0
- package/dist/orchestrator/types.d.ts +133 -0
- package/dist/orchestrator/types.d.ts.map +1 -0
- package/dist/orchestrator/types.js +28 -0
- package/dist/orchestrator/types.js.map +1 -0
- package/dist/playwright-mcp-service.d.ts +9 -0
- package/dist/playwright-mcp-service.d.ts.map +1 -1
- package/dist/playwright-mcp-service.js +20 -5
- package/dist/playwright-mcp-service.js.map +1 -1
- package/dist/progress-reporter.d.ts +97 -0
- package/dist/progress-reporter.d.ts.map +1 -0
- package/dist/progress-reporter.js +18 -0
- package/dist/progress-reporter.js.map +1 -0
- package/dist/prompts.d.ts +24 -0
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +593 -68
- package/dist/prompts.js.map +1 -1
- package/dist/providers/backend-proxy-llm-provider.d.ts +25 -0
- package/dist/providers/backend-proxy-llm-provider.d.ts.map +1 -0
- package/dist/providers/backend-proxy-llm-provider.js +76 -0
- package/dist/providers/backend-proxy-llm-provider.js.map +1 -0
- package/dist/providers/local-llm-provider.d.ts +21 -0
- package/dist/providers/local-llm-provider.d.ts.map +1 -0
- package/dist/providers/local-llm-provider.js +35 -0
- package/dist/providers/local-llm-provider.js.map +1 -0
- package/dist/scenario-service.d.ts +27 -1
- package/dist/scenario-service.d.ts.map +1 -1
- package/dist/scenario-service.js +48 -12
- package/dist/scenario-service.js.map +1 -1
- package/dist/scenario-worker-class.d.ts +39 -2
- package/dist/scenario-worker-class.d.ts.map +1 -1
- package/dist/scenario-worker-class.js +614 -86
- package/dist/scenario-worker-class.js.map +1 -1
- package/dist/script-utils.d.ts +2 -0
- package/dist/script-utils.d.ts.map +1 -1
- package/dist/script-utils.js +44 -4
- package/dist/script-utils.js.map +1 -1
- package/dist/types.d.ts +11 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/browser-utils.d.ts +20 -1
- package/dist/utils/browser-utils.d.ts.map +1 -1
- package/dist/utils/browser-utils.js +102 -51
- package/dist/utils/browser-utils.js.map +1 -1
- package/dist/utils/page-info-utils.d.ts +23 -4
- package/dist/utils/page-info-utils.d.ts.map +1 -1
- package/dist/utils/page-info-utils.js +174 -43
- package/dist/utils/page-info-utils.js.map +1 -1
- package/package.json +1 -2
- package/plandocs/HUMAN_LIKE_IMPROVEMENTS.md +642 -0
- package/plandocs/MULTI_AGENT_ARCHITECTURE_REVIEW.md +844 -0
- package/plandocs/ORCHESTRATOR_MVP_SUMMARY.md +539 -0
- package/plandocs/PHASE1_ABSTRACTION_COMPLETE.md +241 -0
- package/plandocs/PHASE1_FINAL_STATUS.md +210 -0
- package/plandocs/PLANNING_SESSION_SUMMARY.md +372 -0
- package/plandocs/SCRIPT_CLEANUP_FEATURE.md +201 -0
- package/plandocs/SCRIPT_GENERATION_ARCHITECTURE.md +364 -0
- package/plandocs/SELECTOR_IMPROVEMENTS.md +139 -0
- package/src/credit-usage-service.ts +23 -5
- package/src/execution-service.ts +152 -42
- package/src/index.ts +169 -26
- package/src/llm-facade.ts +500 -126
- package/src/llm-provider.ts +43 -0
- package/src/model-constants.ts +23 -0
- package/src/orchestrator/index.ts +33 -0
- package/src/orchestrator/orchestrator-agent.ts +1037 -0
- package/src/orchestrator/tool-registry.ts +182 -0
- package/src/orchestrator/tools/check-page-ready.ts +75 -0
- package/src/orchestrator/tools/extract-data.ts +92 -0
- package/src/orchestrator/tools/index.ts +11 -0
- package/src/orchestrator/tools/inspect-page.ts +42 -0
- package/src/orchestrator/tools/recall-history.ts +72 -0
- package/src/orchestrator/tools/take-screenshot.ts +128 -0
- package/src/orchestrator/types.ts +200 -0
- package/src/playwright-mcp-service.ts +23 -5
- package/src/progress-reporter.ts +109 -0
- package/src/prompts.ts +606 -69
- package/src/providers/backend-proxy-llm-provider.ts +91 -0
- package/src/providers/local-llm-provider.ts +38 -0
- package/src/scenario-service.ts +83 -13
- package/src/scenario-worker-class.ts +740 -72
- package/src/script-utils.ts +50 -5
- package/src/types.ts +13 -1
- package/src/utils/browser-utils.ts +123 -51
- package/src/utils/page-info-utils.ts +210 -53
- package/testchimp-runner-core-0.0.22.tgz +0 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backend Proxy LLM Provider
|
|
3
|
+
* Calls backend proxy API with authentication
|
|
4
|
+
* Used by VS Extension and GitHub Runner
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import axios from 'axios';
|
|
8
|
+
import { LLMProvider, LLMRequest, LLMResponse } from '../llm-provider';
|
|
9
|
+
import { AuthConfig, getAuthHeaders } from '../auth-config';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Default LLM provider that calls backend proxy
|
|
13
|
+
* Converts camelCase requests to snake_case for backend API
|
|
14
|
+
*/
|
|
15
|
+
export class BackendProxyLLMProvider implements LLMProvider {
|
|
16
|
+
private authConfig?: AuthConfig;
|
|
17
|
+
private backendUrl: string;
|
|
18
|
+
private logger?: (message: string, level?: 'log' | 'error' | 'warn') => void;
|
|
19
|
+
|
|
20
|
+
constructor(authConfig?: AuthConfig, backendUrl?: string) {
|
|
21
|
+
this.authConfig = authConfig;
|
|
22
|
+
this.backendUrl = backendUrl || 'https://featureservice.testchimp.io';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
setLogger(logger: (message: string, level?: 'log' | 'error' | 'warn') => void): void {
|
|
26
|
+
this.logger = logger;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async callLLM(request: LLMRequest): Promise<LLMResponse> {
|
|
30
|
+
if (!this.authConfig) {
|
|
31
|
+
throw new Error('Authentication required for backend proxy LLM provider');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const headers = getAuthHeaders(this.authConfig);
|
|
35
|
+
|
|
36
|
+
// Convert camelCase to snake_case for backend API (proto format)
|
|
37
|
+
const backendRequest = {
|
|
38
|
+
model: request.model,
|
|
39
|
+
system_prompt: request.systemPrompt,
|
|
40
|
+
user_prompt: request.userPrompt,
|
|
41
|
+
image_url: request.imageUrl
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const url = `${this.backendUrl}/localagent/call_llm`;
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
const response = await axios.post(
|
|
48
|
+
url,
|
|
49
|
+
backendRequest,
|
|
50
|
+
{ headers, timeout: 300000 }
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
// Calculate token usage (heuristic: 4 chars = 1 token)
|
|
54
|
+
const inputText = `${request.systemPrompt || ''}\n${request.userPrompt || ''}`;
|
|
55
|
+
const inputTokens = Math.ceil(inputText.length / 4);
|
|
56
|
+
|
|
57
|
+
// Add image tokens if present (for vision models)
|
|
58
|
+
let imageTokens = 0;
|
|
59
|
+
if (request.imageUrl) {
|
|
60
|
+
imageTokens = this.estimateImageTokens(request.imageUrl);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const outputTokens = Math.ceil((response.data.answer || '').length / 4);
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
answer: response.data.answer,
|
|
67
|
+
usage: {
|
|
68
|
+
inputTokens: inputTokens + imageTokens,
|
|
69
|
+
outputTokens
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
} catch (error: any) {
|
|
73
|
+
this.logger?.(`LLM call failed: ${error}`, 'error');
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Estimate image token cost based on dimensions
|
|
80
|
+
* For gpt-4.1-mini: patches × 1.62, capped at 1536
|
|
81
|
+
*/
|
|
82
|
+
private estimateImageTokens(imageDataUrl: string): number {
|
|
83
|
+
// For simplicity, estimate common screenshot sizes
|
|
84
|
+
// Viewport (1920x1080): ~1452 tokens (after multiplier and cap)
|
|
85
|
+
// Full page (1920x3000+): ~1536 tokens (capped)
|
|
86
|
+
|
|
87
|
+
// Conservative estimate: assume viewport screenshot
|
|
88
|
+
return 1500; // ~1452-1536 tokens for typical screenshot
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local LLM Provider
|
|
3
|
+
* Calls LLM directly via callback (not via backend proxy)
|
|
4
|
+
* For future use by Script Service (Phase 2)
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { LLMProvider, LLMRequest, LLMResponse } from '../llm-provider';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Local LLM provider that calls LLM directly via callback
|
|
11
|
+
* Allows Script Service to use its own OpenAI integration
|
|
12
|
+
*/
|
|
13
|
+
export class LocalLLMProvider implements LLMProvider {
|
|
14
|
+
private llmCallback: (request: LLMRequest) => Promise<string>;
|
|
15
|
+
private logger?: (message: string, level?: 'log' | 'error' | 'warn') => void;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param llmCallback Function that calls LLM (provided by environment)
|
|
19
|
+
*/
|
|
20
|
+
constructor(llmCallback: (request: LLMRequest) => Promise<string>) {
|
|
21
|
+
this.llmCallback = llmCallback;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
setLogger(logger: (message: string, level?: 'log' | 'error' | 'warn') => void): void {
|
|
25
|
+
this.logger = logger;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async callLLM(request: LLMRequest): Promise<LLMResponse> {
|
|
29
|
+
try {
|
|
30
|
+
const answer = await this.llmCallback(request);
|
|
31
|
+
return { answer };
|
|
32
|
+
} catch (error) {
|
|
33
|
+
this.logger?.(`Local LLM call failed: ${error}`, 'error');
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
package/src/scenario-service.ts
CHANGED
|
@@ -5,6 +5,9 @@ import { ScenarioWorker } from './scenario-worker-class';
|
|
|
5
5
|
import { FileHandler, NoOpFileHandler } from './file-handler';
|
|
6
6
|
import { AuthConfig } from './auth-config';
|
|
7
7
|
import { CreditUsageService } from './credit-usage-service';
|
|
8
|
+
import { LLMProvider } from './llm-provider';
|
|
9
|
+
import { ProgressReporter } from './progress-reporter';
|
|
10
|
+
import { AgentConfig } from './orchestrator';
|
|
8
11
|
|
|
9
12
|
// Load environment variables
|
|
10
13
|
dotenv.config();
|
|
@@ -21,14 +24,62 @@ export class ScenarioService extends EventEmitter {
|
|
|
21
24
|
private authConfig: AuthConfig | null;
|
|
22
25
|
private backendUrl?: string;
|
|
23
26
|
private creditUsageService: CreditUsageService;
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
private logger?: (message: string, level?: 'log' | 'error' | 'warn') => void;
|
|
28
|
+
private llmProvider?: LLMProvider;
|
|
29
|
+
private progressReporter?: ProgressReporter;
|
|
30
|
+
private useOrchestrator: boolean;
|
|
31
|
+
private orchestratorConfig?: Partial<AgentConfig>;
|
|
32
|
+
private debugMode: boolean;
|
|
33
|
+
private outputChannel?: any; // VS Code OutputChannel type
|
|
34
|
+
|
|
35
|
+
constructor(
|
|
36
|
+
maxWorkers: number = 2,
|
|
37
|
+
fileHandler?: FileHandler,
|
|
38
|
+
llmProvider?: LLMProvider,
|
|
39
|
+
progressReporter?: ProgressReporter,
|
|
40
|
+
authConfig?: AuthConfig,
|
|
41
|
+
backendUrl?: string,
|
|
42
|
+
options?: {
|
|
43
|
+
useOrchestrator?: boolean;
|
|
44
|
+
orchestratorConfig?: Partial<AgentConfig>;
|
|
45
|
+
debugMode?: boolean;
|
|
46
|
+
}
|
|
47
|
+
) {
|
|
26
48
|
super();
|
|
27
49
|
this.maxWorkers = maxWorkers;
|
|
28
50
|
this.fileHandler = fileHandler || new NoOpFileHandler();
|
|
51
|
+
this.llmProvider = llmProvider;
|
|
52
|
+
this.progressReporter = progressReporter;
|
|
29
53
|
this.authConfig = authConfig || null;
|
|
30
54
|
this.backendUrl = backendUrl;
|
|
31
55
|
this.creditUsageService = new CreditUsageService(authConfig, backendUrl);
|
|
56
|
+
this.useOrchestrator = options?.useOrchestrator || false;
|
|
57
|
+
this.orchestratorConfig = options?.orchestratorConfig;
|
|
58
|
+
this.debugMode = options?.debugMode || false;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Set a logger callback for capturing execution logs
|
|
63
|
+
*/
|
|
64
|
+
setLogger(logger: (message: string, level?: 'log' | 'error' | 'warn') => void): void {
|
|
65
|
+
this.logger = logger;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Set output channel for worker logs (VS Code OutputChannel)
|
|
70
|
+
*/
|
|
71
|
+
setOutputChannel(outputChannel: any): void {
|
|
72
|
+
this.outputChannel = outputChannel;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Log a message using the configured logger
|
|
77
|
+
*/
|
|
78
|
+
private log(message: string, level: 'log' | 'error' | 'warn' = 'log'): void {
|
|
79
|
+
if (this.logger) {
|
|
80
|
+
this.logger(message, level);
|
|
81
|
+
}
|
|
82
|
+
// No console fallback - logs are routed to consumer
|
|
32
83
|
}
|
|
33
84
|
|
|
34
85
|
private async initializeWorkers(): Promise<void> {
|
|
@@ -38,16 +89,35 @@ export class ScenarioService extends EventEmitter {
|
|
|
38
89
|
}
|
|
39
90
|
|
|
40
91
|
private async createWorker(): Promise<void> {
|
|
41
|
-
|
|
92
|
+
// Pass providers and orchestrator options to worker
|
|
93
|
+
const worker = new ScenarioWorker(
|
|
94
|
+
this.fileHandler,
|
|
95
|
+
this.llmProvider,
|
|
96
|
+
this.progressReporter,
|
|
97
|
+
this.authConfig || undefined,
|
|
98
|
+
this.backendUrl,
|
|
99
|
+
{
|
|
100
|
+
useOrchestrator: this.useOrchestrator,
|
|
101
|
+
orchestratorConfig: this.orchestratorConfig,
|
|
102
|
+
debugMode: this.debugMode
|
|
103
|
+
},
|
|
104
|
+
this.outputChannel // Pass outputChannel for log routing
|
|
105
|
+
);
|
|
42
106
|
await worker.initialize();
|
|
107
|
+
|
|
108
|
+
// Forward log events from worker to service listeners
|
|
109
|
+
worker.on('log', (jobId: string, message: string) => {
|
|
110
|
+
this.emit('jobLog', jobId, message);
|
|
111
|
+
});
|
|
112
|
+
|
|
43
113
|
this.workers.push(worker);
|
|
44
|
-
|
|
114
|
+
this.log(`Scenario worker initialized${this.useOrchestrator ? ' (Orchestrator Mode)' : ''} with session: ${worker['sessionId']}`);
|
|
45
115
|
}
|
|
46
116
|
|
|
47
117
|
async initialize(): Promise<void> {
|
|
48
118
|
// Wait for workers to be initialized
|
|
49
119
|
await this.initializeWorkers();
|
|
50
|
-
|
|
120
|
+
this.log('Scenario service initialized');
|
|
51
121
|
}
|
|
52
122
|
|
|
53
123
|
processScenario(scenario: string, testName?: string, config?: PlaywrightConfig, model?: string, scenarioFileName?: string): string {
|
|
@@ -74,12 +144,12 @@ export class ScenarioService extends EventEmitter {
|
|
|
74
144
|
return;
|
|
75
145
|
}
|
|
76
146
|
|
|
77
|
-
|
|
147
|
+
this.log(`[ScenarioService] Processing next job. Queue length: ${this.jobQueue.length}, Workers: ${this.workers.length}, Busy workers: ${this.busyWorkers.size}`);
|
|
78
148
|
|
|
79
149
|
// Find available worker (proper load balancing)
|
|
80
150
|
const availableWorker = this.workers.find(worker => !this.busyWorkers.has(worker));
|
|
81
151
|
if (!availableWorker) {
|
|
82
|
-
|
|
152
|
+
this.log('[ScenarioService] No available workers, waiting...');
|
|
83
153
|
return; // All workers busy, wait for one to become available
|
|
84
154
|
}
|
|
85
155
|
|
|
@@ -88,7 +158,7 @@ export class ScenarioService extends EventEmitter {
|
|
|
88
158
|
return;
|
|
89
159
|
}
|
|
90
160
|
|
|
91
|
-
|
|
161
|
+
this.log(`[ScenarioService] Processing job ${job.id} with worker`);
|
|
92
162
|
|
|
93
163
|
// Mark worker as busy
|
|
94
164
|
this.busyWorkers.add(availableWorker);
|
|
@@ -96,10 +166,10 @@ export class ScenarioService extends EventEmitter {
|
|
|
96
166
|
try {
|
|
97
167
|
// Process job directly with worker
|
|
98
168
|
const result = await availableWorker.processScenarioJob(job);
|
|
99
|
-
|
|
169
|
+
this.log(`[ScenarioService] Job ${job.id} completed with result: ${JSON.stringify(result)}`);
|
|
100
170
|
this.handleJobResult(job.id, result);
|
|
101
171
|
} catch (error) {
|
|
102
|
-
|
|
172
|
+
this.log(`Error processing job with worker: ${error}`, 'error');
|
|
103
173
|
this.emit('jobError', job.id, error);
|
|
104
174
|
// Put job back in queue if it failed
|
|
105
175
|
this.jobQueue.unshift(job);
|
|
@@ -115,7 +185,7 @@ export class ScenarioService extends EventEmitter {
|
|
|
115
185
|
// Report credit usage for successful script generation
|
|
116
186
|
if (result.success) {
|
|
117
187
|
this.creditUsageService.reportScriptGenerationCredit(jobId).catch(error => {
|
|
118
|
-
|
|
188
|
+
this.log(`Failed to report credit usage for script generation (job: ${jobId}): ${error}`, 'warn');
|
|
119
189
|
});
|
|
120
190
|
}
|
|
121
191
|
|
|
@@ -137,7 +207,7 @@ export class ScenarioService extends EventEmitter {
|
|
|
137
207
|
}
|
|
138
208
|
|
|
139
209
|
async shutdown(): Promise<void> {
|
|
140
|
-
|
|
210
|
+
this.log('Shutting down scenario service...');
|
|
141
211
|
|
|
142
212
|
// Cleanup all workers
|
|
143
213
|
const cleanupPromises = this.workers.map(worker => worker.cleanup());
|
|
@@ -145,6 +215,6 @@ export class ScenarioService extends EventEmitter {
|
|
|
145
215
|
|
|
146
216
|
this.workers = [];
|
|
147
217
|
this.busyWorkers.clear();
|
|
148
|
-
|
|
218
|
+
this.log('Scenario service shutdown complete');
|
|
149
219
|
}
|
|
150
220
|
}
|