testchimp-runner-core 0.0.35 → 0.0.37

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.
Files changed (81) hide show
  1. package/dist/orchestrator/orchestrator-agent.d.ts.map +1 -1
  2. package/dist/orchestrator/orchestrator-agent.js +7 -4
  3. package/dist/orchestrator/orchestrator-agent.js.map +1 -1
  4. package/dist/orchestrator/orchestrator-prompts.d.ts.map +1 -1
  5. package/dist/orchestrator/orchestrator-prompts.js +73 -15
  6. package/dist/orchestrator/orchestrator-prompts.js.map +1 -1
  7. package/dist/orchestrator/page-som-handler.d.ts +1 -2
  8. package/dist/orchestrator/page-som-handler.d.ts.map +1 -1
  9. package/dist/orchestrator/page-som-handler.js +51 -25
  10. package/dist/orchestrator/page-som-handler.js.map +1 -1
  11. package/package.json +6 -1
  12. package/plandocs/BEFORE_AFTER_VERIFICATION.md +0 -148
  13. package/plandocs/COORDINATE_MODE_DIAGNOSIS.md +0 -144
  14. package/plandocs/CREDIT_CALLBACK_ARCHITECTURE.md +0 -253
  15. package/plandocs/HUMAN_LIKE_IMPROVEMENTS.md +0 -642
  16. package/plandocs/IMPLEMENTATION_STATUS.md +0 -108
  17. package/plandocs/INTEGRATION_COMPLETE.md +0 -322
  18. package/plandocs/MULTI_AGENT_ARCHITECTURE_REVIEW.md +0 -844
  19. package/plandocs/ORCHESTRATOR_MVP_SUMMARY.md +0 -539
  20. package/plandocs/PHASE1_ABSTRACTION_COMPLETE.md +0 -241
  21. package/plandocs/PHASE1_FINAL_STATUS.md +0 -210
  22. package/plandocs/PHASE_1_COMPLETE.md +0 -165
  23. package/plandocs/PHASE_1_SUMMARY.md +0 -184
  24. package/plandocs/PLANNING_SESSION_SUMMARY.md +0 -372
  25. package/plandocs/PROMPT_OPTIMIZATION_ANALYSIS.md +0 -120
  26. package/plandocs/PROMPT_SANITY_CHECK.md +0 -120
  27. package/plandocs/SCRIPT_CLEANUP_FEATURE.md +0 -201
  28. package/plandocs/SCRIPT_GENERATION_ARCHITECTURE.md +0 -364
  29. package/plandocs/SELECTOR_IMPROVEMENTS.md +0 -139
  30. package/plandocs/SESSION_SUMMARY_v0.0.33.md +0 -151
  31. package/plandocs/TROUBLESHOOTING_SESSION.md +0 -72
  32. package/plandocs/VISION_DIAGNOSTICS_IMPROVEMENTS.md +0 -336
  33. package/plandocs/VISUAL_AGENT_EVOLUTION_PLAN.md +0 -396
  34. package/plandocs/WHATS_NEW_v0.0.33.md +0 -183
  35. package/plandocs/exploratory-mode-support-v2.plan.md +0 -953
  36. package/plandocs/exploratory-mode-support.plan.md +0 -928
  37. package/plandocs/journey-id-tracking-addendum.md +0 -227
  38. package/releasenotes/RELEASE_0.0.26.md +0 -165
  39. package/releasenotes/RELEASE_0.0.27.md +0 -236
  40. package/releasenotes/RELEASE_0.0.28.md +0 -286
  41. package/src/auth-config.ts +0 -84
  42. package/src/credit-usage-service.ts +0 -188
  43. package/src/env-loader.ts +0 -103
  44. package/src/execution-service.ts +0 -996
  45. package/src/file-handler.ts +0 -104
  46. package/src/index.ts +0 -432
  47. package/src/llm-facade.ts +0 -821
  48. package/src/llm-provider.ts +0 -53
  49. package/src/model-constants.ts +0 -35
  50. package/src/orchestrator/decision-parser.ts +0 -139
  51. package/src/orchestrator/index.ts +0 -58
  52. package/src/orchestrator/orchestrator-agent.ts +0 -1282
  53. package/src/orchestrator/orchestrator-prompts.ts +0 -786
  54. package/src/orchestrator/page-som-handler.ts +0 -1565
  55. package/src/orchestrator/som-types.ts +0 -188
  56. package/src/orchestrator/tool-registry.ts +0 -184
  57. package/src/orchestrator/tools/check-page-ready.ts +0 -75
  58. package/src/orchestrator/tools/extract-data.ts +0 -92
  59. package/src/orchestrator/tools/index.ts +0 -15
  60. package/src/orchestrator/tools/inspect-page.ts +0 -42
  61. package/src/orchestrator/tools/recall-history.ts +0 -72
  62. package/src/orchestrator/tools/refresh-som-markers.ts +0 -69
  63. package/src/orchestrator/tools/take-screenshot.ts +0 -128
  64. package/src/orchestrator/tools/verify-action-result.ts +0 -159
  65. package/src/orchestrator/tools/view-previous-screenshot.ts +0 -103
  66. package/src/orchestrator/types.ts +0 -291
  67. package/src/playwright-mcp-service.ts +0 -224
  68. package/src/progress-reporter.ts +0 -144
  69. package/src/prompts.ts +0 -842
  70. package/src/providers/backend-proxy-llm-provider.ts +0 -91
  71. package/src/providers/local-llm-provider.ts +0 -38
  72. package/src/scenario-service.ts +0 -252
  73. package/src/scenario-worker-class.ts +0 -1110
  74. package/src/script-utils.ts +0 -203
  75. package/src/types.ts +0 -239
  76. package/src/utils/browser-utils.ts +0 -348
  77. package/src/utils/coordinate-converter.ts +0 -162
  78. package/src/utils/page-info-retry.ts +0 -65
  79. package/src/utils/page-info-utils.ts +0 -285
  80. package/testchimp-runner-core-0.0.35.tgz +0 -0
  81. package/tsconfig.json +0 -19
