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.
Files changed (146) hide show
  1. package/VISION_DIAGNOSTICS_IMPROVEMENTS.md +336 -0
  2. package/dist/credit-usage-service.d.ts +9 -0
  3. package/dist/credit-usage-service.d.ts.map +1 -1
  4. package/dist/credit-usage-service.js +20 -5
  5. package/dist/credit-usage-service.js.map +1 -1
  6. package/dist/execution-service.d.ts +7 -2
  7. package/dist/execution-service.d.ts.map +1 -1
  8. package/dist/execution-service.js +91 -36
  9. package/dist/execution-service.js.map +1 -1
  10. package/dist/index.d.ts +30 -2
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +91 -26
  13. package/dist/index.js.map +1 -1
  14. package/dist/llm-facade.d.ts +64 -8
  15. package/dist/llm-facade.d.ts.map +1 -1
  16. package/dist/llm-facade.js +361 -109
  17. package/dist/llm-facade.js.map +1 -1
  18. package/dist/llm-provider.d.ts +39 -0
  19. package/dist/llm-provider.d.ts.map +1 -0
  20. package/dist/llm-provider.js +7 -0
  21. package/dist/llm-provider.js.map +1 -0
  22. package/dist/model-constants.d.ts +21 -0
  23. package/dist/model-constants.d.ts.map +1 -0
  24. package/dist/model-constants.js +24 -0
  25. package/dist/model-constants.js.map +1 -0
  26. package/dist/orchestrator/index.d.ts +8 -0
  27. package/dist/orchestrator/index.d.ts.map +1 -0
  28. package/dist/orchestrator/index.js +23 -0
  29. package/dist/orchestrator/index.js.map +1 -0
  30. package/dist/orchestrator/orchestrator-agent.d.ts +66 -0
  31. package/dist/orchestrator/orchestrator-agent.d.ts.map +1 -0
  32. package/dist/orchestrator/orchestrator-agent.js +855 -0
  33. package/dist/orchestrator/orchestrator-agent.js.map +1 -0
  34. package/dist/orchestrator/tool-registry.d.ts +74 -0
  35. package/dist/orchestrator/tool-registry.d.ts.map +1 -0
  36. package/dist/orchestrator/tool-registry.js +131 -0
  37. package/dist/orchestrator/tool-registry.js.map +1 -0
  38. package/dist/orchestrator/tools/check-page-ready.d.ts +13 -0
  39. package/dist/orchestrator/tools/check-page-ready.d.ts.map +1 -0
  40. package/dist/orchestrator/tools/check-page-ready.js +72 -0
  41. package/dist/orchestrator/tools/check-page-ready.js.map +1 -0
  42. package/dist/orchestrator/tools/extract-data.d.ts +13 -0
  43. package/dist/orchestrator/tools/extract-data.d.ts.map +1 -0
  44. package/dist/orchestrator/tools/extract-data.js +84 -0
  45. package/dist/orchestrator/tools/extract-data.js.map +1 -0
  46. package/dist/orchestrator/tools/index.d.ts +10 -0
  47. package/dist/orchestrator/tools/index.d.ts.map +1 -0
  48. package/dist/orchestrator/tools/index.js +18 -0
  49. package/dist/orchestrator/tools/index.js.map +1 -0
  50. package/dist/orchestrator/tools/inspect-page.d.ts +13 -0
  51. package/dist/orchestrator/tools/inspect-page.d.ts.map +1 -0
  52. package/dist/orchestrator/tools/inspect-page.js +39 -0
  53. package/dist/orchestrator/tools/inspect-page.js.map +1 -0
  54. package/dist/orchestrator/tools/recall-history.d.ts +13 -0
  55. package/dist/orchestrator/tools/recall-history.d.ts.map +1 -0
  56. package/dist/orchestrator/tools/recall-history.js +64 -0
  57. package/dist/orchestrator/tools/recall-history.js.map +1 -0
  58. package/dist/orchestrator/tools/take-screenshot.d.ts +15 -0
  59. package/dist/orchestrator/tools/take-screenshot.d.ts.map +1 -0
  60. package/dist/orchestrator/tools/take-screenshot.js +112 -0
  61. package/dist/orchestrator/tools/take-screenshot.js.map +1 -0
  62. package/dist/orchestrator/types.d.ts +133 -0
  63. package/dist/orchestrator/types.d.ts.map +1 -0
  64. package/dist/orchestrator/types.js +28 -0
  65. package/dist/orchestrator/types.js.map +1 -0
  66. package/dist/playwright-mcp-service.d.ts +9 -0
  67. package/dist/playwright-mcp-service.d.ts.map +1 -1
  68. package/dist/playwright-mcp-service.js +20 -5
  69. package/dist/playwright-mcp-service.js.map +1 -1
  70. package/dist/progress-reporter.d.ts +97 -0
  71. package/dist/progress-reporter.d.ts.map +1 -0
  72. package/dist/progress-reporter.js +18 -0
  73. package/dist/progress-reporter.js.map +1 -0
  74. package/dist/prompts.d.ts +24 -0
  75. package/dist/prompts.d.ts.map +1 -1
  76. package/dist/prompts.js +593 -68
  77. package/dist/prompts.js.map +1 -1
  78. package/dist/providers/backend-proxy-llm-provider.d.ts +25 -0
  79. package/dist/providers/backend-proxy-llm-provider.d.ts.map +1 -0
  80. package/dist/providers/backend-proxy-llm-provider.js +76 -0
  81. package/dist/providers/backend-proxy-llm-provider.js.map +1 -0
  82. package/dist/providers/local-llm-provider.d.ts +21 -0
  83. package/dist/providers/local-llm-provider.d.ts.map +1 -0
  84. package/dist/providers/local-llm-provider.js +35 -0
  85. package/dist/providers/local-llm-provider.js.map +1 -0
  86. package/dist/scenario-service.d.ts +27 -1
  87. package/dist/scenario-service.d.ts.map +1 -1
  88. package/dist/scenario-service.js +48 -12
  89. package/dist/scenario-service.js.map +1 -1
  90. package/dist/scenario-worker-class.d.ts +39 -2
  91. package/dist/scenario-worker-class.d.ts.map +1 -1
  92. package/dist/scenario-worker-class.js +614 -86
  93. package/dist/scenario-worker-class.js.map +1 -1
  94. package/dist/script-utils.d.ts +2 -0
  95. package/dist/script-utils.d.ts.map +1 -1
  96. package/dist/script-utils.js +44 -4
  97. package/dist/script-utils.js.map +1 -1
  98. package/dist/types.d.ts +11 -0
  99. package/dist/types.d.ts.map +1 -1
  100. package/dist/types.js.map +1 -1
  101. package/dist/utils/browser-utils.d.ts +20 -1
  102. package/dist/utils/browser-utils.d.ts.map +1 -1
  103. package/dist/utils/browser-utils.js +102 -51
  104. package/dist/utils/browser-utils.js.map +1 -1
  105. package/dist/utils/page-info-utils.d.ts +23 -4
  106. package/dist/utils/page-info-utils.d.ts.map +1 -1
  107. package/dist/utils/page-info-utils.js +174 -43
  108. package/dist/utils/page-info-utils.js.map +1 -1
  109. package/package.json +1 -2
  110. package/plandocs/HUMAN_LIKE_IMPROVEMENTS.md +642 -0
  111. package/plandocs/MULTI_AGENT_ARCHITECTURE_REVIEW.md +844 -0
  112. package/plandocs/ORCHESTRATOR_MVP_SUMMARY.md +539 -0
  113. package/plandocs/PHASE1_ABSTRACTION_COMPLETE.md +241 -0
  114. package/plandocs/PHASE1_FINAL_STATUS.md +210 -0
  115. package/plandocs/PLANNING_SESSION_SUMMARY.md +372 -0
  116. package/plandocs/SCRIPT_CLEANUP_FEATURE.md +201 -0
  117. package/plandocs/SCRIPT_GENERATION_ARCHITECTURE.md +364 -0
  118. package/plandocs/SELECTOR_IMPROVEMENTS.md +139 -0
  119. package/src/credit-usage-service.ts +23 -5
  120. package/src/execution-service.ts +152 -42
  121. package/src/index.ts +169 -26
  122. package/src/llm-facade.ts +500 -126
  123. package/src/llm-provider.ts +43 -0
  124. package/src/model-constants.ts +23 -0
  125. package/src/orchestrator/index.ts +33 -0
  126. package/src/orchestrator/orchestrator-agent.ts +1037 -0
  127. package/src/orchestrator/tool-registry.ts +182 -0
  128. package/src/orchestrator/tools/check-page-ready.ts +75 -0
  129. package/src/orchestrator/tools/extract-data.ts +92 -0
  130. package/src/orchestrator/tools/index.ts +11 -0
  131. package/src/orchestrator/tools/inspect-page.ts +42 -0
  132. package/src/orchestrator/tools/recall-history.ts +72 -0
  133. package/src/orchestrator/tools/take-screenshot.ts +128 -0
  134. package/src/orchestrator/types.ts +200 -0
  135. package/src/playwright-mcp-service.ts +23 -5
  136. package/src/progress-reporter.ts +109 -0
  137. package/src/prompts.ts +606 -69
  138. package/src/providers/backend-proxy-llm-provider.ts +91 -0
  139. package/src/providers/local-llm-provider.ts +38 -0
  140. package/src/scenario-service.ts +83 -13
  141. package/src/scenario-worker-class.ts +740 -72
  142. package/src/script-utils.ts +50 -5
  143. package/src/types.ts +13 -1
  144. package/src/utils/browser-utils.ts +123 -51
  145. package/src/utils/page-info-utils.ts +210 -53
  146. 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
+
@@ -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
- constructor(maxWorkers: number = 2, fileHandler?: FileHandler, authConfig?: AuthConfig, backendUrl?: string) {
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
- const worker = new ScenarioWorker(this.fileHandler, this.authConfig || undefined, undefined, this.backendUrl);
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
- console.log(`Scenario worker initialized with session: ${worker['sessionId']}`);
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
- console.log('Scenario service initialized');
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
- console.log(`[ScenarioService] Processing next job. Queue length: ${this.jobQueue.length}, Workers: ${this.workers.length}, Busy workers: ${this.busyWorkers.size}`);
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
- console.log('[ScenarioService] No available workers, waiting...');
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
- console.log(`[ScenarioService] Processing job ${job.id} with worker`);
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
- console.log(`[ScenarioService] Job ${job.id} completed with result:`, result);
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
- console.error('Error processing job with worker:', error);
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
- console.warn(`Failed to report credit usage for script generation (job: ${jobId}):`, error);
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
- console.log('Shutting down scenario service...');
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
- console.log('Scenario service shutdown complete');
218
+ this.log('Scenario service shutdown complete');
149
219
  }
150
220
  }