working companion prototype

This commit is contained in:
2025-11-24 23:32:36 +01:00
parent e7978024d7
commit e2bea9a126
175 changed files with 23227 additions and 3519 deletions

View File

@@ -6,7 +6,8 @@ import { ISessionRepository } from '../../../application/ports/ISessionRepositor
import { getStepName } from './templates/IRacingTemplateMap';
export class MockAutomationEngineAdapter implements IAutomationEngine {
private automationInterval: NodeJS.Timeout | null = null;
private isRunning = false;
private automationPromise: Promise<void> | null = null;
constructor(
private readonly browserAutomation: IBrowserAutomation,
@@ -44,16 +45,21 @@ export class MockAutomationEngineAdapter implements IAutomationEngine {
}
private startAutomation(config: HostedSessionConfig): void {
this.automationInterval = setInterval(async () => {
if (this.isRunning) {
return;
}
this.isRunning = true;
this.automationPromise = this.runAutomationLoop(config);
}
private async runAutomationLoop(config: HostedSessionConfig): Promise<void> {
while (this.isRunning) {
try {
const sessions = await this.sessionRepository.findAll();
const session = sessions[0];
if (!session || !session.state.isInProgress()) {
if (this.automationInterval) {
clearInterval(this.automationInterval);
this.automationInterval = null;
}
this.isRunning = false;
return;
}
@@ -68,10 +74,7 @@ export class MockAutomationEngineAdapter implements IAutomationEngine {
console.error(errorMessage);
// Stop automation and mark session as failed
if (this.automationInterval) {
clearInterval(this.automationInterval);
this.automationInterval = null;
}
this.isRunning = false;
session.fail(errorMessage);
await this.sessionRepository.update(session);
@@ -82,31 +85,50 @@ export class MockAutomationEngineAdapter implements IAutomationEngine {
await this.browserAutomation.navigateToPage(`step-${currentStep.value}`);
}
// Transition to next step if not final
// Transition to next step
if (!currentStep.isFinalStep()) {
session.transitionToStep(currentStep.next());
await this.sessionRepository.update(session);
} else {
// Stop at step 18
if (this.automationInterval) {
clearInterval(this.automationInterval);
this.automationInterval = null;
// If we just transitioned to the final step, execute it before stopping
const nextStep = session.currentStep;
if (nextStep.isFinalStep()) {
// Execute final step handler
if (this.browserAutomation.executeStep) {
const result = await this.browserAutomation.executeStep(nextStep, config as unknown as Record<string, unknown>);
if (!result.success) {
const errorMessage = `Step ${nextStep.value} (${getStepName(nextStep.value)}) failed: ${result.error}`;
console.error(errorMessage);
// Don't try to fail terminal session - just log the error
// Session is already in STOPPED_AT_STEP_18 state after transitionToStep()
}
}
// Stop after final step
this.isRunning = false;
return;
}
} else {
// Current step is already final - stop
this.isRunning = false;
return;
}
// Wait before next iteration
await this.delay(500);
} catch (error) {
console.error('Automation error:', error);
if (this.automationInterval) {
clearInterval(this.automationInterval);
this.automationInterval = null;
}
this.isRunning = false;
return;
}
}, 500); // Execute each step every 500ms
}
}
private delay(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
public stopAutomation(): void {
if (this.automationInterval) {
clearInterval(this.automationInterval);
this.automationInterval = null;
}
this.isRunning = false;
this.automationPromise = null;
}
}