@@ -1,91 +0,0 @@
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
-
@@ -1,38 +0,0 @@
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
-
@@ -1,252 +0,0 @@
1
- import { EventEmitter } from 'events';
2
- import dotenv from 'dotenv';
3
- import { ScenarioJob, ScenarioRunJob, ScenarioResponse, PlaywrightConfig } from './types';
4
- import { ScenarioWorker } from './scenario-worker-class';
5
- import { FileHandler, NoOpFileHandler } from './file-handler';
6
- import { AuthConfig } from './auth-config';
7
- import { CreditUsageService } from './credit-usage-service';
8
- import { LLMProvider } from './llm-provider';
9
- import { ProgressReporter } from './progress-reporter';
10
- import { AgentConfig } from './orchestrator';
11
-
12
- // Load environment variables
13
- dotenv.config();
14
-
15
- /**
16
- * Service for processing scenarios using LLM + Playwright
17
- */
18
- export class ScenarioService extends EventEmitter {
19
- private workers: ScenarioWorker[] = [];
20
- private jobQueue: ScenarioRunJob[] = [];
21
- private busyWorkers: Set<ScenarioWorker> = new Set();
22
- private maxWorkers: number;
23
- private fileHandler: FileHandler;
24
- private authConfig: AuthConfig | null;
25
- private backendUrl?: string;
26
- private creditUsageService: CreditUsageService;
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
- ) {
48
- super();
49
- this.maxWorkers = maxWorkers;
50
- this.fileHandler = fileHandler || new NoOpFileHandler();
51
- this.llmProvider = llmProvider;
52
- this.progressReporter = progressReporter;
53
- this.authConfig = authConfig || null;
54
- this.backendUrl = backendUrl;
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
83
- }
84
-
85
- private async initializeWorkers(): Promise<void> {
86
- for (let i = 0; i < this.maxWorkers; i++) {
87
- await this.createWorker();
88
- }
89
- }
90
-
91
- private async createWorker(): Promise<void> {
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
- );
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
-
113
- this.workers.push(worker);
114
- // Internal initialization - no need to log worker details
115
- }
116
-
117
- async initialize(): Promise<void> {
118
- // Wait for workers to be initialized
119
- await this.initializeWorkers();
120
- // Internal initialization - consumer doesn't need to see this
121
- }
122
-
123
- processScenario(
124
- scenario: string,
125
- testName?: string,
126
- config?: PlaywrightConfig,
127
- model?: string,
128
- scenarioFileName?: string,
129
- existingBrowser?: any,
130
- existingContext?: any,
131
- existingPage?: any
132
- ): string {
133
- const jobId = `scenario_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
134
-
135
- // Add job to queue
136
- const job: ScenarioRunJob = {
137
- id: jobId,
138
- scenario,
139
- testName,
140
- playwrightConfig: config,
141
- model,
142
- scenarioFileName,
143
- existingBrowser,
144
- existingContext,
145
- existingPage
146
- };
147
-
148
- this.jobQueue.push(job);
149
- this.processNextJob();
150
-
151
- return jobId; // Return job ID for tracking
152
- }
153
-
154
- private async processNextJob(): Promise<void> {
155
- if (this.jobQueue.length === 0) {
156
- return;
157
- }
158
-
159
- this.log(`[ScenarioService] Processing next job. Queue length: ${this.jobQueue.length}, Workers: ${this.workers.length}, Busy workers: ${this.busyWorkers.size}`);
160
-
161
- // Find available worker (proper load balancing)
162
- const availableWorker = this.workers.find(worker => !this.busyWorkers.has(worker));
163
- if (!availableWorker) {
164
- this.log('[ScenarioService] No available workers, waiting...');
165
- return; // All workers busy, wait for one to become available
166
- }
167
-
168
- const job = this.jobQueue.shift();
169
- if (!job) {
170
- return;
171
- }
172
-
173
- this.log(`[ScenarioService] Processing job ${job.id} with worker`);
174
-
175
- // Mark worker as busy
176
- this.busyWorkers.add(availableWorker);
177
-
178
- try {
179
- // Process job directly with worker
180
- const result = await availableWorker.processScenarioJob(job);
181
- this.log(`[ScenarioService] Job ${job.id} completed with result: ${JSON.stringify(result)}`);
182
- this.handleJobResult(job.id, result);
183
- } catch (error) {
184
- this.log(`Error processing job with worker: ${error}`, 'error');
185
- this.emit('jobError', job.id, error);
186
- // Put job back in queue if it failed
187
- this.jobQueue.unshift(job);
188
- } finally {
189
- // Mark worker as available again
190
- this.busyWorkers.delete(availableWorker);
191
- // Process next job
192
- this.processNextJob();
193
- }
194
- }
195
-
196
- private handleJobResult(jobId: string, result: ScenarioResponse): void {
197
- // Report credit usage for successful script generation
198
- if (result.success) {
199
- this.creditUsageService.reportScriptGenerationCredit(jobId).catch(error => {
200
- this.log(`Failed to report credit usage for script generation (job: ${jobId}): ${error}`, 'warn');
201
- });
202
- }
203
-
204
- // Emit result event
205
- this.emit('jobComplete', jobId, result);
206
-
207
- // Mark worker as available and process next job
208
- this.busyWorkers.clear(); // Simple approach - clear all busy workers
209
- this.processNextJob();
210
- }
211
-
212
- private handleJobError(jobId: string, error: string): void {
213
- // Emit error event
214
- this.emit('jobError', jobId, new Error(error));
215
-
216
- // Mark worker as available and process next job
217
- this.busyWorkers.clear(); // Simple approach - clear all busy workers
218
- this.processNextJob();
219
- }
220
-
221
- /**
222
- * Execute exploration mode using orchestrator
223
- * Requires orchestrator to be enabled via useOrchestrator option
224
- */
225
- async executeExploration(page: any, explorationConfig: any, jobId: string): Promise<any> {
226
- if (!this.useOrchestrator) {
227
- throw new Error('Exploration mode requires orchestrator to be enabled');
228
- }
229
-
230
- // Get an available worker (or create one if needed)
231
- let worker = this.workers.find(w => !this.busyWorkers.has(w));
232
- if (!worker) {
233
- await this.createWorker();
234
- worker = this.workers[this.workers.length - 1];
235
- }
236
-
237
- // Execute exploration via worker's orchestrator
238
- return worker.executeExploration(page, explorationConfig, jobId);
239
- }
240
-
241
- async shutdown(): Promise<void> {
242
- this.log('Shutting down scenario service...');
243
-
244
- // Cleanup all workers
245
- const cleanupPromises = this.workers.map(worker => worker.cleanup());
246
- await Promise.all(cleanupPromises);
247
-
248
- this.workers = [];
249
- this.busyWorkers.clear();
250
- this.log('Scenario service shutdown complete');
251
- }
252
- }