@appclaw/vision 1.1.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.
- package/README.md +27 -0
- package/dist/src/coordinates.d.ts +29 -0
- package/dist/src/coordinates.d.ts.map +1 -0
- package/dist/src/coordinates.js +92 -0
- package/dist/src/coordinates.js.map +1 -0
- package/dist/src/geminiClient.d.ts +54 -0
- package/dist/src/geminiClient.d.ts.map +1 -0
- package/dist/src/geminiClient.js +268 -0
- package/dist/src/geminiClient.js.map +1 -0
- package/dist/src/generated/promptB64.d.ts +10 -0
- package/dist/src/generated/promptB64.d.ts.map +1 -0
- package/dist/src/generated/promptB64.js +15 -0
- package/dist/src/generated/promptB64.js.map +1 -0
- package/dist/src/index.d.ts +29 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +39 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/instructionParser.d.ts +24 -0
- package/dist/src/instructionParser.d.ts.map +1 -0
- package/dist/src/instructionParser.js +119 -0
- package/dist/src/instructionParser.js.map +1 -0
- package/dist/src/openaiCompatClient.d.ts +28 -0
- package/dist/src/openaiCompatClient.d.ts.map +1 -0
- package/dist/src/openaiCompatClient.js +119 -0
- package/dist/src/openaiCompatClient.js.map +1 -0
- package/dist/src/promptCodec.d.ts +2 -0
- package/dist/src/promptCodec.d.ts.map +1 -0
- package/dist/src/promptCodec.js +13 -0
- package/dist/src/promptCodec.js.map +1 -0
- package/dist/src/prompts.d.ts +7 -0
- package/dist/src/prompts.d.ts.map +1 -0
- package/dist/src/prompts.js +19 -0
- package/dist/src/prompts.js.map +1 -0
- package/dist/src/types.d.ts +86 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +11 -0
- package/dist/src/types.js.map +1 -0
- package/package.json +48 -0
package/README.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# @appclaw/vision
|
|
2
|
+
|
|
3
|
+
AI-powered vision element detection for [AppClaw](https://github.com/appclawhq/AppClaw) — locates on-screen UI elements from a screenshot using Gemini / OpenAI-compatible vision models.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @appclaw/vision
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { StarkVisionClient, parseInstruction } from '@appclaw/vision';
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Develop
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install
|
|
21
|
+
npm run build
|
|
22
|
+
npm run typecheck
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## License
|
|
26
|
+
|
|
27
|
+
MIT
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coordinate scaling and parsing utilities.
|
|
3
|
+
* Adapted from appium-stark-vision/src/utils.ts
|
|
4
|
+
*/
|
|
5
|
+
import { BoundingBox, ScreenSize } from './types';
|
|
6
|
+
/**
|
|
7
|
+
* Scale normalized coordinates (0-1000) to device pixel coordinates.
|
|
8
|
+
* Gemini returns [y_min, x_min] in 0-1000 scale.
|
|
9
|
+
* Source: appium-stark-vision/src/utils.ts:138-181
|
|
10
|
+
*/
|
|
11
|
+
export declare function scaleCoordinates(coordinates: [number, number], screenSize: ScreenSize): BoundingBox;
|
|
12
|
+
/**
|
|
13
|
+
* Find the first substring enclosed in square brackets.
|
|
14
|
+
* Used to extract bounding box arrays from LLM responses.
|
|
15
|
+
* Source: appium-stark-vision/src/utils.ts:183-186
|
|
16
|
+
*/
|
|
17
|
+
export declare function findSubstringWithBrackets(message: string): string | null;
|
|
18
|
+
/**
|
|
19
|
+
* Parse a bracket-enclosed string like "[320, 500]" into number array.
|
|
20
|
+
* Source: appium-stark-vision/src/utils.ts:188-194
|
|
21
|
+
*/
|
|
22
|
+
export declare function sanitizeOutput(arrayAsString: string): number[];
|
|
23
|
+
/**
|
|
24
|
+
* Parse a string response from LLM into a JSON object.
|
|
25
|
+
* Handles escaped JSON, markdown code blocks, etc.
|
|
26
|
+
* Source: appium-stark-vision/src/utils.ts:251-283
|
|
27
|
+
*/
|
|
28
|
+
export declare function parseStringToObject(str: string): any;
|
|
29
|
+
//# sourceMappingURL=coordinates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinates.d.ts","sourceRoot":"","sources":["../../src/coordinates.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAElD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7B,UAAU,EAAE,UAAU,GACrB,WAAW,CAkBb;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGxE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,CAM9D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CA+BpD"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Coordinate scaling and parsing utilities.
|
|
4
|
+
* Adapted from appium-stark-vision/src/utils.ts
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.scaleCoordinates = scaleCoordinates;
|
|
8
|
+
exports.findSubstringWithBrackets = findSubstringWithBrackets;
|
|
9
|
+
exports.sanitizeOutput = sanitizeOutput;
|
|
10
|
+
exports.parseStringToObject = parseStringToObject;
|
|
11
|
+
/**
|
|
12
|
+
* Scale normalized coordinates (0-1000) to device pixel coordinates.
|
|
13
|
+
* Gemini returns [y_min, x_min] in 0-1000 scale.
|
|
14
|
+
* Source: appium-stark-vision/src/utils.ts:138-181
|
|
15
|
+
*/
|
|
16
|
+
function scaleCoordinates(coordinates, screenSize) {
|
|
17
|
+
const { width, height } = screenSize;
|
|
18
|
+
const [y_min, x_min] = coordinates;
|
|
19
|
+
const sy = (value) => (value * height) / 1000;
|
|
20
|
+
const sx = (value) => (value * width) / 1000;
|
|
21
|
+
return {
|
|
22
|
+
corners: {
|
|
23
|
+
min: { x: sx(x_min), y: sy(y_min) },
|
|
24
|
+
max: { x: sx(x_min), y: sy(y_min) },
|
|
25
|
+
},
|
|
26
|
+
center: {
|
|
27
|
+
x: sx(x_min),
|
|
28
|
+
y: sy(y_min),
|
|
29
|
+
},
|
|
30
|
+
container: { width, height },
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Find the first substring enclosed in square brackets.
|
|
35
|
+
* Used to extract bounding box arrays from LLM responses.
|
|
36
|
+
* Source: appium-stark-vision/src/utils.ts:183-186
|
|
37
|
+
*/
|
|
38
|
+
function findSubstringWithBrackets(message) {
|
|
39
|
+
const match = message.match(/\[.*?\]/);
|
|
40
|
+
return match ? match[0] : null;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Parse a bracket-enclosed string like "[320, 500]" into number array.
|
|
44
|
+
* Source: appium-stark-vision/src/utils.ts:188-194
|
|
45
|
+
*/
|
|
46
|
+
function sanitizeOutput(arrayAsString) {
|
|
47
|
+
return arrayAsString
|
|
48
|
+
.slice(1, -1)
|
|
49
|
+
.trim()
|
|
50
|
+
.split(/[\s,]+/)
|
|
51
|
+
.map(Number);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Parse a string response from LLM into a JSON object.
|
|
55
|
+
* Handles escaped JSON, markdown code blocks, etc.
|
|
56
|
+
* Source: appium-stark-vision/src/utils.ts:251-283
|
|
57
|
+
*/
|
|
58
|
+
function parseStringToObject(str) {
|
|
59
|
+
// Strip markdown code block wrappers
|
|
60
|
+
const cleaned = str
|
|
61
|
+
.trim()
|
|
62
|
+
.replace(/(^```json\s*|```\s*$)/g, '')
|
|
63
|
+
.trim();
|
|
64
|
+
try {
|
|
65
|
+
return JSON.parse(cleaned);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
try {
|
|
69
|
+
// Handle escaped JSON string
|
|
70
|
+
const unescaped = JSON.parse(cleaned);
|
|
71
|
+
if (typeof unescaped === 'string') {
|
|
72
|
+
return JSON.parse(unescaped);
|
|
73
|
+
}
|
|
74
|
+
return unescaped;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
try {
|
|
78
|
+
// Handle escaped characters
|
|
79
|
+
const furtherCleaned = cleaned
|
|
80
|
+
.replace(/\\n/g, '\n')
|
|
81
|
+
.replace(/\\"/g, '"')
|
|
82
|
+
.replace(/\\'/g, "'")
|
|
83
|
+
.replace(/\\\\/g, '\\');
|
|
84
|
+
return JSON.parse(furtherCleaned);
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
throw new Error('Failed to parse LLM response as JSON');
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=coordinates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinates.js","sourceRoot":"","sources":["../../src/coordinates.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AASH,4CAqBC;AAOD,8DAGC;AAMD,wCAMC;AAOD,kDA+BC;AAtFD;;;;GAIG;AACH,SAAgB,gBAAgB,CAC9B,WAA6B,EAC7B,UAAsB;IAEtB,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC;IACrC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,WAAW,CAAC;IAEnC,MAAM,EAAE,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC;IACtD,MAAM,EAAE,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC;IAErD,OAAO;QACL,OAAO,EAAE;YACP,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE;YACnC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE;SACpC;QACD,MAAM,EAAE;YACN,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC;YACZ,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC;SACb;QACD,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;KAC7B,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAgB,yBAAyB,CAAC,OAAe;IACvD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACvC,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,SAAgB,cAAc,CAAC,aAAqB;IAClD,OAAO,aAAa;SACjB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;SACZ,IAAI,EAAE;SACN,KAAK,CAAC,QAAQ,CAAC;SACf,GAAG,CAAC,MAAM,CAAC,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,SAAgB,mBAAmB,CAAC,GAAW;IAC7C,qCAAqC;IACrC,MAAM,OAAO,GAAG,GAAG;SAChB,IAAI,EAAE;SACN,OAAO,CAAC,wBAAwB,EAAE,EAAE,CAAC;SACrC,IAAI,EAAE,CAAC;IAEV,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,CAAC;YACH,6BAA6B;YAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACtC,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;gBAClC,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YAC/B,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC;gBACH,4BAA4B;gBAC5B,MAAM,cAAc,GAAG,OAAO;qBAC3B,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC;qBACrB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;qBACpB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;qBACpB,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;gBAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YACpC,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gemini API client for stark-vision.
|
|
3
|
+
* Adapted from appium-stark-vision/src/llm/Gemini.ts
|
|
4
|
+
* Stripped: Langfuse tracing, LangfuseMedia, Zod schemas, plugin references.
|
|
5
|
+
*/
|
|
6
|
+
import { StarkVisionConfig } from './types';
|
|
7
|
+
export declare class StarkVisionClient {
|
|
8
|
+
private ai;
|
|
9
|
+
private model;
|
|
10
|
+
private disableThinking;
|
|
11
|
+
private localClient;
|
|
12
|
+
private onTokenUsage;
|
|
13
|
+
constructor(config: StarkVisionConfig);
|
|
14
|
+
/** Extract and emit token usage from a Gemini response's usageMetadata. */
|
|
15
|
+
private emitUsage;
|
|
16
|
+
/**
|
|
17
|
+
* Core Gemini call with retry logic.
|
|
18
|
+
* Adapted from appium-stark-vision/src/llm/Gemini.ts:21-164
|
|
19
|
+
*/
|
|
20
|
+
private createMessage;
|
|
21
|
+
/**
|
|
22
|
+
* Combined instruction + vision: parse instruction and locate element coordinates.
|
|
23
|
+
* Returns raw JSON string from Gemini.
|
|
24
|
+
* Adapted from appium-stark-vision/src/llm/Gemini.ts:251-277
|
|
25
|
+
*/
|
|
26
|
+
private static detectMimeType;
|
|
27
|
+
understandAndLocate(instruction: string, imageBase64: string): Promise<string>;
|
|
28
|
+
/**
|
|
29
|
+
* Check if an element is visible on the screenshot.
|
|
30
|
+
* Adapted from appium-stark-vision/src/llm/Gemini.ts:166-211
|
|
31
|
+
*/
|
|
32
|
+
isElementVisible(imageBase64: string, instruction: string, withExplanation?: boolean): Promise<string>;
|
|
33
|
+
/**
|
|
34
|
+
* Get bounding box coordinates for a specific element.
|
|
35
|
+
* Adapted from appium-stark-vision/src/services/BoundingBoxService.ts:142-204
|
|
36
|
+
*/
|
|
37
|
+
getBoundingBox(locator: string, imageBase64: string): Promise<string>;
|
|
38
|
+
/**
|
|
39
|
+
* Get element information / answer a question about the screen.
|
|
40
|
+
* Adapted from appium-stark-vision/src/llm/Gemini.ts:279-309
|
|
41
|
+
*/
|
|
42
|
+
getElementInfo(imageBase64: string, instruction: string, withExplanation?: boolean): Promise<string>;
|
|
43
|
+
/**
|
|
44
|
+
* Find back navigation element on the screen.
|
|
45
|
+
* Adapted from appium-stark-vision/src/llm/Gemini.ts:311-332
|
|
46
|
+
*/
|
|
47
|
+
findBackNavigation(imageBase64: string): Promise<string>;
|
|
48
|
+
/**
|
|
49
|
+
* Generate test code from execution history.
|
|
50
|
+
* Text-only Gemini call (no image).
|
|
51
|
+
*/
|
|
52
|
+
generateCode(systemPrompt: string, userPrompt: string): Promise<string>;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=geminiClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geminiClient.d.ts","sourceRoot":"","sources":["../../src/geminiClient.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAeH,OAAO,EAAE,iBAAiB,EAAoB,MAAM,SAAS,CAAC;AAE9D,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,EAAE,CAAc;IACxB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,WAAW,CAAmC;IACtD,OAAO,CAAC,YAAY,CAAkD;gBAE1D,MAAM,EAAE,iBAAiB;IAerC,2EAA2E;IAC3E,OAAO,CAAC,SAAS;IAWjB;;;OAGG;YACW,aAAa;IA8D3B;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;IAIvB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAyBpF;;;OAGG;IACG,gBAAgB,CACpB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,eAAe,UAAQ,GACtB,OAAO,CAAC,MAAM,CAAC;IA8BlB;;;OAGG;IACG,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAoD3E;;;OAGG;IACG,cAAc,CAClB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,eAAe,UAAQ,GACtB,OAAO,CAAC,MAAM,CAAC;IA0BlB;;;OAGG;IACG,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmB9D;;;OAGG;IACG,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAc9E"}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Gemini API client for stark-vision.
|
|
4
|
+
* Adapted from appium-stark-vision/src/llm/Gemini.ts
|
|
5
|
+
* Stripped: Langfuse tracing, LangfuseMedia, Zod schemas, plugin references.
|
|
6
|
+
*/
|
|
7
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.StarkVisionClient = void 0;
|
|
12
|
+
const genai_1 = require("@google/genai");
|
|
13
|
+
const async_retry_1 = __importDefault(require("async-retry"));
|
|
14
|
+
const openaiCompatClient_1 = require("./openaiCompatClient");
|
|
15
|
+
const prompts_1 = require("./prompts");
|
|
16
|
+
class StarkVisionClient {
|
|
17
|
+
constructor(config) {
|
|
18
|
+
this.localClient = null;
|
|
19
|
+
this.ai = new genai_1.GoogleGenAI({ apiKey: config.apiKey });
|
|
20
|
+
this.model = config.model;
|
|
21
|
+
this.disableThinking = config.disableThinking ?? false;
|
|
22
|
+
this.onTokenUsage = config.onTokenUsage;
|
|
23
|
+
if (config.baseUrl) {
|
|
24
|
+
this.localClient = new openaiCompatClient_1.OpenAICompatClient(config.baseUrl, config.model, config.apiKey, config.coordinateOrder ?? 'yx');
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/** Extract and emit token usage from a Gemini response's usageMetadata. */
|
|
28
|
+
emitUsage(usageMetadata) {
|
|
29
|
+
if (!this.onTokenUsage || !usageMetadata)
|
|
30
|
+
return;
|
|
31
|
+
this.onTokenUsage({
|
|
32
|
+
inputTokens: usageMetadata.promptTokenCount ?? 0,
|
|
33
|
+
outputTokens: usageMetadata.candidatesTokenCount ?? 0,
|
|
34
|
+
totalTokens: usageMetadata.totalTokenCount ?? 0,
|
|
35
|
+
cachedTokens: usageMetadata.cachedContentTokenCount || undefined,
|
|
36
|
+
thoughtsTokens: usageMetadata.thoughtsTokenCount || undefined,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Core Gemini call with retry logic.
|
|
41
|
+
* Adapted from appium-stark-vision/src/llm/Gemini.ts:21-164
|
|
42
|
+
*/
|
|
43
|
+
async createMessage(params) {
|
|
44
|
+
if (this.localClient) {
|
|
45
|
+
return this.localClient.createMessage(params);
|
|
46
|
+
}
|
|
47
|
+
const { system, contents, temperature = 0, maxTokens = 3000, responseMimeType = 'text/plain', } = params;
|
|
48
|
+
const response = await (0, async_retry_1.default)(async (bail) => {
|
|
49
|
+
try {
|
|
50
|
+
const config = {
|
|
51
|
+
...(this.disableThinking
|
|
52
|
+
? { thinkingConfig: { thinkingBudget: 0 } }
|
|
53
|
+
: { thinkingConfig: { thinkingLevel: genai_1.ThinkingLevel.MINIMAL } }),
|
|
54
|
+
temperature,
|
|
55
|
+
maxOutputTokens: maxTokens,
|
|
56
|
+
responseMimeType,
|
|
57
|
+
};
|
|
58
|
+
const result = await this.ai.models.generateContent({
|
|
59
|
+
model: this.model,
|
|
60
|
+
config: {
|
|
61
|
+
...config,
|
|
62
|
+
...(system ? { systemInstruction: system } : {}),
|
|
63
|
+
},
|
|
64
|
+
contents,
|
|
65
|
+
});
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
if (error.status === 400 || error.status === 401) {
|
|
70
|
+
bail(error);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
throw error;
|
|
74
|
+
}
|
|
75
|
+
}, {
|
|
76
|
+
retries: 3,
|
|
77
|
+
factor: 1,
|
|
78
|
+
minTimeout: 1000,
|
|
79
|
+
randomize: true,
|
|
80
|
+
});
|
|
81
|
+
this.emitUsage(response?.usageMetadata);
|
|
82
|
+
return response?.candidates?.[0]?.content?.parts?.[0]?.text || '';
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Combined instruction + vision: parse instruction and locate element coordinates.
|
|
86
|
+
* Returns raw JSON string from Gemini.
|
|
87
|
+
* Adapted from appium-stark-vision/src/llm/Gemini.ts:251-277
|
|
88
|
+
*/
|
|
89
|
+
static detectMimeType(base64) {
|
|
90
|
+
return base64.startsWith('/9j/') ? 'image/jpeg' : 'image/png';
|
|
91
|
+
}
|
|
92
|
+
async understandAndLocate(instruction, imageBase64) {
|
|
93
|
+
return this.createMessage({
|
|
94
|
+
system: prompts_1.combinedInstructionPrompt,
|
|
95
|
+
contents: [
|
|
96
|
+
{
|
|
97
|
+
role: 'user',
|
|
98
|
+
parts: [
|
|
99
|
+
{
|
|
100
|
+
inlineData: {
|
|
101
|
+
data: imageBase64,
|
|
102
|
+
mimeType: StarkVisionClient.detectMimeType(imageBase64),
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
text: instruction,
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
temperature: 0.1,
|
|
112
|
+
maxTokens: 1024,
|
|
113
|
+
responseMimeType: 'application/json',
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Check if an element is visible on the screenshot.
|
|
118
|
+
* Adapted from appium-stark-vision/src/llm/Gemini.ts:166-211
|
|
119
|
+
*/
|
|
120
|
+
async isElementVisible(imageBase64, instruction, withExplanation = false) {
|
|
121
|
+
const visibleCheckPrompt = withExplanation
|
|
122
|
+
? prompts_1.elementVisibilityWithExplanationPrompt
|
|
123
|
+
: prompts_1.elementVisibilityPrompt;
|
|
124
|
+
const prompt = `${visibleCheckPrompt} Can you see ${instruction} completely visible in the image?`;
|
|
125
|
+
return this.createMessage({
|
|
126
|
+
system: '',
|
|
127
|
+
contents: [
|
|
128
|
+
{
|
|
129
|
+
role: 'user',
|
|
130
|
+
parts: [
|
|
131
|
+
{
|
|
132
|
+
inlineData: {
|
|
133
|
+
data: imageBase64,
|
|
134
|
+
mimeType: StarkVisionClient.detectMimeType(imageBase64),
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
text: prompt,
|
|
139
|
+
},
|
|
140
|
+
],
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
temperature: 0,
|
|
144
|
+
maxTokens: 512,
|
|
145
|
+
responseMimeType: 'application/json',
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Get bounding box coordinates for a specific element.
|
|
150
|
+
* Adapted from appium-stark-vision/src/services/BoundingBoxService.ts:142-204
|
|
151
|
+
*/
|
|
152
|
+
async getBoundingBox(locator, imageBase64) {
|
|
153
|
+
const content = prompts_1.bboxPrompt.replace('${locator}', locator);
|
|
154
|
+
const promptConfig = [
|
|
155
|
+
{ text: content },
|
|
156
|
+
{
|
|
157
|
+
inlineData: { mimeType: StarkVisionClient.detectMimeType(imageBase64), data: imageBase64 },
|
|
158
|
+
},
|
|
159
|
+
];
|
|
160
|
+
const contents = [
|
|
161
|
+
{ role: 'model', parts: [{ text: content }] },
|
|
162
|
+
{ role: 'user', parts: promptConfig },
|
|
163
|
+
];
|
|
164
|
+
if (this.localClient) {
|
|
165
|
+
return this.localClient.createMessage({
|
|
166
|
+
system: '',
|
|
167
|
+
contents,
|
|
168
|
+
temperature: 0.1,
|
|
169
|
+
responseMimeType: 'text/plain',
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
const response = await (0, async_retry_1.default)(async () => {
|
|
173
|
+
try {
|
|
174
|
+
const result = await this.ai.models.generateContent({
|
|
175
|
+
model: this.model,
|
|
176
|
+
contents,
|
|
177
|
+
config: {
|
|
178
|
+
temperature: 0.1,
|
|
179
|
+
responseMimeType: 'text/plain',
|
|
180
|
+
...(this.disableThinking
|
|
181
|
+
? { thinkingConfig: { thinkingBudget: 0 } }
|
|
182
|
+
: { thinkingConfig: { thinkingLevel: genai_1.ThinkingLevel.MINIMAL } }),
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
return result;
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
}, {
|
|
191
|
+
retries: 3,
|
|
192
|
+
factor: 1,
|
|
193
|
+
minTimeout: 1000,
|
|
194
|
+
});
|
|
195
|
+
this.emitUsage(response?.usageMetadata);
|
|
196
|
+
return response?.candidates?.[0]?.content?.parts?.[0]?.text || '';
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Get element information / answer a question about the screen.
|
|
200
|
+
* Adapted from appium-stark-vision/src/llm/Gemini.ts:279-309
|
|
201
|
+
*/
|
|
202
|
+
async getElementInfo(imageBase64, instruction, withExplanation = false) {
|
|
203
|
+
const infoPrompt = withExplanation ? prompts_1.getInformationWithExplanationPrompt : prompts_1.getInformationPrompt;
|
|
204
|
+
return this.createMessage({
|
|
205
|
+
system: infoPrompt,
|
|
206
|
+
contents: [
|
|
207
|
+
{
|
|
208
|
+
role: 'user',
|
|
209
|
+
parts: [
|
|
210
|
+
{
|
|
211
|
+
inlineData: {
|
|
212
|
+
data: imageBase64,
|
|
213
|
+
mimeType: StarkVisionClient.detectMimeType(imageBase64),
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
text: instruction,
|
|
218
|
+
},
|
|
219
|
+
],
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
maxTokens: 512,
|
|
223
|
+
responseMimeType: 'application/json',
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Find back navigation element on the screen.
|
|
228
|
+
* Adapted from appium-stark-vision/src/llm/Gemini.ts:311-332
|
|
229
|
+
*/
|
|
230
|
+
async findBackNavigation(imageBase64) {
|
|
231
|
+
return this.createMessage({
|
|
232
|
+
system: prompts_1.backNavigationPrompt,
|
|
233
|
+
contents: [
|
|
234
|
+
{
|
|
235
|
+
role: 'user',
|
|
236
|
+
parts: [
|
|
237
|
+
{
|
|
238
|
+
inlineData: {
|
|
239
|
+
data: imageBase64,
|
|
240
|
+
mimeType: StarkVisionClient.detectMimeType(imageBase64),
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
],
|
|
244
|
+
},
|
|
245
|
+
],
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Generate test code from execution history.
|
|
250
|
+
* Text-only Gemini call (no image).
|
|
251
|
+
*/
|
|
252
|
+
async generateCode(systemPrompt, userPrompt) {
|
|
253
|
+
return this.createMessage({
|
|
254
|
+
system: systemPrompt,
|
|
255
|
+
contents: [
|
|
256
|
+
{
|
|
257
|
+
role: 'user',
|
|
258
|
+
parts: [{ text: userPrompt }],
|
|
259
|
+
},
|
|
260
|
+
],
|
|
261
|
+
temperature: 0,
|
|
262
|
+
maxTokens: 8192,
|
|
263
|
+
responseMimeType: 'text/plain',
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
exports.StarkVisionClient = StarkVisionClient;
|
|
268
|
+
//# sourceMappingURL=geminiClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geminiClient.js","sourceRoot":"","sources":["../../src/geminiClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const combinedInstructionPrompt: string;
|
|
2
|
+
export declare const elementVisibilityPrompt: string;
|
|
3
|
+
export declare const elementVisibilityWithExplanationPrompt: string;
|
|
4
|
+
export declare const bboxPrompt: string;
|
|
5
|
+
export declare const backNavigationPrompt: string;
|
|
6
|
+
export declare const getInformationWithExplanationPrompt: string;
|
|
7
|
+
export declare const getInformationPrompt: string;
|
|
8
|
+
export declare const createWDIOTestPrompt: string;
|
|
9
|
+
export declare const createAppiumJavaTestPrompt: string;
|
|
10
|
+
//# sourceMappingURL=promptB64.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promptB64.d.ts","sourceRoot":"","sources":["../../../src/generated/promptB64.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,yBAAyB,QAErC,CAAC;AACF,eAAO,MAAM,uBAAuB,QAEnC,CAAC;AACF,eAAO,MAAM,sCAAsC,QAElD,CAAC;AACF,eAAO,MAAM,UAAU,QAEtB,CAAC;AACF,eAAO,MAAM,oBAAoB,QAEhC,CAAC;AACF,eAAO,MAAM,mCAAmC,QAE/C,CAAC;AACF,eAAO,MAAM,oBAAoB,QAEhC,CAAC;AACF,eAAO,MAAM,oBAAoB,QAEhC,CAAC;AACF,eAAO,MAAM,0BAA0B,QAEtC,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createAppiumJavaTestPrompt = exports.createWDIOTestPrompt = exports.getInformationPrompt = exports.getInformationWithExplanationPrompt = exports.backNavigationPrompt = exports.bboxPrompt = exports.elementVisibilityWithExplanationPrompt = exports.elementVisibilityPrompt = exports.combinedInstructionPrompt = void 0;
|
|
4
|
+
/** Auto-generated by scripts/generate-prompt-b64.cjs from src/prompts.raw.ts — do not edit. */
|
|
5
|
+
const promptCodec_1 = require("../promptCodec");
|
|
6
|
+
exports.combinedInstructionPrompt = (0, promptCodec_1.decodeVisionPrompt)('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');
|
|
7
|
+
exports.elementVisibilityPrompt = (0, promptCodec_1.decodeVisionPrompt)('H4sIAAAAAAAAA31Ty27cMAy8+yuIXNoChnNPTw0aoCnQpOiihxxpi14zK4uuSG3WKAr0I/qF/ZJC8jq7faBHkdRoZjiqHiQBRoIpyp4dOXhiGwAD8IhbAgwOEL4kUmMJTfUgKYKh7oAVTIAdBeN+Bu7BBjreGlDLqU/eA3kaKdgCTAfsDEa0bijYQWDCaIx+KZI21QfcEWiKVDCSUgTUHblnJFYIYiB7ih6n6URabKC4jjXV7cLp7NqelVtPwEHZESA4Ri9bkAiTTGmqQcmgk+A4692gsfZMLku1mAh+fv+x4umKsoIuWFrs7KT0Irm13VT3wc//we/RK60+nnEe2DkKcH3z7vbu7YnyS26oqX8bpgOrKUgoVe0iUYA2FRRptUuR3OWZa+185kAAkwmkB7ZXxbqAxnuCUVo+ibssNl2O4tBDRsFY9sj53R5sngi8dJjVwURxZNUcnE9kKS68ZCrNfvH88/Smy+frZCYhxwYNniR5B+0SgJbUoGdrbrdBjqFYFl1Y6POeOajFVNBKAjHMOdaHkW0GzzuCQBhriLwdrAZPvdVZdA2tmMkIXmRXeJ2b2qKSO3qqdALMqtUid+Zn6MV7efqThTbVZp1wUhY0eeSQmdnAYQvYSrLTxylS2MAJ6bpPGH/7DpF0kpCDovCY1KAV8YQBUJcENbAx7nY5US1lUpJsSpZ1jWjNi9fVzWGizrKopYMK7zf3dyDtI3VWfa3+EdCr9Z26Ap3VaPyYd3de/nuZV3CRHQrbi7oq0bjvj7fWevWt+gUnEZ8GggQAAA==');
|
|
8
|
+
exports.elementVisibilityWithExplanationPrompt = (0, promptCodec_1.decodeVisionPrompt)('H4sIAAAAAAAAA31SzW7UMBC+5ylGvQBSlN4LQgJRiSLRIioOPU7iye50HY/xjLe7Qkg8BE/IkyA7m+4WEEd7PJ+/v+ZOMmAiiEm27MjBA9saMABPuCLA4ADhayY1ltA1d5ITGOoGWMEE2FEwHvfAI9iaDltr1Hoas/dAniYKNgPTDgeDCW1YV+wgEDEZo58vSbvmI24INCeqGFkpAeqG3CMSKwQxkC0ljzEeSYutKS3PuuZq5nSytmXl3hNwUHYECI7RywokQZSYYwtKBoMEx0XvLRrryOSKVEuZ4NePnwueLigL6Iyl1c5B6iyRW8ZdcxP8/j/4I3qlxccTzmt2jgK8vXx/df3uSPk5d9S1Tx7TjtUUJNRbHRJRgD5XFOl1yInc+Ylr/f7EgQAmEWQEthfVuoDGW4JJej6KO682nU/i0ENBwVRz5PLvCLaPBF4GLOogUppYtRTnM1lOMy+JdTjOnn+Jb4ZyfpvNJJTaoMGDZO+gnwvQkxqMbN3VKsihFHPQlYU+5sxBLeWKVhuIYV9qvZvY9uB5QxAIUwuJV2trwdNobRHdQi9mMoEX2VRep6b2qOQOniodAYtqtcSD+T2M4r08/MlCCzM2cEK6xAPTk3Yn0iih5K5wn9WgF/GEAVDnQnTPXjaXu0iDFRbZYrYy+3B7cw3S39NgzbfmH426WJDaBmgXPYaayQW8Ojm9bhvQvRpNn0oSpzt/R3MBZ0VvWJ21DdSkb8bD2jJovje/ATfufGJRBAAA');
|
|
9
|
+
exports.bboxPrompt = (0, promptCodec_1.decodeVisionPrompt)('H4sIAAAAAAAAA2WOwWrDQAxE7/6KOfTomv5F6KEtlEIPIQQlq8RL15LRalMvIf9ess6tIBCaYfTmeyRHzPCRcdAiIcoZB11wUmvi0zXpkVztNnRv9MPIxbg5R31WC1HIOYOMIerQC1uieeaA3+gjSCqEycCJJxbPQ/d6avGHgKCc8f7xBV5idkRpbpzozD2MvZhg+9LjMTuQhDtqvDfllHnoNvHCmNZWWnwuDsogAZlRxbbupyg9lnXV/URLu2jZDfhcESqptgdr5h/kD7bnbQIpAQAA');
|
|
10
|
+
exports.backNavigationPrompt = (0, promptCodec_1.decodeVisionPrompt)('H4sIAAAAAAAAA42Sy24aQRBF9/0VV3hhCaGR7OzYGQVFXsRYESyyo2amYCo0Xa3uGh6K8u9RDwYUJYts+3VP3dPuu/agxIhJD9Jyi6NYBwqQPW0ZugFhr7V4BsXopSETDRNQaHHWPsEo7yAZppCWg8nmDApnsOc9B4MGWMfYyoGvj1pHBvJej3nY6zOncj/QQbZkjJqaXVkomzHxQbTPyE1iDpVz4zEWq+X7aonx2D1V6CjPL2FTzFQ9U8CBfM9IHBPnAhW2OHZsXQnqODH4JNlyGfQKOlA1FFAPRC02mgaSI6X2yiYaKvdcXS9N8YJOtp0/o2Uj8dyi5dwkieVoqa/MsHq9pUgAIUvYeoaXwPfYjn2813Hr4t81TCCh8X1bBsuRG9lIk5H7pgNlGJ9sgqhZLrKkKRbOkQdtiT2ZHPh2oHLu9ev74tvy5W2Jt8VyPsVnRVD7CGGM1uv1j6xhVPgLjvYWe6uKi/mJ9tFzkfHwVLmfDn8YsdTzxOHe2GhW1AyKKSU9Xug+volphOeNodEUOI3cL+cenv9+dUM+87D56X8iv5TOUPdmGuCp5iLqcUbN7vGafBeMmhLIhtVazXRfMH4Dnksc2yoDAAA=');
|
|
11
|
+
exports.getInformationWithExplanationPrompt = (0, promptCodec_1.decodeVisionPrompt)('H4sIAAAAAAAAA72SMW/CMBCF9/sVJ7NFiKodo4itQzvAQDswmnDELuQusi+QCvHfqzgtUHWokKpuvif583vPB0tp0QbCyu+J0TL62laEltdp4KihLdULT/A1EqojNNQ1O8u2Vw2qgDrPW/SK6oK0lUu3t0RNr0VfNzsaJ00dMQaKjfAaD17dwLMcDxTMBB67hkqlNUqrTatoIz4v5jOU1RuVmhAsip4HOWrwXMERBkCOxXCYwpXDHIuraQonKKizvacpjO4nkGVP3L+1IFbikvIsQ7On4DfvSDuqifXTKnWKtlXBSFYxur62JlAkVgNZdjY/T+bzLIMjfGXL0SwpjlPe36k+nsFj+FZ3jublRgQK40pUpcbgK6dYSmAKKJvkJpaBiC+/8QNUCk8MnGD08I9lzeSGrvqd+IO+rjB9Z5dyUvzi7rw2H2Rypiw1AwAA');
|
|
12
|
+
exports.getInformationPrompt = (0, promptCodec_1.decodeVisionPrompt)('H4sIAAAAAAAAA7VSO0/DMBDe/StO6QIWagVsUVXEwFCEWqQuhM0xR2KUnCPfuQ2q+t+RE1Fg4LGw+fE97vNnVfgIJiBUbosEhsC1pkIw9DRsiCVEK87TVN03aBghoMRAcA1dQOt4xHK01pGAId5hAPEgNQL2EowVEOzlq9ZN36EVfAIfpYsChuF2s16BL1/QyiBJPnHGY5bgqJqqvRoNcpiPi4U6qDn2pu0aXKjJ+VRpvaSkuEESJIu51pBtMbjnV+hqTzhrkTlldNYTOAazNa4xZYOZ0vo42HoYLNda7VU2mmU5ZAXy2ZDtFy3g2u8cVSnZO+iheISdk/qDD2UsE3igexou2AZEytRBTS7+Pc7K/5QmVfBJ7qAml99MtOSx8AZbJIE7X/ko6YcwklzBSYE8W/nTP75wsprPjrW+AX8xYDmlAgAA');
|
|
13
|
+
exports.createWDIOTestPrompt = (0, promptCodec_1.decodeVisionPrompt)('H4sIAAAAAAAAA1WRT2vbQBDF7/oUj1xkg1CUtFCQcUFNDjU02CQpPYa1dhwNkXbU3Vk7xvi7F0kNOIeFZd78/b2k9mSUYKAUFCGyEnbioQ3hlfcE4705QnYISn2AcRZBPdfaHmHFpQpjLYw7gt771hllcTnuPyl/7ldr1NJ1Q/X4rE0Mz66eTQ9x4E0jjq7mH9o4fUutHFCLJaiMkY60ETvsIlH7qGAXeJAbgqVQ85awbaV+y5NaXFAYxhImHF2NGbugPtbDenMsv+OUAJ40egdzMKywnvfkc3qnOirN0j0HFldix87+OFarNBtrgItO2RiQfviHBDjPF8l5kVRtELCr22gJ1Qq76Mb08T4rbvEZmpmoTXC14QAOowlV33PsclT/kXj6G9mTHa5lT/Wd6c2WW1amqcA464Unxrx+yjFu0pk3Qoh+IjUZ3UhsLbaEg/g3dq857mSk6Se3JiaeOlGanZDn+RB+2VSP1cNThvpy8nm+mIomFcYTJgOqzWb1++Hl5/rpGUukN7ff8iIv8pt0kXxK2Kwfh4Sv326/fCgX47DEaYg6Gik+kvrjnUSnJYosaSSoMx2Vl9OypBev5WX/LOmNNiXS64O9buL2Os2SVl5/0Z7aEim7naRZMpy9E//MHUnUEjdFURRZ0kndmHWvocQp0Q/xdhLP2WD6P+3jD3JLAwAA');
|
|
14
|
+
exports.createAppiumJavaTestPrompt = (0, promptCodec_1.decodeVisionPrompt)('H4sIAAAAAAAAA51U32/iOBB+918x4gkkGlp6p5VYrbRZqLpIuw0iobo3ZJyBjNbxRP4B7Z72fz85pAV6vdPp8hLbM5/9fZ89I6YWpUeQ4NF5UFo6B1u24CuEHe3RgLRWPgNvwXlsHBzIVxw8SPMM+NRoaaQnNi6BosLjLq7ioEvAJ4+mhC/SYRGXpSkhOARJX1E3aBNJ/UF7WDoHxXUtTekSyIJvggc2+rllobhuNHo8ZxhJtMEta80HMjtw3gblg8WJEFQ3bD2w3SURZHaJNIZ9RzSS+ShEEzaaVLfhPRq00mPZMj0ydyfqfwoAgM9x3I467J6pbGnlCo20xP1Blxq/0Qha8NG34CLLC+1t5i/xS4ho3YVP6Xx6NOSYfmSJDqRFkNqiLJ/BoYfQtF5MxBWkTUOhnlnaowUy5Elq+tlqjtFXi6FGX3HpxFVL7+EezswRV5CjjTsoNlvaBduuTwRAuljMV9/XX7O8gE/Quxl/SK6T6+Smd4otsmWM/fZhfHtazO+Wj3fL9Wr5LcIq75vJaPSKnsTk0aEcVWHTEyI1pY2mKtnIDWnyhG4iVpQGz7X0bMdZ0xIF7v6fwOAB3sno/E0c+i5GbB5kjf3LaZI+zJbZfLZezdNVkX1Pi2w5PmFnuCeFLa7Xseudogst/ZZt/YjWEZt+72acXJ/FH/DQXWRBNXLw/VlnacLbHBWb0vVvrweDj0JQlr/R/cd0NY939L7mN9H/rHee5euIXRd3efG+UFpUbPBfdf7+v3Wme0labjTGR9k9xom4SS6Ko0fmWNHEpjeAq1gepM6esRifAfAJVfD4WjWX8CE4uceCp1JVOATUWKPxj+Roo3FaofoxhFo+5cqy1m4Irh3k9BPjwWm5l0ZheX727QXZe/Rzs+W/c75H/3IakIn+HctRvLSbU5d729z+sWmcdcoZg+G4s9KhxLYjO/ShAcVl1HnWnYfAFmRZUpxJ/dJPEvEXSDqHqwEGAAA=');
|
|
15
|
+
//# sourceMappingURL=promptB64.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promptB64.js","sourceRoot":"","sources":["../../../src/generated/promptB64.ts"],"names":[],"mappings":";;;AAAA,+FAA+F;AAC/F,gDAAoD;AAEvC,QAAA,yBAAyB,GAAG,IAAA,gCAAkB,EACzD,s1FAAs1F,CACv1F,CAAC;AACW,QAAA,uBAAuB,GAAG,IAAA,gCAAkB,EACvD,8xBAA8xB,CAC/xB,CAAC;AACW,QAAA,sCAAsC,GAAG,IAAA,gCAAkB,EACtE,0vBAA0vB,CAC3vB,CAAC;AACW,QAAA,UAAU,GAAG,IAAA,gCAAkB,EAC1C,8RAA8R,CAC/R,CAAC;AACW,QAAA,oBAAoB,GAAG,IAAA,gCAAkB,EACpD,0mBAA0mB,CAC3mB,CAAC;AACW,QAAA,mCAAmC,GAAG,IAAA,gCAAkB,EACnE,kcAAkc,CACnc,CAAC;AACW,QAAA,oBAAoB,GAAG,IAAA,gCAAkB,EACpD,sbAAsb,CACvb,CAAC;AACW,QAAA,oBAAoB,GAAG,IAAA,gCAAkB,EACpD,srBAAsrB,CACvrB,CAAC;AACW,QAAA,0BAA0B,GAAG,IAAA,gCAAkB,EAC1D,k+BAAk+B,CACn+B,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* df-vision (npm) — Device Farm packages/stark-vision
|
|
3
|
+
*
|
|
4
|
+
* AI-powered vision element detection for device-farm.
|
|
5
|
+
* Core logic extracted from appium-stark-vision, stripped of Appium/Prisma/Langfuse dependencies.
|
|
6
|
+
*/
|
|
7
|
+
import { findSubstringWithBrackets, parseStringToObject, sanitizeOutput, scaleCoordinates } from './coordinates';
|
|
8
|
+
import { StarkVisionClient } from './geminiClient';
|
|
9
|
+
import { detectSimpleAction, parseInstruction } from './instructionParser';
|
|
10
|
+
export { StarkVisionClient } from './geminiClient';
|
|
11
|
+
export { parseInstruction, detectSimpleAction, SUPPORTED_ACTIONS } from './instructionParser';
|
|
12
|
+
export { scaleCoordinates, findSubstringWithBrackets, sanitizeOutput, parseStringToObject, } from './coordinates';
|
|
13
|
+
/** Prompt text lives in ./prompts (internal); not re-exported so npm typings do not publish prompt bodies. */
|
|
14
|
+
export type { StarkVisionAction, StarkVisionConfig, VisionTokenUsage, BoundingBox, ScreenSize, ExecutionConfig, ScrollSize, CommandType, VisibilityResult, } from './types';
|
|
15
|
+
export { DefaultExecutionConfig } from './types';
|
|
16
|
+
/** CJS `default` for consumers that use `import pkg from 'df-vision'` under ESM (e.g. AppClaw). */
|
|
17
|
+
declare const _default: {
|
|
18
|
+
StarkVisionClient: typeof StarkVisionClient;
|
|
19
|
+
parseInstruction: typeof parseInstruction;
|
|
20
|
+
detectSimpleAction: typeof detectSimpleAction;
|
|
21
|
+
SUPPORTED_ACTIONS: string[];
|
|
22
|
+
scaleCoordinates: typeof scaleCoordinates;
|
|
23
|
+
findSubstringWithBrackets: typeof findSubstringWithBrackets;
|
|
24
|
+
sanitizeOutput: typeof sanitizeOutput;
|
|
25
|
+
parseStringToObject: typeof parseStringToObject;
|
|
26
|
+
DefaultExecutionConfig: import("./types").ExecutionConfig;
|
|
27
|
+
};
|
|
28
|
+
export default _default;
|
|
29
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EACjB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAqB,MAAM,qBAAqB,CAAC;AAG9F,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,EACL,gBAAgB,EAChB,yBAAyB,EACzB,cAAc,EACd,mBAAmB,GACpB,MAAM,eAAe,CAAC;AACvB,8GAA8G;AAC9G,YAAY,EACV,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,eAAe,EACf,UAAU,EACV,WAAW,EACX,gBAAgB,GACjB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAEjD,mGAAmG;;;;;;;;;;;;AACnG,wBAUE"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* df-vision (npm) — Device Farm packages/stark-vision
|
|
4
|
+
*
|
|
5
|
+
* AI-powered vision element detection for device-farm.
|
|
6
|
+
* Core logic extracted from appium-stark-vision, stripped of Appium/Prisma/Langfuse dependencies.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.DefaultExecutionConfig = exports.parseStringToObject = exports.sanitizeOutput = exports.findSubstringWithBrackets = exports.scaleCoordinates = exports.SUPPORTED_ACTIONS = exports.detectSimpleAction = exports.parseInstruction = exports.StarkVisionClient = void 0;
|
|
10
|
+
const coordinates_1 = require("./coordinates");
|
|
11
|
+
const geminiClient_1 = require("./geminiClient");
|
|
12
|
+
const instructionParser_1 = require("./instructionParser");
|
|
13
|
+
const types_1 = require("./types");
|
|
14
|
+
var geminiClient_2 = require("./geminiClient");
|
|
15
|
+
Object.defineProperty(exports, "StarkVisionClient", { enumerable: true, get: function () { return geminiClient_2.StarkVisionClient; } });
|
|
16
|
+
var instructionParser_2 = require("./instructionParser");
|
|
17
|
+
Object.defineProperty(exports, "parseInstruction", { enumerable: true, get: function () { return instructionParser_2.parseInstruction; } });
|
|
18
|
+
Object.defineProperty(exports, "detectSimpleAction", { enumerable: true, get: function () { return instructionParser_2.detectSimpleAction; } });
|
|
19
|
+
Object.defineProperty(exports, "SUPPORTED_ACTIONS", { enumerable: true, get: function () { return instructionParser_2.SUPPORTED_ACTIONS; } });
|
|
20
|
+
var coordinates_2 = require("./coordinates");
|
|
21
|
+
Object.defineProperty(exports, "scaleCoordinates", { enumerable: true, get: function () { return coordinates_2.scaleCoordinates; } });
|
|
22
|
+
Object.defineProperty(exports, "findSubstringWithBrackets", { enumerable: true, get: function () { return coordinates_2.findSubstringWithBrackets; } });
|
|
23
|
+
Object.defineProperty(exports, "sanitizeOutput", { enumerable: true, get: function () { return coordinates_2.sanitizeOutput; } });
|
|
24
|
+
Object.defineProperty(exports, "parseStringToObject", { enumerable: true, get: function () { return coordinates_2.parseStringToObject; } });
|
|
25
|
+
var types_2 = require("./types");
|
|
26
|
+
Object.defineProperty(exports, "DefaultExecutionConfig", { enumerable: true, get: function () { return types_2.DefaultExecutionConfig; } });
|
|
27
|
+
/** CJS `default` for consumers that use `import pkg from 'df-vision'` under ESM (e.g. AppClaw). */
|
|
28
|
+
exports.default = {
|
|
29
|
+
StarkVisionClient: geminiClient_1.StarkVisionClient,
|
|
30
|
+
parseInstruction: instructionParser_1.parseInstruction,
|
|
31
|
+
detectSimpleAction: instructionParser_1.detectSimpleAction,
|
|
32
|
+
SUPPORTED_ACTIONS: instructionParser_1.SUPPORTED_ACTIONS,
|
|
33
|
+
scaleCoordinates: coordinates_1.scaleCoordinates,
|
|
34
|
+
findSubstringWithBrackets: coordinates_1.findSubstringWithBrackets,
|
|
35
|
+
sanitizeOutput: coordinates_1.sanitizeOutput,
|
|
36
|
+
parseStringToObject: coordinates_1.parseStringToObject,
|
|
37
|
+
DefaultExecutionConfig: types_1.DefaultExecutionConfig,
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,+CAKuB;AACvB,iDAAmD;AACnD,2DAA8F;AAC9F,mCAAiD;AAEjD,+CAAmD;AAA1C,iHAAA,iBAAiB,OAAA;AAC1B,yDAA8F;AAArF,qHAAA,gBAAgB,OAAA;AAAE,uHAAA,kBAAkB,OAAA;AAAE,sHAAA,iBAAiB,OAAA;AAChE,6CAKuB;AAJrB,+GAAA,gBAAgB,OAAA;AAChB,wHAAA,yBAAyB,OAAA;AACzB,6GAAA,cAAc,OAAA;AACd,kHAAA,mBAAmB,OAAA;AAcrB,iCAAiD;AAAxC,+GAAA,sBAAsB,OAAA;AAE/B,mGAAmG;AACnG,kBAAe;IACb,iBAAiB,EAAjB,gCAAiB;IACjB,gBAAgB,EAAhB,oCAAgB;IAChB,kBAAkB,EAAlB,sCAAkB;IAClB,iBAAiB,EAAjB,qCAAiB;IACjB,gBAAgB,EAAhB,8BAAgB;IAChB,yBAAyB,EAAzB,uCAAyB;IACzB,cAAc,EAAd,4BAAc;IACd,mBAAmB,EAAnB,iCAAmB;IACnB,sBAAsB,EAAtB,8BAAsB;CACvB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Instruction parsing — converts natural language to structured actions.
|
|
3
|
+
* Adapted from appium-stark-vision/src/llm.ts
|
|
4
|
+
*/
|
|
5
|
+
import { StarkVisionClient } from './geminiClient';
|
|
6
|
+
import { StarkVisionAction } from './types';
|
|
7
|
+
/**
|
|
8
|
+
* Detect simple actions (scroll, back) without calling LLM.
|
|
9
|
+
* Returns null if instruction doesn't match any simple pattern.
|
|
10
|
+
* Source: appium-stark-vision/src/llm.ts:31-47
|
|
11
|
+
*/
|
|
12
|
+
export declare function detectSimpleAction(instruction: string): StarkVisionAction | null;
|
|
13
|
+
/**
|
|
14
|
+
* Parse an instruction using Gemini vision + the combined instruction prompt.
|
|
15
|
+
* Takes a screenshot and instruction, returns structured actions with coordinates.
|
|
16
|
+
* Source: appium-stark-vision/src/llm.ts:55-151 (understandUserInstruction)
|
|
17
|
+
*/
|
|
18
|
+
export declare function parseInstruction(client: StarkVisionClient, instruction: string, screenshotBase64: string): Promise<StarkVisionAction[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Supported actions list.
|
|
21
|
+
* Source: appium-stark-vision/src/services/ActionService.ts:13-36
|
|
22
|
+
*/
|
|
23
|
+
export declare const SUPPORTED_ACTIONS: string[];
|
|
24
|
+
//# sourceMappingURL=instructionParser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instructionParser.d.ts","sourceRoot":"","sources":["../../src/instructionParser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAyB5C;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAoBhF;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,iBAAiB,EACzB,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAsB9B;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,UAmC7B,CAAC"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Instruction parsing — converts natural language to structured actions.
|
|
4
|
+
* Adapted from appium-stark-vision/src/llm.ts
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.SUPPORTED_ACTIONS = void 0;
|
|
8
|
+
exports.detectSimpleAction = detectSimpleAction;
|
|
9
|
+
exports.parseInstruction = parseInstruction;
|
|
10
|
+
const coordinates_1 = require("./coordinates");
|
|
11
|
+
/**
|
|
12
|
+
* Simple action patterns that bypass the LLM entirely.
|
|
13
|
+
* Source: appium-stark-vision/src/llm.ts:24-47
|
|
14
|
+
*/
|
|
15
|
+
const SIMPLE_ACTION_PATTERNS = [
|
|
16
|
+
{ pattern: /^(scroll|swipe|move|slide)\s*(up|upwards)$/i, action: 'up' },
|
|
17
|
+
{ pattern: /^(scroll|swipe|move|slide)\s*(down|downwards)$/i, action: 'down' },
|
|
18
|
+
{ pattern: /^(scroll|swipe|move|slide)\s*(left|leftwards)$/i, action: 'left' },
|
|
19
|
+
{ pattern: /^(scroll|swipe|move|slide)\s*(right|rightwards)$/i, action: 'right' },
|
|
20
|
+
{
|
|
21
|
+
pattern: /^(scroll|swipe)\s*(up|down)\s*by\s*(\d+)%?$/i,
|
|
22
|
+
action: 'up',
|
|
23
|
+
valueExtractor: m => m[3],
|
|
24
|
+
},
|
|
25
|
+
{ pattern: /^(go\s*)?back$/i, action: 'back' },
|
|
26
|
+
{ pattern: /^(go\s*)?home$/i, action: 'home' },
|
|
27
|
+
{ pattern: /^(navigate\s*)?home$/i, action: 'home' },
|
|
28
|
+
];
|
|
29
|
+
/**
|
|
30
|
+
* Detect simple actions (scroll, back) without calling LLM.
|
|
31
|
+
* Returns null if instruction doesn't match any simple pattern.
|
|
32
|
+
* Source: appium-stark-vision/src/llm.ts:31-47
|
|
33
|
+
*/
|
|
34
|
+
function detectSimpleAction(instruction) {
|
|
35
|
+
const trimmed = instruction.trim();
|
|
36
|
+
for (const { pattern, action, valueExtractor } of SIMPLE_ACTION_PATTERNS) {
|
|
37
|
+
const match = trimmed.match(pattern);
|
|
38
|
+
if (match) {
|
|
39
|
+
const directionMatch = match[2]?.toLowerCase();
|
|
40
|
+
const resolvedAction = action === 'up' && directionMatch === 'down'
|
|
41
|
+
? 'down'
|
|
42
|
+
: action === 'down' && directionMatch === 'up'
|
|
43
|
+
? 'up'
|
|
44
|
+
: action;
|
|
45
|
+
return {
|
|
46
|
+
action: resolvedAction,
|
|
47
|
+
value: valueExtractor ? valueExtractor(match) : null,
|
|
48
|
+
locators: [],
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Parse an instruction using Gemini vision + the combined instruction prompt.
|
|
56
|
+
* Takes a screenshot and instruction, returns structured actions with coordinates.
|
|
57
|
+
* Source: appium-stark-vision/src/llm.ts:55-151 (understandUserInstruction)
|
|
58
|
+
*/
|
|
59
|
+
async function parseInstruction(client, instruction, screenshotBase64) {
|
|
60
|
+
const response = await client.understandAndLocate(instruction, screenshotBase64);
|
|
61
|
+
const cleanedText = response.trim().replace(/(^```json|```$)/g, '');
|
|
62
|
+
const instructionParsed = (0, coordinates_1.parseStringToObject)(cleanedText);
|
|
63
|
+
const formattedInstruction = Array.isArray(instructionParsed)
|
|
64
|
+
? instructionParsed
|
|
65
|
+
: [
|
|
66
|
+
{
|
|
67
|
+
action: instructionParsed.action,
|
|
68
|
+
value: instructionParsed.value,
|
|
69
|
+
locators: Array.isArray(instructionParsed.locators)
|
|
70
|
+
? instructionParsed.locators
|
|
71
|
+
: [{ element: instructionParsed.locators?.element || '' }],
|
|
72
|
+
},
|
|
73
|
+
];
|
|
74
|
+
if (formattedInstruction.length === 0) {
|
|
75
|
+
throw new Error(`Unable to find any actionable element for instruction: "${instruction}"`);
|
|
76
|
+
}
|
|
77
|
+
return formattedInstruction;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Supported actions list.
|
|
81
|
+
* Source: appium-stark-vision/src/services/ActionService.ts:13-36
|
|
82
|
+
*/
|
|
83
|
+
exports.SUPPORTED_ACTIONS = [
|
|
84
|
+
'back',
|
|
85
|
+
'up',
|
|
86
|
+
'down',
|
|
87
|
+
'left',
|
|
88
|
+
'right',
|
|
89
|
+
'tap',
|
|
90
|
+
'click',
|
|
91
|
+
'touch',
|
|
92
|
+
'select',
|
|
93
|
+
'long press',
|
|
94
|
+
'longpress',
|
|
95
|
+
'enter',
|
|
96
|
+
'type',
|
|
97
|
+
'send',
|
|
98
|
+
'sendkeys',
|
|
99
|
+
'set',
|
|
100
|
+
'set value',
|
|
101
|
+
'clear',
|
|
102
|
+
'delete',
|
|
103
|
+
'remove',
|
|
104
|
+
'drag',
|
|
105
|
+
'verify',
|
|
106
|
+
'validate',
|
|
107
|
+
'wait',
|
|
108
|
+
'check',
|
|
109
|
+
'home',
|
|
110
|
+
'launch',
|
|
111
|
+
'launch app',
|
|
112
|
+
'open app',
|
|
113
|
+
'stop',
|
|
114
|
+
'stop app',
|
|
115
|
+
'terminate',
|
|
116
|
+
'deeplink',
|
|
117
|
+
'open url',
|
|
118
|
+
];
|
|
119
|
+
//# sourceMappingURL=instructionParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instructionParser.js","sourceRoot":"","sources":["../../src/instructionParser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI-compatible API client for local LLM servers (LM Studio, Ollama, etc.).
|
|
3
|
+
* Uses raw fetch — no extra dependencies.
|
|
4
|
+
*/
|
|
5
|
+
interface OpenAICompatRequestParams {
|
|
6
|
+
system: string;
|
|
7
|
+
contents: Array<{
|
|
8
|
+
role: string;
|
|
9
|
+
parts: Array<any>;
|
|
10
|
+
}>;
|
|
11
|
+
temperature?: number;
|
|
12
|
+
maxTokens?: number;
|
|
13
|
+
responseMimeType?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare class OpenAICompatClient {
|
|
16
|
+
private baseUrl;
|
|
17
|
+
private model;
|
|
18
|
+
private apiKey;
|
|
19
|
+
private coordinateOrder;
|
|
20
|
+
constructor(baseUrl: string, model: string, apiKey: string, coordinateOrder?: 'yx' | 'xy');
|
|
21
|
+
/**
|
|
22
|
+
* Convert Google GenAI content format to OpenAI chat messages.
|
|
23
|
+
*/
|
|
24
|
+
private convertToMessages;
|
|
25
|
+
createMessage(params: OpenAICompatRequestParams): Promise<string>;
|
|
26
|
+
}
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=openaiCompatClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openaiCompatClient.d.ts","sourceRoot":"","sources":["../../src/openaiCompatClient.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,UAAU,yBAAyB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAA;KAAE,CAAC,CAAC;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAuBD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,eAAe,CAAc;gBAEzB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAE,IAAI,GAAG,IAAW;IAO/F;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAgCnB,aAAa,CAAC,MAAM,EAAE,yBAAyB,GAAG,OAAO,CAAC,MAAM,CAAC;CA8DxE"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OpenAI-compatible API client for local LLM servers (LM Studio, Ollama, etc.).
|
|
4
|
+
* Uses raw fetch — no extra dependencies.
|
|
5
|
+
*/
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.OpenAICompatClient = void 0;
|
|
11
|
+
const async_retry_1 = __importDefault(require("async-retry"));
|
|
12
|
+
/**
|
|
13
|
+
* Walk a parsed JSON value and swap [x, y] → [y, x] in all coordinates arrays.
|
|
14
|
+
* Used for models that return coordinates in x-first order despite the prompt.
|
|
15
|
+
*/
|
|
16
|
+
function swapCoordinates(value) {
|
|
17
|
+
if (Array.isArray(value)) {
|
|
18
|
+
if (value.length === 2 && typeof value[0] === 'number' && typeof value[1] === 'number') {
|
|
19
|
+
return [value[1], value[0]];
|
|
20
|
+
}
|
|
21
|
+
return value.map((item) => swapCoordinates(item));
|
|
22
|
+
}
|
|
23
|
+
if (value && typeof value === 'object') {
|
|
24
|
+
const out = {};
|
|
25
|
+
for (const [k, v] of Object.entries(value)) {
|
|
26
|
+
out[k] = swapCoordinates(v);
|
|
27
|
+
}
|
|
28
|
+
return out;
|
|
29
|
+
}
|
|
30
|
+
return value;
|
|
31
|
+
}
|
|
32
|
+
class OpenAICompatClient {
|
|
33
|
+
constructor(baseUrl, model, apiKey, coordinateOrder = 'yx') {
|
|
34
|
+
this.baseUrl = baseUrl.replace(/\/+$/, '');
|
|
35
|
+
this.model = model;
|
|
36
|
+
this.apiKey = apiKey;
|
|
37
|
+
this.coordinateOrder = coordinateOrder;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Convert Google GenAI content format to OpenAI chat messages.
|
|
41
|
+
*/
|
|
42
|
+
convertToMessages(system, contents) {
|
|
43
|
+
const messages = [];
|
|
44
|
+
if (system) {
|
|
45
|
+
messages.push({ role: 'system', content: system });
|
|
46
|
+
}
|
|
47
|
+
for (const entry of contents) {
|
|
48
|
+
const role = entry.role === 'model' ? 'assistant' : entry.role;
|
|
49
|
+
const parts = [];
|
|
50
|
+
for (const part of entry.parts) {
|
|
51
|
+
if (part.text) {
|
|
52
|
+
parts.push({ type: 'text', text: part.text });
|
|
53
|
+
}
|
|
54
|
+
else if (part.inlineData) {
|
|
55
|
+
const { mimeType, data } = part.inlineData;
|
|
56
|
+
parts.push({
|
|
57
|
+
type: 'image_url',
|
|
58
|
+
image_url: { url: `data:${mimeType};base64,${data}` },
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
messages.push({ role, content: parts });
|
|
63
|
+
}
|
|
64
|
+
return messages;
|
|
65
|
+
}
|
|
66
|
+
async createMessage(params) {
|
|
67
|
+
const { system, contents, temperature = 0, maxTokens = 3000 } = params;
|
|
68
|
+
const messages = this.convertToMessages(system, contents);
|
|
69
|
+
const body = {
|
|
70
|
+
model: this.model,
|
|
71
|
+
messages,
|
|
72
|
+
temperature,
|
|
73
|
+
max_tokens: maxTokens,
|
|
74
|
+
};
|
|
75
|
+
const response = await (0, async_retry_1.default)(async (bail) => {
|
|
76
|
+
const res = await fetch(`${this.baseUrl}/v1/chat/completions`, {
|
|
77
|
+
method: 'POST',
|
|
78
|
+
headers: {
|
|
79
|
+
'Content-Type': 'application/json',
|
|
80
|
+
...(this.apiKey ? { Authorization: `Bearer ${this.apiKey}` } : {}),
|
|
81
|
+
},
|
|
82
|
+
body: JSON.stringify(body),
|
|
83
|
+
});
|
|
84
|
+
if (res.status === 400 || res.status === 401) {
|
|
85
|
+
const errBody = await res.text();
|
|
86
|
+
bail(new Error(`${res.status}: ${errBody}`));
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (!res.ok) {
|
|
90
|
+
const errBody = await res.text();
|
|
91
|
+
throw new Error(`${res.status}: ${errBody}`);
|
|
92
|
+
}
|
|
93
|
+
return res.json();
|
|
94
|
+
}, {
|
|
95
|
+
retries: 3,
|
|
96
|
+
factor: 1,
|
|
97
|
+
minTimeout: 1000,
|
|
98
|
+
randomize: true,
|
|
99
|
+
});
|
|
100
|
+
let content = response?.choices?.[0]?.message?.content || '';
|
|
101
|
+
// If the model returns [x, y] instead of [y, x], swap them.
|
|
102
|
+
if (this.coordinateOrder === 'xy') {
|
|
103
|
+
try {
|
|
104
|
+
const cleaned = content
|
|
105
|
+
.trim()
|
|
106
|
+
.replace(/(^```json\s*|```\s*$)/g, '')
|
|
107
|
+
.trim();
|
|
108
|
+
const parsed = JSON.parse(cleaned);
|
|
109
|
+
content = JSON.stringify(swapCoordinates(parsed));
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// Not JSON or not a coordinate response — leave as-is
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return content;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
exports.OpenAICompatClient = OpenAICompatClient;
|
|
119
|
+
//# sourceMappingURL=openaiCompatClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openaiCompatClient.js","sourceRoot":"","sources":["../../src/openaiCompatClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promptCodec.d.ts","sourceRoot":"","sources":["../../src/promptCodec.ts"],"names":[],"mappings":"AAOA,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEtD"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.decodeVisionPrompt = decodeVisionPrompt;
|
|
4
|
+
/**
|
|
5
|
+
* Decode build-time prompt payloads. The published npm bundle avoids shipping
|
|
6
|
+
* plain-text prompts: they are gzip-compressed then Base64-encoded at build time
|
|
7
|
+
* (see scripts/generate-prompt-b64.cjs) and inflated here at runtime.
|
|
8
|
+
*/
|
|
9
|
+
const node_zlib_1 = require("node:zlib");
|
|
10
|
+
function decodeVisionPrompt(b64) {
|
|
11
|
+
return (0, node_zlib_1.gunzipSync)(Buffer.from(b64, 'base64')).toString('utf8');
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=promptCodec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promptCodec.js","sourceRoot":"","sources":["../../src/promptCodec.ts"],"names":[],"mappings":";;AAOA,gDAEC;AATD;;;;GAIG;AACH,yCAAuC;AAEvC,SAAgB,kBAAkB,CAAC,GAAW;IAC5C,OAAO,IAAA,sBAAU,EAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public prompt exports for stark-vision / df-vision.
|
|
3
|
+
* Human-readable source: `prompts.raw.ts` (not compiled). Published npm bundle uses Base64 payloads
|
|
4
|
+
* in `generated/promptB64.ts` (regenerate: `npm run gen:prompts`).
|
|
5
|
+
*/
|
|
6
|
+
export { combinedInstructionPrompt, elementVisibilityPrompt, elementVisibilityWithExplanationPrompt, bboxPrompt, backNavigationPrompt, getInformationWithExplanationPrompt, getInformationPrompt, createWDIOTestPrompt, createAppiumJavaTestPrompt, } from './generated/promptB64';
|
|
7
|
+
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/prompts.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,sCAAsC,EACtC,UAAU,EACV,oBAAoB,EACpB,mCAAmC,EACnC,oBAAoB,EACpB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Public prompt exports for stark-vision / df-vision.
|
|
4
|
+
* Human-readable source: `prompts.raw.ts` (not compiled). Published npm bundle uses Base64 payloads
|
|
5
|
+
* in `generated/promptB64.ts` (regenerate: `npm run gen:prompts`).
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.createAppiumJavaTestPrompt = exports.createWDIOTestPrompt = exports.getInformationPrompt = exports.getInformationWithExplanationPrompt = exports.backNavigationPrompt = exports.bboxPrompt = exports.elementVisibilityWithExplanationPrompt = exports.elementVisibilityPrompt = exports.combinedInstructionPrompt = void 0;
|
|
9
|
+
var promptB64_1 = require("./generated/promptB64");
|
|
10
|
+
Object.defineProperty(exports, "combinedInstructionPrompt", { enumerable: true, get: function () { return promptB64_1.combinedInstructionPrompt; } });
|
|
11
|
+
Object.defineProperty(exports, "elementVisibilityPrompt", { enumerable: true, get: function () { return promptB64_1.elementVisibilityPrompt; } });
|
|
12
|
+
Object.defineProperty(exports, "elementVisibilityWithExplanationPrompt", { enumerable: true, get: function () { return promptB64_1.elementVisibilityWithExplanationPrompt; } });
|
|
13
|
+
Object.defineProperty(exports, "bboxPrompt", { enumerable: true, get: function () { return promptB64_1.bboxPrompt; } });
|
|
14
|
+
Object.defineProperty(exports, "backNavigationPrompt", { enumerable: true, get: function () { return promptB64_1.backNavigationPrompt; } });
|
|
15
|
+
Object.defineProperty(exports, "getInformationWithExplanationPrompt", { enumerable: true, get: function () { return promptB64_1.getInformationWithExplanationPrompt; } });
|
|
16
|
+
Object.defineProperty(exports, "getInformationPrompt", { enumerable: true, get: function () { return promptB64_1.getInformationPrompt; } });
|
|
17
|
+
Object.defineProperty(exports, "createWDIOTestPrompt", { enumerable: true, get: function () { return promptB64_1.createWDIOTestPrompt; } });
|
|
18
|
+
Object.defineProperty(exports, "createAppiumJavaTestPrompt", { enumerable: true, get: function () { return promptB64_1.createAppiumJavaTestPrompt; } });
|
|
19
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/prompts.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH,mDAU+B;AAT7B,sHAAA,yBAAyB,OAAA;AACzB,oHAAA,uBAAuB,OAAA;AACvB,mIAAA,sCAAsC,OAAA;AACtC,uGAAA,UAAU,OAAA;AACV,iHAAA,oBAAoB,OAAA;AACpB,gIAAA,mCAAmC,OAAA;AACnC,iHAAA,oBAAoB,OAAA;AACpB,iHAAA,oBAAoB,OAAA;AACpB,uHAAA,0BAA0B,OAAA"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
export type ScrollSize = 'SMALL' | 'MEDIUM' | 'LARGE';
|
|
2
|
+
/** Token usage reported by a single Gemini API call inside StarkVisionClient. */
|
|
3
|
+
export interface VisionTokenUsage {
|
|
4
|
+
inputTokens: number;
|
|
5
|
+
outputTokens: number;
|
|
6
|
+
totalTokens: number;
|
|
7
|
+
/** Tokens served from Gemini implicit cache (~75% cost reduction). */
|
|
8
|
+
cachedTokens?: number;
|
|
9
|
+
/** Tokens consumed by extended thinking (Gemini 2.5+ with MINIMAL/AUTO thinking). */
|
|
10
|
+
thoughtsTokens?: number;
|
|
11
|
+
}
|
|
12
|
+
export type CommandType = 'find' | 'getInfo';
|
|
13
|
+
export interface StarkVisionConfig {
|
|
14
|
+
apiKey: string;
|
|
15
|
+
model: string;
|
|
16
|
+
/** Disable thinking (ThinkingLevel.NONE) for faster responses. Default: false (MINIMAL). */
|
|
17
|
+
disableThinking?: boolean;
|
|
18
|
+
/** Base URL for OpenAI-compatible local servers (e.g. LM Studio: http://127.0.0.1:1234). */
|
|
19
|
+
baseUrl?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Coordinate order returned by the local model in the coordinates array.
|
|
22
|
+
* 'yx' (default): model returns [y, x] as the prompt instructs.
|
|
23
|
+
* 'xy': model returns [x, y] despite the prompt (e.g. some Qwen variants).
|
|
24
|
+
* When 'xy', coordinates are swapped before scaling.
|
|
25
|
+
*/
|
|
26
|
+
coordinateOrder?: 'yx' | 'xy';
|
|
27
|
+
/**
|
|
28
|
+
* Optional callback invoked after every Gemini API call with token usage.
|
|
29
|
+
* Use this to accumulate and display token costs for vision operations.
|
|
30
|
+
*/
|
|
31
|
+
onTokenUsage?: (usage: VisionTokenUsage) => void;
|
|
32
|
+
}
|
|
33
|
+
export interface ExecutionConfig {
|
|
34
|
+
scrollSize: ScrollSize;
|
|
35
|
+
elementVisibleCheck: boolean;
|
|
36
|
+
maxScrolls: number;
|
|
37
|
+
saveToCache: boolean;
|
|
38
|
+
visibleExplanation: boolean;
|
|
39
|
+
}
|
|
40
|
+
export declare const DefaultExecutionConfig: ExecutionConfig;
|
|
41
|
+
export interface StarkVisionAction {
|
|
42
|
+
action: string;
|
|
43
|
+
value: string | null;
|
|
44
|
+
locators: {
|
|
45
|
+
element: string;
|
|
46
|
+
coordinates?: [number, number];
|
|
47
|
+
/**
|
|
48
|
+
* How directly the original instruction described this element (1–10).
|
|
49
|
+
* 1 = vague/unrelated (model had to interpret heavily),
|
|
50
|
+
* 10 = exact/direct description.
|
|
51
|
+
* Only present when the combinedInstructionPrompt includes matchScore support.
|
|
52
|
+
*/
|
|
53
|
+
matchScore?: number;
|
|
54
|
+
}[];
|
|
55
|
+
}
|
|
56
|
+
export interface BoundingBox {
|
|
57
|
+
corners: {
|
|
58
|
+
min: {
|
|
59
|
+
x: number;
|
|
60
|
+
y: number;
|
|
61
|
+
};
|
|
62
|
+
max: {
|
|
63
|
+
x: number;
|
|
64
|
+
y: number;
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
center: {
|
|
68
|
+
x: number;
|
|
69
|
+
y: number;
|
|
70
|
+
};
|
|
71
|
+
container: {
|
|
72
|
+
width: number;
|
|
73
|
+
height: number;
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
export interface ScreenSize {
|
|
77
|
+
width: number;
|
|
78
|
+
height: number;
|
|
79
|
+
}
|
|
80
|
+
export interface VisibilityResult {
|
|
81
|
+
elementState: boolean | string;
|
|
82
|
+
systemPopUp: boolean;
|
|
83
|
+
popUpActionButtons: string;
|
|
84
|
+
typeOfPopUp: string;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEtD,iFAAiF;AACjF,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qFAAqF;IACrF,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,SAAS,CAAC;AAE7C,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,4FAA4F;IAC5F,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,4FAA4F;IAC5F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAC9B;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;CAClD;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,UAAU,CAAC;IACvB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAED,eAAO,MAAM,sBAAsB,EAAE,eAMpC,CAAC;AAEF,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/B;;;;;WAKG;QACH,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,EAAE,CAAC;CACL;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE;QAAE,GAAG,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,GAAG,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IAC1E,MAAM,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjC,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9C;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,OAAO,GAAG,MAAM,CAAC;IAC/B,WAAW,EAAE,OAAO,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;CACrB"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DefaultExecutionConfig = void 0;
|
|
4
|
+
exports.DefaultExecutionConfig = {
|
|
5
|
+
scrollSize: 'MEDIUM',
|
|
6
|
+
elementVisibleCheck: true,
|
|
7
|
+
maxScrolls: 0,
|
|
8
|
+
saveToCache: true,
|
|
9
|
+
visibleExplanation: false,
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":";;;AA4Ca,QAAA,sBAAsB,GAAoB;IACrD,UAAU,EAAE,QAAQ;IACpB,mBAAmB,EAAE,IAAI;IACzB,UAAU,EAAE,CAAC;IACb,WAAW,EAAE,IAAI;IACjB,kBAAkB,EAAE,KAAK;CAC1B,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@appclaw/vision",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "AI-powered vision element detection for AppClaw",
|
|
5
|
+
"main": "dist/src/index.js",
|
|
6
|
+
"types": "dist/src/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/src/index.d.ts",
|
|
10
|
+
"import": "./dist/src/index.js",
|
|
11
|
+
"require": "./dist/src/index.js",
|
|
12
|
+
"default": "./dist/src/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"gen:prompts": "node scripts/generate-prompt-b64.cjs",
|
|
17
|
+
"clean": "rm -rf dist",
|
|
18
|
+
"build": "npm run clean && npm run gen:prompts && tsc",
|
|
19
|
+
"build:tsc": "tsc",
|
|
20
|
+
"build:watch": "tsc --watch",
|
|
21
|
+
"typecheck": "npm run gen:prompts && tsc --noEmit",
|
|
22
|
+
"prepublishOnly": "npm run build"
|
|
23
|
+
},
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@google/genai": "^1.44.0",
|
|
27
|
+
"async-retry": "^1.3.3"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
31
|
+
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
32
|
+
"@semantic-release/git": "^10.0.1",
|
|
33
|
+
"@semantic-release/github": "^11.0.6",
|
|
34
|
+
"@semantic-release/npm": "^12.0.2",
|
|
35
|
+
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
36
|
+
"@types/async-retry": "^1.4.9",
|
|
37
|
+
"@types/node": "^20.11.0",
|
|
38
|
+
"conventional-changelog-conventionalcommits": "^9.3.1",
|
|
39
|
+
"semantic-release": "^24.2.9",
|
|
40
|
+
"typescript": "5.6.2"
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"dist"
|
|
44
|
+
],
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"access": "public"
|
|
47
|
+
}
|
|
48
|
+
}
|