ff-automationv2 1.0.0

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 (69) hide show
  1. package/ARCHITECTURE.md +112 -0
  2. package/FireFlink_Architecture.drawio +68 -0
  3. package/ONBOARDING.md +29 -0
  4. package/README.md +28 -0
  5. package/TECHNICAL_DEEP_DIVE.md +26 -0
  6. package/eslint.config.ts +29 -0
  7. package/package.json +51 -0
  8. package/src/ai/llmcalls/decodeApiKey.ts +14 -0
  9. package/src/ai/llmcalls/llmAction.ts +89 -0
  10. package/src/ai/llmcalls/parseLlmOputput.ts +69 -0
  11. package/src/ai/llmprompts/promptRegistry.ts +16 -0
  12. package/src/ai/llmprompts/systemPrompts/actionExtractorPrompt.ts +70 -0
  13. package/src/ai/llmprompts/systemPrompts/errorDescriptionPrompt.ts +23 -0
  14. package/src/ai/llmprompts/systemPrompts/fireflinkElementIndexExtactors.ts +198 -0
  15. package/src/ai/llmprompts/systemPrompts/userStoryToListPrompt.ts +24 -0
  16. package/src/ai/llmprompts/systemPrompts/visionPrompt.ts +28 -0
  17. package/src/ai/llmprompts/userPrompts/userPrompt.ts +41 -0
  18. package/src/automation/actions/executor.ts +75 -0
  19. package/src/automation/actions/interaction/click.ts +25 -0
  20. package/src/automation/actions/interaction/enterInput.ts +27 -0
  21. package/src/automation/actions/interface/interactionActionInterface.ts +27 -0
  22. package/src/automation/actions/interface/navigationActionInterface.ts +22 -0
  23. package/src/automation/actions/interface/waitActionInterface.ts +6 -0
  24. package/src/automation/actions/navigation/getTitle.ts +9 -0
  25. package/src/automation/actions/navigation/goBack.ts +9 -0
  26. package/src/automation/actions/navigation/navigate.ts +10 -0
  27. package/src/automation/actions/navigation/refresh.ts +9 -0
  28. package/src/automation/actions/wait/wait.ts +10 -0
  29. package/src/automation/browserSession/initiateBrowserSession.ts +81 -0
  30. package/src/core/constants/supportedActions.ts +8 -0
  31. package/src/core/interfaces/StableDomInterface.ts +6 -0
  32. package/src/core/interfaces/actionInterface.ts +13 -0
  33. package/src/core/interfaces/automationRunnerInterface.ts +3 -0
  34. package/src/core/interfaces/browserCapabilitiesInterface.ts +5 -0
  35. package/src/core/interfaces/browserConfigurationInterface.ts +3 -0
  36. package/src/core/interfaces/domAnalysisInterface.ts +34 -0
  37. package/src/core/interfaces/executionDetails.ts +29 -0
  38. package/src/core/interfaces/fireflinkScriptPayloadInterface.ts +39 -0
  39. package/src/core/interfaces/llmConfigurationInterface.ts +3 -0
  40. package/src/core/interfaces/llmResponseInterface.ts +38 -0
  41. package/src/core/interfaces/promptInterface.ts +21 -0
  42. package/src/core/interfaces/scriptGenrationDataInterface.ts +16 -0
  43. package/src/core/interfaces/toolsInterface.ts +5 -0
  44. package/src/core/main/actionHandlerFactory.ts +86 -0
  45. package/src/core/main/executionContext.ts +18 -0
  46. package/src/core/main/runAutomationScript.ts +177 -0
  47. package/src/core/main/stepProcessor.ts +28 -0
  48. package/src/core/types/llmResponseType.ts +11 -0
  49. package/src/core/types/promptMap.ts +7 -0
  50. package/src/core/types/promptType.ts +7 -0
  51. package/src/core/types/visionllmInputType.ts +4 -0
  52. package/src/domAnalysis/getRelaventElements.ts +24 -0
  53. package/src/domAnalysis/relativeElementsFromDom.ts +94 -0
  54. package/src/domAnalysis/searchBest.ts +159 -0
  55. package/src/domAnalysis/simplifyAndFlatten.ts +118 -0
  56. package/src/fireflinkData/fireflinkLocators/elementsFromHTML.ts +656 -0
  57. package/src/fireflinkData/fireflinkLocators/getListOfLocators.ts +31 -0
  58. package/src/fireflinkData/fireflinkLocators/typeList.ts +36 -0
  59. package/src/fireflinkData/fireflinkScript/scriptGenrationData.ts +30 -0
  60. package/src/index.ts +5 -0
  61. package/src/llmConfig/llmConfiguration.ts +26 -0
  62. package/src/service/fireflinkApi.service.ts +46 -0
  63. package/src/service/scriptRunner.service.ts +83 -0
  64. package/src/utils/DomExtraction/jsForAttributeInjection.ts +254 -0
  65. package/src/utils/javascript/jsFindElement.ts +161 -0
  66. package/src/utils/javascript/jsForShadowRoot.ts +216 -0
  67. package/src/utils/javascript/jsForToaster.ts +60 -0
  68. package/src/utils/logger/logData.ts +36 -0
  69. package/tsconfig.json +26 -0
