alumnium 0.14.0 → 0.16.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 +0 -8
- package/dist/Alumni.d.ts +7 -4
- package/dist/Alumni.js +12 -9
- package/dist/Area.d.ts +5 -4
- package/dist/Area.js +12 -11
- package/dist/Model.d.ts +3 -1
- package/dist/Model.js +12 -5
- package/dist/accessibility/ChromiumAccessibilityTree.d.ts +1 -5
- package/dist/clients/ApiModels.d.ts +73 -0
- package/dist/clients/ApiModels.js +7 -0
- package/dist/clients/HttpClient.d.ts +8 -5
- package/dist/clients/HttpClient.js +59 -80
- package/dist/drivers/AppiumDriver.d.ts +2 -1
- package/dist/drivers/AppiumDriver.js +68 -40
- package/dist/drivers/PlaywrightDriver.js +59 -23
- package/dist/drivers/SeleniumDriver.js +15 -6
- package/dist/errors/AssertionError.d.ts +7 -0
- package/dist/errors/AssertionError.js +14 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/tools/BaseTool.d.ts +3 -3
- package/dist/tools/BaseTool.js +1 -5
- package/dist/tools/ClickTool.d.ts +2 -0
- package/dist/tools/ClickTool.js +8 -0
- package/dist/tools/DragAndDropTool.d.ts +2 -0
- package/dist/tools/DragAndDropTool.js +15 -0
- package/dist/tools/Field.d.ts +25 -0
- package/dist/tools/Field.js +13 -0
- package/dist/tools/HoverTool.d.ts +2 -0
- package/dist/tools/HoverTool.js +8 -0
- package/dist/tools/PressKeyTool.d.ts +2 -0
- package/dist/tools/PressKeyTool.js +10 -0
- package/dist/tools/SelectTool.d.ts +2 -0
- package/dist/tools/SelectTool.js +9 -0
- package/dist/tools/TypeTool.d.ts +2 -0
- package/dist/tools/TypeTool.js +13 -0
- package/dist/tools/toolToSchemaConverter.d.ts +3 -2
- package/dist/tools/toolToSchemaConverter.js +22 -48
- package/dist/utils/logger.js +13 -4
- package/dist/utils/retry.d.ts +7 -0
- package/dist/utils/retry.js +56 -0
- package/package.json +20 -9
- package/.mocharc.json +0 -10
- package/.vscode/extensions.json +0 -6
- package/.vscode/settings.json +0 -16
- package/log/alumnium.log +0 -731
- package/playwright-report/data/9bb9e740488ba36abef0f2c1176f965fea9c0318.zip +0 -0
- package/playwright-report/index.html +0 -85
- package/playwright-report/trace/assets/codeMirrorModule-eyVcHN77.js +0 -24
- package/playwright-report/trace/assets/defaultSettingsView-w0zYjHsW.js +0 -265
- package/playwright-report/trace/codeMirrorModule.C3UTv-Ge.css +0 -1
- package/playwright-report/trace/codicon.DCmgc-ay.ttf +0 -0
- package/playwright-report/trace/defaultSettingsView.TQ8_7ybu.css +0 -1
- package/playwright-report/trace/index.Bx16ehp1.js +0 -2
- package/playwright-report/trace/index.I8N9v4jT.css +0 -1
- package/playwright-report/trace/index.html +0 -43
- package/playwright-report/trace/playwright-logo.svg +0 -9
- package/playwright-report/trace/snapshot.html +0 -21
- package/playwright-report/trace/sw.bundle.js +0 -3
- package/playwright-report/trace/uiMode.Btcz36p_.css +0 -1
- package/playwright-report/trace/uiMode.DRQ310U5.js +0 -5
- package/playwright-report/trace/uiMode.html +0 -17
- package/playwright-report/trace/xtermModule.DYP7pi_n.css +0 -32
- package/reports/test-report.html +0 -1408
- package/src/Alumni.ts +0 -195
- package/src/Area.ts +0 -99
- package/src/Cache.ts +0 -17
- package/src/Model.ts +0 -56
- package/src/accessibility/AccessibilityElement.ts +0 -39
- package/src/accessibility/BaseAccessibilityTree.ts +0 -7
- package/src/accessibility/ChromiumAccessibilityTree.ts +0 -290
- package/src/accessibility/UIAutomator2AccessibilityTree.ts +0 -199
- package/src/accessibility/XCUITestAccessibilityTree.ts +0 -186
- package/src/accessibility/index.ts +0 -5
- package/src/clients/HttpClient.ts +0 -288
- package/src/clients/typecasting.ts +0 -34
- package/src/drivers/AppiumDriver.ts +0 -208
- package/src/drivers/BaseDriver.ts +0 -20
- package/src/drivers/PlaywrightDriver.ts +0 -186
- package/src/drivers/SeleniumDriver.ts +0 -208
- package/src/drivers/index.ts +0 -5
- package/src/drivers/keys.ts +0 -6
- package/src/index.ts +0 -11
- package/src/tools/BaseTool.ts +0 -29
- package/src/tools/ClickTool.ts +0 -17
- package/src/tools/DragAndDropTool.ts +0 -20
- package/src/tools/HoverTool.ts +0 -17
- package/src/tools/NavigateBackTool.ts +0 -19
- package/src/tools/PressKeyTool.ts +0 -18
- package/src/tools/SelectTool.ts +0 -20
- package/src/tools/TypeTool.ts +0 -19
- package/src/tools/toolToSchemaConverter.ts +0 -83
- package/src/utils/logger.ts +0 -46
- package/test-results/.last-run.json +0 -6
- package/test-results/calculator-Calculator-Tests-addition-default/trace.zip +0 -0
- package/tsconfig.json +0 -27
- package/wdio.conf.ts +0 -45
- /package/{src → dist}/drivers/scripts/waitFor.js +0 -0
- /package/{src → dist}/drivers/scripts/waiter.js +0 -0
package/README.md
CHANGED
|
@@ -59,14 +59,6 @@ Check out [documentation][1] and more [examples][2]!
|
|
|
59
59
|
|
|
60
60
|
See the [contributing guidelines][4] for information on how to get involved in the project and develop locally.
|
|
61
61
|
|
|
62
|
-
## Acknowledgments
|
|
63
|
-
|
|
64
|
-
[][5]
|
|
65
|
-
|
|
66
|
-
Alumnium is a member of [LambdaTest][5] Open Source Program, which supports the project community and development with
|
|
67
|
-
the necessary tools. Thank you! 💚
|
|
68
|
-
|
|
69
|
-
|
|
70
62
|
|
|
71
63
|
[1]: https://alumnium.ai/docs/
|
|
72
64
|
[2]: https://github.com/alumnium-hq/alumnium/tree/main/packages/typescript/examples/
|
package/dist/Alumni.d.ts
CHANGED
|
@@ -7,11 +7,14 @@ import { Data } from "./clients/typecasting.js";
|
|
|
7
7
|
import { BaseDriver } from "./drivers/BaseDriver.js";
|
|
8
8
|
import { Element } from "./drivers/index.js";
|
|
9
9
|
import { Model } from "./Model.js";
|
|
10
|
-
import {
|
|
10
|
+
import { ToolClass } from "./tools/BaseTool.js";
|
|
11
11
|
export interface AlumniOptions {
|
|
12
12
|
url?: string;
|
|
13
13
|
model?: Model;
|
|
14
|
-
extraTools?:
|
|
14
|
+
extraTools?: ToolClass[];
|
|
15
|
+
}
|
|
16
|
+
export interface VisionOptions {
|
|
17
|
+
vision?: boolean;
|
|
15
18
|
}
|
|
16
19
|
export declare class Alumni {
|
|
17
20
|
driver: BaseDriver;
|
|
@@ -23,8 +26,8 @@ export declare class Alumni {
|
|
|
23
26
|
constructor(driver: WebDriver | Page | Browser, options?: AlumniOptions);
|
|
24
27
|
quit(): Promise<void>;
|
|
25
28
|
do(goal: string): Promise<void>;
|
|
26
|
-
check(statement: string,
|
|
27
|
-
get(data: string,
|
|
29
|
+
check(statement: string, options?: VisionOptions): Promise<string>;
|
|
30
|
+
get(data: string, options?: VisionOptions): Promise<Data>;
|
|
28
31
|
find(description: string): Promise<Element>;
|
|
29
32
|
area(description: string): Promise<Area>;
|
|
30
33
|
learn(goal: string, actions: string[]): Promise<void>;
|
package/dist/Alumni.js
CHANGED
|
@@ -5,6 +5,7 @@ import { HttpClient } from "./clients/HttpClient.js";
|
|
|
5
5
|
import { AppiumDriver } from "./drivers/AppiumDriver.js";
|
|
6
6
|
import { PlaywrightDriver } from "./drivers/PlaywrightDriver.js";
|
|
7
7
|
import { SeleniumDriver } from "./drivers/SeleniumDriver.js";
|
|
8
|
+
import { AssertionError } from "./errors/AssertionError.js";
|
|
8
9
|
import { Model } from "./Model.js";
|
|
9
10
|
import { BaseTool } from "./tools/BaseTool.js";
|
|
10
11
|
import { ClickTool } from "./tools/ClickTool.js";
|
|
@@ -50,7 +51,7 @@ export class Alumni {
|
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
53
|
// Initialize HTTP client
|
|
53
|
-
this.client = new HttpClient(this.url, this.driver.platform, this.tools);
|
|
54
|
+
this.client = new HttpClient(this.url, this.model, this.driver.platform, this.tools);
|
|
54
55
|
this.cache = new Cache(this.client);
|
|
55
56
|
logger.info(`Using model: ${this.model.provider}/${this.model.name}`);
|
|
56
57
|
logger.info(`Using HTTP client with server: ${this.url}`);
|
|
@@ -71,21 +72,25 @@ export class Alumni {
|
|
|
71
72
|
const actorResponse = await this.client.executeAction(goal, step, accessibilityTree.toStr());
|
|
72
73
|
// Execute tool calls
|
|
73
74
|
for (const toolCall of actorResponse) {
|
|
74
|
-
await BaseTool.executeToolCall(toolCall, this.tools, this.
|
|
75
|
+
await BaseTool.executeToolCall(toolCall, this.tools, this.driver);
|
|
75
76
|
}
|
|
76
77
|
}
|
|
77
78
|
}
|
|
78
|
-
async check(statement,
|
|
79
|
-
const screenshot = vision
|
|
79
|
+
async check(statement, options = {}) {
|
|
80
|
+
const screenshot = options.vision
|
|
81
|
+
? await this.driver.screenshot()
|
|
82
|
+
: undefined;
|
|
80
83
|
const accessibilityTree = await this.driver.getAccessibilityTree();
|
|
81
84
|
const [explanation, value] = await this.client.retrieve(`Is the following true or false - ${statement}`, accessibilityTree.toStr(), await this.driver.title(), await this.driver.url(), screenshot);
|
|
82
85
|
if (!value) {
|
|
83
|
-
throw new
|
|
86
|
+
throw new AssertionError(explanation);
|
|
84
87
|
}
|
|
85
88
|
return explanation;
|
|
86
89
|
}
|
|
87
|
-
async get(data,
|
|
88
|
-
const screenshot = vision
|
|
90
|
+
async get(data, options = {}) {
|
|
91
|
+
const screenshot = options.vision
|
|
92
|
+
? await this.driver.screenshot()
|
|
93
|
+
: undefined;
|
|
89
94
|
const accessibilityTree = await this.driver.getAccessibilityTree();
|
|
90
95
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
91
96
|
const [_explanation, value] = await this.client.retrieve(data, accessibilityTree.toStr(), await this.driver.title(), await this.driver.url(), screenshot);
|
|
@@ -93,9 +98,7 @@ export class Alumni {
|
|
|
93
98
|
}
|
|
94
99
|
async find(description) {
|
|
95
100
|
const accessibilityTree = await this.driver.getAccessibilityTree();
|
|
96
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
97
101
|
const response = await this.client.findElement(description, accessibilityTree.toStr());
|
|
98
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
99
102
|
return this.driver.findElement(response.id);
|
|
100
103
|
}
|
|
101
104
|
async area(description) {
|
package/dist/Area.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { BaseAccessibilityTree } from "./accessibility/BaseAccessibilityTree.js";
|
|
2
|
+
import { VisionOptions } from "./Alumni.js";
|
|
2
3
|
import { HttpClient } from "./clients/HttpClient.js";
|
|
3
4
|
import { Data } from "./clients/typecasting.js";
|
|
4
5
|
import { BaseDriver } from "./drivers/BaseDriver.js";
|
|
5
6
|
import { Element } from "./drivers/index.js";
|
|
6
|
-
import {
|
|
7
|
+
import { ToolClass } from "./tools/BaseTool.js";
|
|
7
8
|
export declare class Area {
|
|
8
9
|
id: number;
|
|
9
10
|
description: string;
|
|
@@ -11,9 +12,9 @@ export declare class Area {
|
|
|
11
12
|
private driver;
|
|
12
13
|
private tools;
|
|
13
14
|
private client;
|
|
14
|
-
constructor(id: number, description: string, accessibilityTree: BaseAccessibilityTree, driver: BaseDriver, tools: Record<string,
|
|
15
|
+
constructor(id: number, description: string, accessibilityTree: BaseAccessibilityTree, driver: BaseDriver, tools: Record<string, ToolClass>, client: HttpClient);
|
|
15
16
|
do(goal: string): Promise<void>;
|
|
16
|
-
check(statement: string,
|
|
17
|
-
get(data: string,
|
|
17
|
+
check(statement: string, options?: VisionOptions): Promise<string>;
|
|
18
|
+
get(data: string, options?: VisionOptions): Promise<Data>;
|
|
18
19
|
find(description: string): Promise<Element>;
|
|
19
20
|
}
|
package/dist/Area.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
+
import { AssertionError } from "./errors/AssertionError.js";
|
|
1
2
|
import { BaseTool } from "./tools/BaseTool.js";
|
|
2
3
|
export class Area {
|
|
3
|
-
constructor(id, description, accessibilityTree, driver,
|
|
4
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5
|
-
tools, client) {
|
|
4
|
+
constructor(id, description, accessibilityTree, driver, tools, client) {
|
|
6
5
|
this.id = id;
|
|
7
6
|
this.description = description;
|
|
8
7
|
this.accessibilityTree = accessibilityTree;
|
|
@@ -16,28 +15,30 @@ export class Area {
|
|
|
16
15
|
const actorResponse = await this.client.executeAction(goal, step, this.accessibilityTree.toStr());
|
|
17
16
|
// Execute tool calls
|
|
18
17
|
for (const toolCall of actorResponse) {
|
|
19
|
-
await BaseTool.executeToolCall(toolCall, this.tools, this.
|
|
18
|
+
await BaseTool.executeToolCall(toolCall, this.tools, this.driver);
|
|
20
19
|
}
|
|
21
20
|
}
|
|
22
21
|
}
|
|
23
|
-
async check(statement,
|
|
24
|
-
const screenshot = vision
|
|
22
|
+
async check(statement, options = {}) {
|
|
23
|
+
const screenshot = options.vision
|
|
24
|
+
? await this.driver.screenshot()
|
|
25
|
+
: undefined;
|
|
25
26
|
const [explanation, value] = await this.client.retrieve(`Is the following true or false - ${statement}`, this.accessibilityTree.toStr(), await this.driver.title(), await this.driver.url(), screenshot);
|
|
26
27
|
if (!value) {
|
|
27
|
-
throw new
|
|
28
|
+
throw new AssertionError(explanation);
|
|
28
29
|
}
|
|
29
30
|
return explanation;
|
|
30
31
|
}
|
|
31
|
-
async get(data,
|
|
32
|
-
const screenshot = vision
|
|
32
|
+
async get(data, options = {}) {
|
|
33
|
+
const screenshot = options.vision
|
|
34
|
+
? await this.driver.screenshot()
|
|
35
|
+
: undefined;
|
|
33
36
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
34
37
|
const [_explanation, value] = await this.client.retrieve(data, this.accessibilityTree.toStr(), await this.driver.title(), await this.driver.url(), screenshot);
|
|
35
38
|
return value;
|
|
36
39
|
}
|
|
37
40
|
async find(description) {
|
|
38
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
39
41
|
const response = await this.client.findElement(description, this.accessibilityTree.toStr());
|
|
40
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
41
42
|
return this.driver.findElement(response.id);
|
|
42
43
|
}
|
|
43
44
|
}
|
package/dist/Model.d.ts
CHANGED
|
@@ -4,10 +4,12 @@ export declare enum Provider {
|
|
|
4
4
|
AWS_ANTHROPIC = "aws_anthropic",
|
|
5
5
|
AWS_META = "aws_meta",
|
|
6
6
|
DEEPSEEK = "deepseek",
|
|
7
|
+
GITHUB = "github",
|
|
7
8
|
GOOGLE = "google",
|
|
8
9
|
MISTRALAI = "mistralai",
|
|
9
10
|
OLLAMA = "ollama",
|
|
10
|
-
OPENAI = "openai"
|
|
11
|
+
OPENAI = "openai",
|
|
12
|
+
XAI = "xai"
|
|
11
13
|
}
|
|
12
14
|
export declare class ModelName {
|
|
13
15
|
static readonly DEFAULT: Record<Provider, string>;
|
package/dist/Model.js
CHANGED
|
@@ -5,23 +5,27 @@ export var Provider;
|
|
|
5
5
|
Provider["AWS_ANTHROPIC"] = "aws_anthropic";
|
|
6
6
|
Provider["AWS_META"] = "aws_meta";
|
|
7
7
|
Provider["DEEPSEEK"] = "deepseek";
|
|
8
|
+
Provider["GITHUB"] = "github";
|
|
8
9
|
Provider["GOOGLE"] = "google";
|
|
9
10
|
Provider["MISTRALAI"] = "mistralai";
|
|
10
11
|
Provider["OLLAMA"] = "ollama";
|
|
11
12
|
Provider["OPENAI"] = "openai";
|
|
13
|
+
Provider["XAI"] = "xai";
|
|
12
14
|
})(Provider || (Provider = {}));
|
|
13
15
|
export class ModelName {
|
|
14
16
|
}
|
|
15
17
|
ModelName.DEFAULT = {
|
|
16
18
|
[Provider.AZURE_OPENAI]: "gpt-4o-mini",
|
|
17
|
-
[Provider.ANTHROPIC]: "claude-
|
|
18
|
-
[Provider.AWS_ANTHROPIC]: "anthropic.claude-
|
|
19
|
+
[Provider.ANTHROPIC]: "claude-haiku-4-5-20251001",
|
|
20
|
+
[Provider.AWS_ANTHROPIC]: "us.anthropic.claude-haiku-4-5-20251001-v1:0",
|
|
19
21
|
[Provider.AWS_META]: "us.meta.llama4-maverick-17b-instruct-v1:0",
|
|
20
22
|
[Provider.DEEPSEEK]: "deepseek-chat",
|
|
23
|
+
[Provider.GITHUB]: "gpt-4o-mini",
|
|
21
24
|
[Provider.GOOGLE]: "gemini-2.0-flash-001",
|
|
22
25
|
[Provider.MISTRALAI]: "mistral-medium-2505",
|
|
23
26
|
[Provider.OLLAMA]: "mistral-small3.1",
|
|
24
27
|
[Provider.OPENAI]: "gpt-4o-mini-2024-07-18",
|
|
28
|
+
[Provider.XAI]: "grok-4-fast-non-reasoning",
|
|
25
29
|
};
|
|
26
30
|
export class Model {
|
|
27
31
|
constructor(provider, name) {
|
|
@@ -37,9 +41,12 @@ export class Model {
|
|
|
37
41
|
this.name = name || ModelName.DEFAULT[this.provider];
|
|
38
42
|
}
|
|
39
43
|
static initialize() {
|
|
40
|
-
const alumniumModel = process.env.ALUMNIUM_MODEL || "
|
|
41
|
-
|
|
42
|
-
|
|
44
|
+
const alumniumModel = process.env.ALUMNIUM_MODEL || "";
|
|
45
|
+
let [provider, name] = alumniumModel.toLowerCase().split("/");
|
|
46
|
+
if (!provider && process.env.GITHUB_ACTIONS) {
|
|
47
|
+
provider = "github";
|
|
48
|
+
name = ModelName.DEFAULT[Provider.GITHUB];
|
|
49
|
+
}
|
|
43
50
|
Model.current = new Model(provider, name);
|
|
44
51
|
}
|
|
45
52
|
}
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import { AccessibilityElement } from "./AccessibilityElement.js";
|
|
2
2
|
import { BaseAccessibilityTree } from "./BaseAccessibilityTree.js";
|
|
3
|
-
interface CDPResponse {
|
|
4
|
-
nodes: any[];
|
|
5
|
-
}
|
|
6
3
|
export declare class ChromiumAccessibilityTree extends BaseAccessibilityTree {
|
|
7
4
|
private cdpResponse;
|
|
8
5
|
private nextRawId;
|
|
9
6
|
private raw;
|
|
10
|
-
constructor(cdpResponse:
|
|
7
|
+
constructor(cdpResponse: unknown);
|
|
11
8
|
private static fromXml;
|
|
12
9
|
toStr(): string;
|
|
13
10
|
private nodeToXml;
|
|
@@ -17,4 +14,3 @@ export declare class ChromiumAccessibilityTree extends BaseAccessibilityTree {
|
|
|
17
14
|
private findElementByRawId;
|
|
18
15
|
private parseSimpleXml;
|
|
19
16
|
}
|
|
20
|
-
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript interfaces for API request and response models.
|
|
3
|
+
*
|
|
4
|
+
* IMPORTANT: These interfaces must be kept in sync with the Python API models
|
|
5
|
+
* defined in packages/python/src/alumnium/server/api_models.py
|
|
6
|
+
*/
|
|
7
|
+
export interface SessionRequest {
|
|
8
|
+
platform: "chromium" | "uiautomator2" | "xcuitest";
|
|
9
|
+
provider: string;
|
|
10
|
+
name?: string;
|
|
11
|
+
tools: {
|
|
12
|
+
[key: string]: any;
|
|
13
|
+
}[];
|
|
14
|
+
}
|
|
15
|
+
export interface SessionResponse {
|
|
16
|
+
session_id: string;
|
|
17
|
+
}
|
|
18
|
+
export interface PlanRequest {
|
|
19
|
+
goal: string;
|
|
20
|
+
accessibility_tree: string;
|
|
21
|
+
url?: string;
|
|
22
|
+
title?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface PlanResponse {
|
|
25
|
+
steps: string[];
|
|
26
|
+
}
|
|
27
|
+
export interface StepRequest {
|
|
28
|
+
goal: string;
|
|
29
|
+
step: string;
|
|
30
|
+
accessibility_tree: string;
|
|
31
|
+
}
|
|
32
|
+
export interface StepResponse {
|
|
33
|
+
actions: {
|
|
34
|
+
[key: string]: any;
|
|
35
|
+
}[];
|
|
36
|
+
}
|
|
37
|
+
export interface StatementRequest {
|
|
38
|
+
statement: string;
|
|
39
|
+
accessibility_tree: string;
|
|
40
|
+
url?: string;
|
|
41
|
+
title?: string;
|
|
42
|
+
screenshot?: string | null;
|
|
43
|
+
}
|
|
44
|
+
export interface StatementResponse {
|
|
45
|
+
result: string | string[];
|
|
46
|
+
explanation: string;
|
|
47
|
+
}
|
|
48
|
+
export interface AreaRequest {
|
|
49
|
+
description: string;
|
|
50
|
+
accessibility_tree: string;
|
|
51
|
+
}
|
|
52
|
+
export interface AreaResponse {
|
|
53
|
+
id: number;
|
|
54
|
+
explanation: string;
|
|
55
|
+
}
|
|
56
|
+
export interface FindRequest {
|
|
57
|
+
description: string;
|
|
58
|
+
accessibility_tree: string;
|
|
59
|
+
}
|
|
60
|
+
export interface FindResponse {
|
|
61
|
+
elements: {
|
|
62
|
+
[key: string]: number | string;
|
|
63
|
+
}[];
|
|
64
|
+
}
|
|
65
|
+
export interface AddExampleRequest {
|
|
66
|
+
goal: string;
|
|
67
|
+
actions: string[];
|
|
68
|
+
}
|
|
69
|
+
export interface StatsResponse {
|
|
70
|
+
[key: string]: {
|
|
71
|
+
[key: string]: number;
|
|
72
|
+
};
|
|
73
|
+
}
|
|
@@ -1,27 +1,30 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Model } from "../Model.js";
|
|
2
|
+
import { ToolClass } from "../tools/BaseTool.js";
|
|
3
|
+
import { FindResponse, StatsResponse, StepResponse } from "./ApiModels.js";
|
|
2
4
|
import { Data } from "./typecasting.js";
|
|
3
5
|
export declare class HttpClient {
|
|
6
|
+
private model;
|
|
4
7
|
private platform;
|
|
5
8
|
private tools;
|
|
6
9
|
private baseUrl;
|
|
7
10
|
private sessionId;
|
|
8
11
|
private sessionPromise;
|
|
9
12
|
private timeout;
|
|
10
|
-
constructor(baseUrl: string, platform: string, tools: Record<string,
|
|
13
|
+
constructor(baseUrl: string, model: Model, platform: string, tools: Record<string, ToolClass>);
|
|
11
14
|
private fetchWithTimeout;
|
|
12
15
|
private ensureSession;
|
|
13
16
|
quit(): Promise<void>;
|
|
14
17
|
planActions(goal: string, accessibilityTree: string): Promise<string[]>;
|
|
15
18
|
addExample(goal: string, actions: string[]): Promise<void>;
|
|
16
19
|
clearExamples(): Promise<void>;
|
|
17
|
-
executeAction(goal: string, step: string, accessibilityTree: string): Promise<
|
|
20
|
+
executeAction(goal: string, step: string, accessibilityTree: string): Promise<StepResponse["actions"]>;
|
|
18
21
|
retrieve(statement: string, accessibilityTree: string, title: string, url: string, screenshot?: string): Promise<[string, Data]>;
|
|
19
22
|
findArea(description: string, accessibilityTree: string): Promise<{
|
|
20
23
|
id: number;
|
|
21
24
|
explanation: string;
|
|
22
25
|
}>;
|
|
23
|
-
findElement(description: string, accessibilityTree: string): Promise<
|
|
26
|
+
findElement(description: string, accessibilityTree: string): Promise<FindResponse["elements"][0]>;
|
|
24
27
|
saveCache(): Promise<void>;
|
|
25
28
|
discardCache(): Promise<void>;
|
|
26
|
-
getStats(): Promise<
|
|
29
|
+
getStats(): Promise<StatsResponse>;
|
|
27
30
|
}
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
2
|
-
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
3
|
-
import { Model } from "../Model.js";
|
|
4
1
|
import { convertToolsToSchemas } from "../tools/toolToSchemaConverter.js";
|
|
5
2
|
import { getLogger } from "../utils/logger.js";
|
|
6
3
|
import { looselyTypecast } from "./typecasting.js";
|
|
7
4
|
const logger = getLogger(["HttpClient"]);
|
|
8
5
|
export class HttpClient {
|
|
9
|
-
constructor(baseUrl, platform,
|
|
10
|
-
|
|
11
|
-
tools) {
|
|
6
|
+
constructor(baseUrl, model, platform, tools) {
|
|
7
|
+
this.model = model;
|
|
12
8
|
this.platform = platform;
|
|
13
9
|
this.tools = tools;
|
|
14
10
|
this.sessionId = null;
|
|
@@ -17,21 +13,14 @@ export class HttpClient {
|
|
|
17
13
|
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
18
14
|
}
|
|
19
15
|
async fetchWithTimeout(url, options = {}) {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
});
|
|
27
|
-
if (!response.ok) {
|
|
28
|
-
throw new Error(`HTTP error! status: ${response.status}`);
|
|
29
|
-
}
|
|
30
|
-
return response;
|
|
31
|
-
}
|
|
32
|
-
finally {
|
|
33
|
-
clearTimeout(timeoutId);
|
|
16
|
+
const response = await fetch(url, {
|
|
17
|
+
...options,
|
|
18
|
+
signal: AbortSignal.timeout(this.timeout),
|
|
19
|
+
});
|
|
20
|
+
if (!response.ok) {
|
|
21
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
34
22
|
}
|
|
23
|
+
return response;
|
|
35
24
|
}
|
|
36
25
|
async ensureSession() {
|
|
37
26
|
if (this.sessionId) {
|
|
@@ -40,21 +29,20 @@ export class HttpClient {
|
|
|
40
29
|
if (!this.sessionPromise) {
|
|
41
30
|
this.sessionPromise = (async () => {
|
|
42
31
|
const toolSchemas = convertToolsToSchemas(this.tools);
|
|
32
|
+
const requestBody = {
|
|
33
|
+
provider: this.model.provider,
|
|
34
|
+
name: this.model.name,
|
|
35
|
+
platform: this.platform,
|
|
36
|
+
tools: toolSchemas,
|
|
37
|
+
};
|
|
43
38
|
const response = await this.fetchWithTimeout(`${this.baseUrl}/v1/sessions`, {
|
|
44
39
|
method: "POST",
|
|
45
40
|
headers: {
|
|
46
41
|
"Content-Type": "application/json",
|
|
47
42
|
},
|
|
48
|
-
body: JSON.stringify(
|
|
49
|
-
provider: Model.current.provider,
|
|
50
|
-
name: Model.current.name,
|
|
51
|
-
platform: this.platform,
|
|
52
|
-
tools: toolSchemas,
|
|
53
|
-
}),
|
|
43
|
+
body: JSON.stringify(requestBody),
|
|
54
44
|
});
|
|
55
|
-
|
|
56
|
-
const data = await response.json();
|
|
57
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
45
|
+
const data = (await response.json());
|
|
58
46
|
this.sessionId = data.session_id;
|
|
59
47
|
logger.debug(`Session initialized with ID: ${this.sessionId}`);
|
|
60
48
|
})();
|
|
@@ -71,32 +59,32 @@ export class HttpClient {
|
|
|
71
59
|
}
|
|
72
60
|
async planActions(goal, accessibilityTree) {
|
|
73
61
|
await this.ensureSession();
|
|
62
|
+
const requestBody = {
|
|
63
|
+
goal,
|
|
64
|
+
accessibility_tree: accessibilityTree,
|
|
65
|
+
};
|
|
74
66
|
const response = await this.fetchWithTimeout(`${this.baseUrl}/v1/sessions/${this.sessionId}/plans`, {
|
|
75
67
|
method: "POST",
|
|
76
68
|
headers: {
|
|
77
69
|
"Content-Type": "application/json",
|
|
78
70
|
},
|
|
79
|
-
body: JSON.stringify(
|
|
80
|
-
goal,
|
|
81
|
-
accessibility_tree: accessibilityTree,
|
|
82
|
-
}),
|
|
71
|
+
body: JSON.stringify(requestBody),
|
|
83
72
|
});
|
|
84
|
-
|
|
85
|
-
const responseData = await response.json();
|
|
86
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
73
|
+
const responseData = (await response.json());
|
|
87
74
|
return responseData.steps;
|
|
88
75
|
}
|
|
89
76
|
async addExample(goal, actions) {
|
|
90
77
|
await this.ensureSession();
|
|
78
|
+
const requestBody = {
|
|
79
|
+
goal,
|
|
80
|
+
actions,
|
|
81
|
+
};
|
|
91
82
|
await this.fetchWithTimeout(`${this.baseUrl}/v1/sessions/${this.sessionId}/examples`, {
|
|
92
83
|
method: "POST",
|
|
93
84
|
headers: {
|
|
94
85
|
"Content-Type": "application/json",
|
|
95
86
|
},
|
|
96
|
-
body: JSON.stringify(
|
|
97
|
-
goal,
|
|
98
|
-
actions,
|
|
99
|
-
}),
|
|
87
|
+
body: JSON.stringify(requestBody),
|
|
100
88
|
});
|
|
101
89
|
}
|
|
102
90
|
async clearExamples() {
|
|
@@ -105,80 +93,72 @@ export class HttpClient {
|
|
|
105
93
|
method: "DELETE",
|
|
106
94
|
});
|
|
107
95
|
}
|
|
108
|
-
async executeAction(goal, step, accessibilityTree
|
|
109
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
110
|
-
) {
|
|
96
|
+
async executeAction(goal, step, accessibilityTree) {
|
|
111
97
|
await this.ensureSession();
|
|
98
|
+
const requestBody = {
|
|
99
|
+
goal,
|
|
100
|
+
step,
|
|
101
|
+
accessibility_tree: accessibilityTree,
|
|
102
|
+
};
|
|
112
103
|
const response = await this.fetchWithTimeout(`${this.baseUrl}/v1/sessions/${this.sessionId}/steps`, {
|
|
113
104
|
method: "POST",
|
|
114
105
|
headers: {
|
|
115
106
|
"Content-Type": "application/json",
|
|
116
107
|
},
|
|
117
|
-
body: JSON.stringify(
|
|
118
|
-
goal,
|
|
119
|
-
step,
|
|
120
|
-
accessibility_tree: accessibilityTree,
|
|
121
|
-
}),
|
|
108
|
+
body: JSON.stringify(requestBody),
|
|
122
109
|
});
|
|
123
|
-
|
|
124
|
-
const responseData = await response.json();
|
|
125
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
110
|
+
const responseData = (await response.json());
|
|
126
111
|
return responseData.actions;
|
|
127
112
|
}
|
|
128
113
|
async retrieve(statement, accessibilityTree, title, url, screenshot) {
|
|
129
114
|
await this.ensureSession();
|
|
115
|
+
const requestBody = {
|
|
116
|
+
statement,
|
|
117
|
+
accessibility_tree: accessibilityTree,
|
|
118
|
+
title,
|
|
119
|
+
url,
|
|
120
|
+
screenshot: screenshot || null,
|
|
121
|
+
};
|
|
130
122
|
const response = await this.fetchWithTimeout(`${this.baseUrl}/v1/sessions/${this.sessionId}/statements`, {
|
|
131
123
|
method: "POST",
|
|
132
124
|
headers: {
|
|
133
125
|
"Content-Type": "application/json",
|
|
134
126
|
},
|
|
135
|
-
body: JSON.stringify(
|
|
136
|
-
statement,
|
|
137
|
-
accessibility_tree: accessibilityTree,
|
|
138
|
-
title,
|
|
139
|
-
url,
|
|
140
|
-
screenshot: screenshot || null,
|
|
141
|
-
}),
|
|
127
|
+
body: JSON.stringify(requestBody),
|
|
142
128
|
});
|
|
143
|
-
|
|
144
|
-
const responseData = await response.json();
|
|
145
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument
|
|
129
|
+
const responseData = (await response.json());
|
|
146
130
|
return [responseData.explanation, looselyTypecast(responseData.result)];
|
|
147
131
|
}
|
|
148
132
|
async findArea(description, accessibilityTree) {
|
|
149
133
|
await this.ensureSession();
|
|
134
|
+
const requestBody = {
|
|
135
|
+
description,
|
|
136
|
+
accessibility_tree: accessibilityTree,
|
|
137
|
+
};
|
|
150
138
|
const response = await this.fetchWithTimeout(`${this.baseUrl}/v1/sessions/${this.sessionId}/areas`, {
|
|
151
139
|
method: "POST",
|
|
152
140
|
headers: {
|
|
153
141
|
"Content-Type": "application/json",
|
|
154
142
|
},
|
|
155
|
-
body: JSON.stringify(
|
|
156
|
-
description,
|
|
157
|
-
accessibility_tree: accessibilityTree,
|
|
158
|
-
}),
|
|
143
|
+
body: JSON.stringify(requestBody),
|
|
159
144
|
});
|
|
160
|
-
|
|
161
|
-
const responseData = await response.json();
|
|
162
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
145
|
+
const responseData = (await response.json());
|
|
163
146
|
return { id: responseData.id, explanation: responseData.explanation };
|
|
164
147
|
}
|
|
165
|
-
async findElement(description, accessibilityTree
|
|
166
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
167
|
-
) {
|
|
148
|
+
async findElement(description, accessibilityTree) {
|
|
168
149
|
await this.ensureSession();
|
|
150
|
+
const requestBody = {
|
|
151
|
+
description,
|
|
152
|
+
accessibility_tree: accessibilityTree,
|
|
153
|
+
};
|
|
169
154
|
const response = await this.fetchWithTimeout(`${this.baseUrl}/v1/sessions/${this.sessionId}/elements`, {
|
|
170
155
|
method: "POST",
|
|
171
156
|
headers: {
|
|
172
157
|
"Content-Type": "application/json",
|
|
173
158
|
},
|
|
174
|
-
body: JSON.stringify(
|
|
175
|
-
description,
|
|
176
|
-
accessibility_tree: accessibilityTree,
|
|
177
|
-
}),
|
|
159
|
+
body: JSON.stringify(requestBody),
|
|
178
160
|
});
|
|
179
|
-
|
|
180
|
-
const responseData = await response.json();
|
|
181
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
161
|
+
const responseData = (await response.json());
|
|
182
162
|
return responseData.elements[0];
|
|
183
163
|
}
|
|
184
164
|
async saveCache() {
|
|
@@ -198,7 +178,6 @@ export class HttpClient {
|
|
|
198
178
|
const response = await this.fetchWithTimeout(`${this.baseUrl}/v1/sessions/${this.sessionId}/stats`, {
|
|
199
179
|
method: "GET",
|
|
200
180
|
});
|
|
201
|
-
|
|
202
|
-
return response.json();
|
|
181
|
+
return (await response.json());
|
|
203
182
|
}
|
|
204
183
|
}
|
|
@@ -4,10 +4,11 @@ import { BaseDriver } from "./BaseDriver.js";
|
|
|
4
4
|
import { Key } from "./keys.js";
|
|
5
5
|
export declare class AppiumDriver extends BaseDriver {
|
|
6
6
|
private driver;
|
|
7
|
-
platform:
|
|
7
|
+
platform: "xcuitest" | "uiautomator2";
|
|
8
8
|
supportedTools: Set<string>;
|
|
9
9
|
autoswitchContexts: boolean;
|
|
10
10
|
delay: number;
|
|
11
|
+
doubleFetchPageSource: boolean;
|
|
11
12
|
hideKeyboardAfterTyping: boolean;
|
|
12
13
|
constructor(driver: Browser);
|
|
13
14
|
getAccessibilityTree(): Promise<BaseAccessibilityTree>;
|