@@ -0,0 +1,112 @@
1
+ # 📊 FireFlink System Architecture
2
+
3
+ ## Layered Architecture
4
+
5
+ ```
6
+ ┌────────────────────────────────────────────┐
7
+ │ User Story Layer │
8
+ └────────────────────────────────────────────┘
9
+
10
+ ┌────────────────────────────────────────────┐
11
+ │ LLM Reasoning Layer │
12
+ │ - USER_STORY_TO_LIST │
13
+ │ - KEYWORD_EXTRACTOR │
14
+ │ - FF_INSPECTOR │
15
+ └────────────────────────────────────────────┘
16
+
17
+ ┌────────────────────────────────────────────┐
18
+ │ Orchestration Layer │
19
+ │ (AutomationRunner) │
20
+ └────────────────────────────────────────────┘
21
+
22
+ ┌────────────────────────────────────────────┐
23
+ │ DOM Abstraction Layer │
24
+ │ - Inject FF-inspecter attributes │
25
+ │ - Serialize DOM │
26
+ │ - Build FF → XPath mapping │
27
+ └────────────────────────────────────────────┘
28
+
29
+ ┌────────────────────────────────────────────┐
30
+ │ DOM Processing Engine │
31
+ │ - Keyword-based DOM filtering │
32
+ └────────────────────────────────────────────┘
33
+
34
+ ┌────────────────────────────────────────────┐
35
+ │ Action Execution Layer │
36
+ │ - Click Handler │
37
+ │ - Enter Handler │
38
+ │ - Navigate Handler │
39
+ └────────────────────────────────────────────┘
40
+
41
+ ┌────────────────────────────────────────────┐
42
+ │ Script Generation Layer │
43
+ │ - ScriptAppender │
44
+ │ - Payload Builder │
45
+ └────────────────────────────────────────────┘
46
+
47
+ ┌────────────────────────────────────────────┐
48
+ │ FireFlink Backend API │
49
+ └────────────────────────────────────────────┘
50
+
51
+ ```
52
+
53
+ ## Execution Sequence
54
+
55
+ AutomationRunner
56
+ → StepProcessor (LLM)
57
+ → Browser (Inject DOM)
58
+ → DomProcessingEngine
59
+ → StepProcessor (FF selection)
60
+ → ActionHandler
61
+ → ScriptAppender
62
+ → ScriptRunner
63
+ → FireFlink API
64
+
65
+ ## high Level flow
66
+
67
+ ```
68
+ User Story
69
+
70
+ LLM → Manual Steps
71
+
72
+ FOR EACH STEP
73
+
74
+ LLM → Action + Keywords
75
+
76
+ Inject Annotated DOM
77
+
78
+ Filter Relevant DOM (DomProcessingEngine)
79
+
80
+ LLM → Choose FF-inspecter Index
81
+
82
+ Map FF Index → XPath
83
+
84
+ Execute Action
85
+
86
+ Append Script Data
87
+
88
+ ┌─────────────────────────────┐
89
+ │ Error Occurred? │
90
+ └──────────────┬──────────────┘
91
+
92
+ ┌──────┴──────┐
93
+ │ │
94
+ NO YES
95
+ │ │
96
+ │ Append CloseBrowser
97
+ │ ↓
98
+ │ Stop Execution
99
+ │ |
100
+ ↓ |
101
+ Continue Next Step |
102
+ ↓ |
103
+ (all Steps Complete) |
104
+ | |
105
+ | |
106
+ └──────┬──────┘
107
+ Collect Token Usage
108
+
109
+ Build Payload
110
+
111
+ Send to FireFlink API
112
+ ```
@@ -0,0 +1,68 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <mxfile host="app.diagrams.net">
3
+ <diagram name="FireFlink Architecture">
4
+ <mxGraphModel dx="1000" dy="1000" grid="1" gridSize="10" guides="1" tooltips="1"
5
+ connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100"
6
+ math="0" shadow="0">
7
+ <root>
8
+ <mxCell id="0"/>
9
+ <mxCell id="1" parent="0"/>
10
+
11
+ <mxCell id="2" value="User Story" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
12
+ <mxGeometry x="300" y="20" width="200" height="60" as="geometry"/>
13
+ </mxCell>
14
+
15
+ <mxCell id="3" value="LLM Reasoning Layer" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
16
+ <mxGeometry x="300" y="120" width="200" height="60" as="geometry"/>
17
+ </mxCell>
18
+
19
+ <mxCell id="4" value="AutomationRunner (Orchestration)" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
20
+ <mxGeometry x="300" y="220" width="200" height="60" as="geometry"/>
21
+ </mxCell>
22
+
23
+ <mxCell id="5" value="DOM Abstraction Layer (FF-inspecter Injection)" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
24
+ <mxGeometry x="300" y="320" width="200" height="60" as="geometry"/>
25
+ </mxCell>
26
+
27
+ <mxCell id="6" value="DOM Processing Engine" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
28
+ <mxGeometry x="300" y="420" width="200" height="60" as="geometry"/>
29
+ </mxCell>
30
+
31
+ <mxCell id="7" value="Action Execution Layer" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
32
+ <mxGeometry x="300" y="520" width="200" height="60" as="geometry"/>
33
+ </mxCell>
34
+
35
+ <mxCell id="8" value="Script Generation Layer" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
36
+ <mxGeometry x="300" y="620" width="200" height="60" as="geometry"/>
37
+ </mxCell>
38
+
39
+ <mxCell id="9" value="FireFlink Backend API" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
40
+ <mxGeometry x="300" y="720" width="200" height="60" as="geometry"/>
41
+ </mxCell>
42
+
43
+ <mxCell id="10" style="endArrow=block;html=1;" edge="1" parent="1" source="2" target="3">
44
+ <mxGeometry relative="1" as="geometry"/>
45
+ </mxCell>
46
+ <mxCell id="11" style="endArrow=block;html=1;" edge="1" parent="1" source="3" target="4">
47
+ <mxGeometry relative="1" as="geometry"/>
48
+ </mxCell>
49
+ <mxCell id="12" style="endArrow=block;html=1;" edge="1" parent="1" source="4" target="5">
50
+ <mxGeometry relative="1" as="geometry"/>
51
+ </mxCell>
52
+ <mxCell id="13" style="endArrow=block;html=1;" edge="1" parent="1" source="5" target="6">
53
+ <mxGeometry relative="1" as="geometry"/>
54
+ </mxCell>
55
+ <mxCell id="14" style="endArrow=block;html=1;" edge="1" parent="1" source="6" target="7">
56
+ <mxGeometry relative="1" as="geometry"/>
57
+ </mxCell>
58
+ <mxCell id="15" style="endArrow=block;html=1;" edge="1" parent="1" source="7" target="8">
59
+ <mxGeometry relative="1" as="geometry"/>
60
+ </mxCell>
61
+ <mxCell id="16" style="endArrow=block;html=1;" edge="1" parent="1" source="8" target="9">
62
+ <mxGeometry relative="1" as="geometry"/>
63
+ </mxCell>
64
+
65
+ </root>
66
+ </mxGraphModel>
67
+ </diagram>
68
+ </mxfile>
package/ONBOARDING.md ADDED
@@ -0,0 +1,29 @@
1
+ # 🧪 Developer Onboarding Guide
2
+
3
+ ## Getting Started
4
+
5
+ Entry Point: AutomationRunner.ts
6
+
7
+ Run: new AutomationRunner(request).run();
8
+
9
+ ## Execution Flow
10
+
11
+ 1. Convert user story to steps
12
+ 2. Extract action & keywords
13
+ 3. Inject annotated DOM
14
+ 4. Filter relevant DOM
15
+ 5. Resolve FF-index
16
+ 6. Execute action
17
+ 7. Send script to backend
18
+
19
+ ## Adding a New Action
20
+
21
+ - Create handler
22
+ - Register in actionHandlerFactory
23
+ - Add to INPUTLESS_ACTIONS if applicable
24
+
25
+ ## Debugging
26
+
27
+ - Log DOM using saveDomToFile()
28
+ - Validate FF-index mapping
29
+ - Check token usage tracking
package/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # 🔥 FireFlink AI Automation Platform
2
+
3
+ Enterprise-grade AI-powered automation engine that transforms natural
4
+ language user stories into executable browser automation scripts using
5
+ LLM-driven reasoning and intelligent DOM abstraction.
6
+
7
+ ## Executive Summary
8
+
9
+ FireFlink enables organizations to: - Convert user stories into
10
+ automated test scripts - Reduce manual scripting effort - Improve
11
+ element resilience using AI-based DOM interpretation - Track LLM token
12
+ usage and automation generation cost - Integrate automation results
13
+ directly into backend infrastructure
14
+
15
+ ## Core Capabilities
16
+
17
+ - AI Step Generation
18
+ - Intelligent Element Resolution
19
+ - DOM Annotation Engine (FF-inspecter system)
20
+ - Modular Action Handler Framework
21
+ - Failure Isolation & Safe Termination
22
+ - Token Usage Monitoring
23
+ - API Integration Layer
24
+
25
+ ## High-Level Execution Lifecycle
26
+
27
+ User Story → LLM Steps → DOM Annotation → Element Resolution → Action
28
+ Execution → Script Generation → API Submission
@@ -0,0 +1,26 @@
1
+ # 🧠 Technical Deep Dive
2
+
3
+ ## Core Concept
4
+
5
+ Each DOM element is assigned: FF-inspecter="Fire-Flink-X"
6
+
7
+ This allows deterministic mapping from AI selection to XPath.
8
+
9
+ ## Token Optimization Strategy
10
+
11
+ Instead of sending full DOM to LLM, FireFlink filters relevant nodes
12
+ using DomProcessingEngine to reduce token usage.
13
+
14
+ ## Failure Handling Model
15
+
16
+ Execution stops on: - Unsupported action - Invalid FF-index - XPath
17
+ resolution failure - Handler execution failure
18
+
19
+ CloseBrowser step is appended before termination.
20
+
21
+ ## Extensibility
22
+
23
+ - Add new PromptType
24
+ - Extend StepProcessor
25
+ - Add ActionHandler
26
+ - Modify payload schema
@@ -0,0 +1,29 @@
1
+ import js from "@eslint/js";
2
+ import globals from "globals";
3
+ import tseslint from "typescript-eslint";
4
+ import { defineConfig } from "eslint/config";
5
+
6
+ export default defineConfig([
7
+ {
8
+ files: ["**/*.{js,mjs,cjs,ts,mts,cts}"],
9
+ plugins: { js },
10
+ extends: ["js/recommended"],
11
+ languageOptions: { globals: globals.browser },
12
+ },
13
+
14
+ ...tseslint.configs.recommended,
15
+
16
+ {
17
+ rules: {
18
+ "no-console": ["error", { allow: ["warn", "error"] }],
19
+ "@typescript-eslint/no-explicit-any": "off",
20
+ "@typescript-eslint/no-unused-vars": [
21
+ "error",
22
+ {
23
+ argsIgnorePattern: "^_",
24
+ varsIgnorePattern: "^_",
25
+ },
26
+ ],
27
+ },
28
+ },
29
+ ]);
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "ff-automationv2",
3
+ "version": "1.0.0",
4
+ "private": false,
5
+ "type": "module",
6
+ "description": "This lib is used to automate the manual testcase",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "scripts": {
16
+ "builds": "npm run lint && tsc",
17
+ "build": "tsc",
18
+ "prepare": "npm run build",
19
+ "lint": "eslint src --max-warnings=0",
20
+ "test": "npm run build && node dist/tests/test12.js",
21
+ "llm": "npm run build && node dist/tests/testllm.js",
22
+ "dev": "npm run build && node dist/index.js",
23
+ "start": "node dist/index.js",
24
+ "file": "node dist/domAnalysis/getXpath.js"
25
+ },
26
+ "keywords": [],
27
+ "author": "Diwahar R",
28
+ "license": "ISC",
29
+ "devDependencies": {
30
+ "@eslint/js": "10.0.1",
31
+ "@types/jsdom": "27.0.0",
32
+ "@types/node": "25.2.2",
33
+ "eslint": "10.0.0",
34
+ "globals": "17.3.0",
35
+ "jiti": "2.6.1",
36
+ "nodemon": "3.1.11",
37
+ "ts-node": "10.9.2",
38
+ "typescript": "5.9.3",
39
+ "typescript-eslint": "8.56.0"
40
+ },
41
+ "dependencies": {
42
+ "axios": "1.13.5",
43
+ "cheerio": "1.2.0",
44
+ "fs-extra": "11.3.3",
45
+ "fuzzball": "2.2.3",
46
+ "jsdom": "27.4.0",
47
+ "openai": "6.18.0",
48
+ "uuid": "13.0.0",
49
+ "webdriverio": "9.23.3"
50
+ }
51
+ }
@@ -0,0 +1,14 @@
1
+
2
+ export function decodeApiKey(apiKey: string): string {
3
+ if (!apiKey) {
4
+ throw new Error("API key is required");
5
+ }
6
+
7
+ try {
8
+ return Buffer.from(apiKey, "base64").toString("utf-8");
9
+ } catch (error) {
10
+ throw new Error("Failed to decode API key", { cause: error });
11
+ }
12
+ }
13
+
14
+
@@ -0,0 +1,89 @@
1
+ import { prompts } from "../llmprompts/promptRegistry.js";
2
+ import OpenAI from "openai";
3
+ import { decodeApiKey } from "./decodeApiKey.js";
4
+ import { FireFlinkLLMResponse } from "../../core/types/llmResponseType.js"
5
+ import { PromptArgsMap } from "../../core/interfaces/promptInterface.js"
6
+ import { userInputFormatters } from "../../ai/llmprompts/userPrompts/userPrompt.js"
7
+ import { visionPromptMessage } from "../../core/types/visionllmInputType.js"
8
+ import { PromptType } from "../../core/types/promptType.js";
9
+ export class llmAction {
10
+ private client: OpenAI;
11
+ private model: string;
12
+ private visionClient: OpenAI
13
+ constructor(
14
+ apiKey: string,
15
+ baseURL: string,
16
+ model: string,
17
+ visionApiKey: string
18
+ ) {
19
+ this.model = model;
20
+ this.client = new OpenAI({
21
+ apiKey: decodeApiKey(apiKey),
22
+ baseURL: baseURL,
23
+ });
24
+ this.visionClient = new OpenAI({
25
+ apiKey: decodeApiKey(visionApiKey),
26
+ });
27
+
28
+ }
29
+
30
+ private async getLLMResponseText(system: string, user: string): Promise<FireFlinkLLMResponse> {
31
+ const response = await this.client.chat.completions.create({
32
+ model: this.model,
33
+ messages: [
34
+ {
35
+ role: "system",
36
+ content: system
37
+ },
38
+ {
39
+ role: "user",
40
+ content: user
41
+ }
42
+ ],
43
+ response_format: { type: "json_object" }
44
+ });
45
+ try {
46
+
47
+ return response;
48
+ } catch {
49
+ throw new Error(`Invalid JSON returned from LLM `);
50
+ }
51
+ }
52
+ async getLLMResponse<K extends keyof PromptArgsMap>(
53
+ type: K,
54
+ args: PromptArgsMap[K],
55
+ userInput: Record<string, any>
56
+ ): Promise<FireFlinkLLMResponse> {
57
+ const promptBuilder: (args: PromptArgsMap[K]) => Promise<string> =
58
+ prompts[type];
59
+ const systemPrompt = await promptBuilder(args);
60
+ const userPrompt: string | visionPromptMessage = userInputFormatters[type](userInput);
61
+ if (type === PromptType.VISION_PROMPT && Array.isArray(userPrompt)) {
62
+ return this.getLLMResponseWithVision(systemPrompt, userPrompt);
63
+ }
64
+ if (typeof userPrompt !== "string") {
65
+ throw new Error("Invalid non-vision user prompt format");
66
+ }
67
+ return this.getLLMResponseText(systemPrompt, userPrompt);
68
+ }
69
+
70
+ private async getLLMResponseWithVision(system: any, userPrompt: visionPromptMessage): Promise<string> {
71
+ const response = await this.visionClient.chat.completions.create({
72
+ model: "gpt-4.1",
73
+ messages: [
74
+ {
75
+ role: "system",
76
+ content: system
77
+ },
78
+ {
79
+ role: "user",
80
+ content: userPrompt
81
+ }
82
+ ],
83
+ response_format: { type: "json_object" }
84
+ });
85
+ return response.choices[0].message.content || "";
86
+ }
87
+
88
+
89
+ }
@@ -0,0 +1,69 @@
1
+ import { FireFlinkLLMResponse } from "../../core/types/llmResponseType.js";
2
+
3
+
4
+ export class LLMResultParser {
5
+ private inputTokens: number = 0;
6
+ private outputTokens: number = 0;
7
+ private totalTokens: number = 0;
8
+
9
+ private async extractJsonObject(response: string) {
10
+ const match = response.match(/\{[\s\S]*\}/);
11
+ if (!match) return null;
12
+ return JSON.parse(match[0]);
13
+ }
14
+ public async fetchResult(llmOutput: any): Promise<{
15
+ response: FireFlinkLLMResponse
16
+ }> {
17
+ try {
18
+ const content = llmOutput?.choices?.[0]?.message?.content;
19
+
20
+ if (!content) {
21
+ throw new Error("No content in LLM output");
22
+ }
23
+
24
+ let parsedContent: FireFlinkLLMResponse;
25
+
26
+ try {
27
+ // Try direct parse first
28
+ parsedContent = JSON.parse(content);
29
+ } catch {
30
+ // If LLM added explanation text, extract JSON block
31
+ const extracted = this.extractJsonObject(content);
32
+
33
+ if (!extracted) {
34
+ throw new Error("Could not extract valid JSON from LLM response");
35
+ }
36
+
37
+ parsedContent = extracted as FireFlinkLLMResponse;
38
+ }
39
+
40
+ const usage = llmOutput?.usage ?? {};
41
+
42
+ const inputTokens = Number(usage.prompt_tokens ?? 0);
43
+ const outputTokens = Number(usage.completion_tokens ?? 0);
44
+ const totalTokens = Number(usage.total_tokens ?? 0);
45
+
46
+ this.inputTokens += inputTokens;
47
+ this.outputTokens += outputTokens;
48
+ this.totalTokens += totalTokens;
49
+
50
+ return { response: parsedContent };
51
+
52
+ } catch (error) {
53
+ throw new Error(
54
+ "Failed to parse LLM output",
55
+ { cause: error }
56
+ );
57
+ }
58
+
59
+ }
60
+
61
+
62
+ public getTokenUsage() {
63
+ return {
64
+ inputTokens: this.inputTokens,
65
+ outputTokens: this.outputTokens,
66
+ totalTokens: this.totalTokens,
67
+ };
68
+ }
69
+ }
@@ -0,0 +1,16 @@
1
+ import { keywordExtractor } from "./systemPrompts/actionExtractorPrompt.js";
2
+ import { buildStepExtractionPrompt } from "./systemPrompts/userStoryToListPrompt.js";
3
+ import { buildErrorDescriptionPrompt } from "./systemPrompts/errorDescriptionPrompt.js";
4
+ import { ffInspectorNumExtractor } from "./systemPrompts/fireflinkElementIndexExtactors.js";
5
+ import { visionPrompt } from "./systemPrompts/visionPrompt.js";
6
+ import { PromptMap } from "../../core/types/promptMap.js";
7
+
8
+
9
+ export const prompts: PromptMap = {
10
+ userStoryToList: buildStepExtractionPrompt,
11
+ keywordExtractorPrompt: keywordExtractor,
12
+ errorDescriptionPrompt: buildErrorDescriptionPrompt,
13
+ ffInspectorNumExtractor: ffInspectorNumExtractor,
14
+ visionPrompt: visionPrompt,
15
+ };
16
+
@@ -0,0 +1,70 @@
1
+
2
+ type keywordExtractor = {
3
+ priorAndNextSteps: string[];
4
+
5
+ };
6
+ export async function keywordExtractor(
7
+ { priorAndNextSteps }: keywordExtractor
8
+ ): Promise<string> {
9
+
10
+ const allowedActions: string[] = [
11
+ "enter",
12
+ "wait",
13
+ "verify",
14
+ "scroll",
15
+ "navigate",
16
+ "click",
17
+ "maximize",
18
+ "get",
19
+ "upload",
20
+ "close",
21
+ "open",
22
+ "drag_and_drop",
23
+ "switch"
24
+ ];
25
+
26
+ const prompt = `
27
+ You are an expert in Web application testing.
28
+ From the step: step, extract ONLY the meaningful keywords so that i can search for the element in the dom.
29
+
30
+ Rules:
31
+ - Only give response for the current step .
32
+ - understand the step and context from the ${JSON.stringify(priorAndNextSteps)} and keywords should be from step.
33
+ - 3 to 5 keywords maximum.
34
+ - If the step is about entering text or Uploading file, Should NOT include input value from the step into keywords.
35
+ - If the step has words like tag name audio, video, image, svg, checkbox etc, include them in the keywords.
36
+ - If icon is mentioned in step then 'svg' should add in keywords and for Upload action first keyword should be 'file'.
37
+ - First keyword should be from step. Next keywords must be distinct and based on element label meaning only.
38
+ - If keyword is two words, then create an additional keyword by combining them.
39
+ Example: "Sign In" → "Sign In", "SignIn"
40
+ - Keywords can be string or number.
41
+ - Do NOT include generic UI words or action words.
42
+ - Do NOT include status or technical words.
43
+ - If element label contains multiple words, keep them together as ONE keyword.
44
+ - element_name: extract name of the element from step.
45
+ Capitalize first letter.
46
+ If not mentioned, return action as element_name.
47
+ - action rules:
48
+ click, enter, wait, scroll, navigate, get, maximize, close, open,
49
+ upload, drag_and_drop, switch
50
+ - action must be one of ${JSON.stringify(allowedActions)}.
51
+ If not, return "0".
52
+ - For navigate:
53
+ - keywords must contain ONLY full URL
54
+ - element_name must be "URL"
55
+ - navigate allowed ONLY if step intent is purely navigation
56
+ - If verification intent exists, MUST return "verify"
57
+
58
+ Respond only with JSON using this format:
59
+ {
60
+ "keywords": [],
61
+ "elementName": "",
62
+ "elementType":""
63
+ "action": ""
64
+ }
65
+
66
+ No other text.
67
+ `;
68
+
69
+ return prompt;
70
+ }
@@ -0,0 +1,23 @@
1
+ export async function buildErrorDescriptionPrompt(): Promise<string> {
2
+ const description_prompt = `
3
+
4
+ Analyze the error and execution history to provide diagnostics in JSON format.
5
+
6
+ Return a JSON object with the following keys:
7
+ 1. "error": A concise, single-line, selenium type(error).__name__ (e.g., "InvalidSessionIdException", "InvalidElementStateException", "ElementNotInteractableException", "NoSuchElementException" etc).
8
+ 2. "errorDescription": A very simple, non-technical, and user-friendly explanation of why the automation might have failed.
9
+ - Use plain English.
10
+ - All the lines should contain FireFlink. example: "FireFlink was unable to find the element..."
11
+ - Do not mention code, XPaths, or internal technical terms.
12
+ - The output MUST be a single paragraph of exactly 10 to 15 lines of text.
13
+ - Focus on potential real-world causes.
14
+
15
+ Respond only with JSON using this format:
16
+ {
17
+ "error": ",
18
+ "errorDescription": "",
19
+ }
20
+ `;
21
+
22
+ return description_prompt;
23
+ }