askui 0.10.4 → 0.10.5
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/dist/cjs/execution/inference-client.d.ts +5 -5
- package/dist/cjs/execution/inference-client.js +10 -9
- package/dist/cjs/utils/http/http-client-got.d.ts +4 -0
- package/dist/cjs/utils/http/http-client-got.js +48 -1
- package/dist/esm/execution/inference-client.d.ts +5 -5
- package/dist/esm/execution/inference-client.js +10 -9
- package/dist/esm/utils/http/http-client-got.d.ts +4 -0
- package/dist/esm/utils/http/http-client-got.js +48 -1
- package/package.json +2 -2
|
@@ -5,13 +5,13 @@ import { Annotation } from '../core/annotation/annotation';
|
|
|
5
5
|
import { DetectedElement } from '../core/model/annotation-result/detected-element';
|
|
6
6
|
import { ModelCompositionBranch } from './model-composition-branch';
|
|
7
7
|
export declare class InferenceClient {
|
|
8
|
-
baseUrl
|
|
9
|
-
httpClient
|
|
10
|
-
|
|
8
|
+
private readonly baseUrl;
|
|
9
|
+
private readonly httpClient;
|
|
10
|
+
private readonly resize?;
|
|
11
11
|
readonly workspaceId?: string | undefined;
|
|
12
12
|
readonly modelComposition?: ModelCompositionBranch[] | undefined;
|
|
13
|
-
apiVersion
|
|
14
|
-
|
|
13
|
+
private readonly apiVersion;
|
|
14
|
+
private urls;
|
|
15
15
|
constructor(baseUrl: string, httpClient: HttpClientGot, resize?: number | undefined, workspaceId?: string | undefined, modelComposition?: ModelCompositionBranch[] | undefined, apiVersion?: string);
|
|
16
16
|
isImageRequired(instruction: string): Promise<boolean>;
|
|
17
17
|
private resizeIfNeeded;
|
|
@@ -29,9 +29,14 @@ class InferenceClient {
|
|
|
29
29
|
this.modelComposition = modelComposition;
|
|
30
30
|
this.apiVersion = apiVersion;
|
|
31
31
|
const versionedBaseUrl = (0, url_join_1.default)(this.baseUrl, 'api', this.apiVersion);
|
|
32
|
-
|
|
32
|
+
const url = workspaceId
|
|
33
33
|
? (0, url_join_1.default)(versionedBaseUrl, 'workspaces', workspaceId)
|
|
34
34
|
: versionedBaseUrl;
|
|
35
|
+
this.urls = {
|
|
36
|
+
inference: (0, url_join_1.default)(url, 'inference'),
|
|
37
|
+
isImageRequired: (0, url_join_1.default)(url, 'instruction', 'is-image-required'),
|
|
38
|
+
};
|
|
39
|
+
this.httpClient.urlsToRetry = Object.values(this.urls);
|
|
35
40
|
if (this.resize !== undefined && this.resize <= 0) {
|
|
36
41
|
throw new config_error_1.ConfigurationError(`Resize must be a positive number. The current resize value "${this.resize}" is not valid.`);
|
|
37
42
|
}
|
|
@@ -39,11 +44,9 @@ class InferenceClient {
|
|
|
39
44
|
}
|
|
40
45
|
isImageRequired(instruction) {
|
|
41
46
|
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
-
const
|
|
43
|
-
const requestBody = {
|
|
47
|
+
const response = yield this.httpClient.post(this.urls.isImageRequired, {
|
|
44
48
|
instruction,
|
|
45
|
-
};
|
|
46
|
-
const response = yield this.httpClient.post(url, requestBody);
|
|
49
|
+
});
|
|
47
50
|
return response.body.isImageRequired;
|
|
48
51
|
});
|
|
49
52
|
}
|
|
@@ -59,14 +62,12 @@ class InferenceClient {
|
|
|
59
62
|
inference(customElements = [], image, instruction) {
|
|
60
63
|
return __awaiter(this, void 0, void 0, function* () {
|
|
61
64
|
const resizedImage = yield this.resizeIfNeeded(customElements, image);
|
|
62
|
-
const
|
|
65
|
+
const response = yield this.httpClient.post(this.urls.inference, {
|
|
63
66
|
image: resizedImage.base64Image,
|
|
64
67
|
instruction,
|
|
65
68
|
customElements,
|
|
66
69
|
modelComposition: this.modelComposition,
|
|
67
|
-
};
|
|
68
|
-
const url = (0, url_join_1.default)(this.url, 'inference');
|
|
69
|
-
const response = yield this.httpClient.post(url, requestBody);
|
|
70
|
+
});
|
|
70
71
|
InferenceClient.logMetaInformation(response);
|
|
71
72
|
return ui_control_commands_1.InferenceResponse.fromJson(response.body, resizedImage.resizeRatio, image);
|
|
72
73
|
});
|
|
@@ -12,10 +12,14 @@ export declare class HttpClientGot {
|
|
|
12
12
|
} | undefined;
|
|
13
13
|
private headers;
|
|
14
14
|
private askuiGot;
|
|
15
|
+
urlsToRetry: string[];
|
|
15
16
|
constructor(token?: string | undefined, customHeaders?: Record<string, string> | undefined, cookies?: Record<string, string>, proxyAgents?: {
|
|
16
17
|
http: http.Agent;
|
|
17
18
|
https: https.Agent;
|
|
18
19
|
} | undefined);
|
|
20
|
+
private buildGotExtendOptions;
|
|
21
|
+
private shouldRetryOnError;
|
|
22
|
+
private shouldRetryPostRequest;
|
|
19
23
|
private initHeaders;
|
|
20
24
|
private injectHeadersAndCookies;
|
|
21
25
|
post<T>(url: string, data: Record<string | number | symbol, unknown>): Promise<{
|
|
@@ -25,8 +25,55 @@ class HttpClientGot {
|
|
|
25
25
|
this.cookies = cookies;
|
|
26
26
|
this.proxyAgents = proxyAgents;
|
|
27
27
|
this.headers = {};
|
|
28
|
+
this.urlsToRetry = [];
|
|
28
29
|
this.initHeaders(token, customHeaders);
|
|
29
|
-
|
|
30
|
+
const gotExtendOptions = this.buildGotExtendOptions(proxyAgents);
|
|
31
|
+
this.askuiGot = got_1.default.extend(gotExtendOptions);
|
|
32
|
+
}
|
|
33
|
+
buildGotExtendOptions(proxyAgents) {
|
|
34
|
+
const gotExtendOptions = {
|
|
35
|
+
retry: {
|
|
36
|
+
limit: 5,
|
|
37
|
+
methods: ['POST', 'GET', 'PUT', 'HEAD', 'DELETE', 'OPTIONS', 'TRACE'],
|
|
38
|
+
statusCodes: [408, 413, 429, 500, 502, 503, 504, 521, 522, 524],
|
|
39
|
+
errorCodes: [
|
|
40
|
+
'ETIMEDOUT',
|
|
41
|
+
'ECONNRESET',
|
|
42
|
+
'EADDRINUSE',
|
|
43
|
+
'ECONNREFUSED',
|
|
44
|
+
'EPIPE',
|
|
45
|
+
'ENOTFOUND',
|
|
46
|
+
'ENETUNREACH',
|
|
47
|
+
'EAI_AGAIN',
|
|
48
|
+
],
|
|
49
|
+
calculateDelay: ({ attemptCount, retryOptions, error, computedValue, }) => {
|
|
50
|
+
var _a, _b, _c;
|
|
51
|
+
if (attemptCount > retryOptions.limit
|
|
52
|
+
|| !this.shouldRetryOnError(error)) {
|
|
53
|
+
return 0;
|
|
54
|
+
}
|
|
55
|
+
if (error.response !== undefined
|
|
56
|
+
&& error.response.headers['retry-after'] === undefined) {
|
|
57
|
+
lib_1.logger.debug(`Request to ${(_a = error.request) === null || _a === void 0 ? void 0 : _a.requestUrl} failed with status code ${(_b = error.response) === null || _b === void 0 ? void 0 : _b.statusCode}.\n${error.message}\nRetrying... (attempt ${attemptCount})`);
|
|
58
|
+
return Math.min(1000 * Math.pow(2, (attemptCount - 1)) + Math.random() * 100, Number.MAX_SAFE_INTEGER);
|
|
59
|
+
}
|
|
60
|
+
lib_1.logger.debug(`Request to ${(_c = error.request) === null || _c === void 0 ? void 0 : _c.requestUrl} failed.\n${error.message}\nRetrying... (attempt ${attemptCount})`);
|
|
61
|
+
return computedValue;
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
if (proxyAgents) {
|
|
66
|
+
gotExtendOptions.agent = proxyAgents;
|
|
67
|
+
}
|
|
68
|
+
return gotExtendOptions;
|
|
69
|
+
}
|
|
70
|
+
shouldRetryOnError(error) {
|
|
71
|
+
var _a;
|
|
72
|
+
return (((_a = error.request) === null || _a === void 0 ? void 0 : _a.options.method) !== 'POST'
|
|
73
|
+
|| this.shouldRetryPostRequest(error.request));
|
|
74
|
+
}
|
|
75
|
+
shouldRetryPostRequest(request) {
|
|
76
|
+
return (request !== undefined && this.urlsToRetry.includes(request.requestUrl));
|
|
30
77
|
}
|
|
31
78
|
initHeaders(token, customHeaders = {}) {
|
|
32
79
|
const credentials = token ? new credentials_1.Credentials(token) : undefined;
|
|
@@ -5,13 +5,13 @@ import { Annotation } from '../core/annotation/annotation';
|
|
|
5
5
|
import { DetectedElement } from '../core/model/annotation-result/detected-element';
|
|
6
6
|
import { ModelCompositionBranch } from './model-composition-branch';
|
|
7
7
|
export declare class InferenceClient {
|
|
8
|
-
baseUrl
|
|
9
|
-
httpClient
|
|
10
|
-
|
|
8
|
+
private readonly baseUrl;
|
|
9
|
+
private readonly httpClient;
|
|
10
|
+
private readonly resize?;
|
|
11
11
|
readonly workspaceId?: string | undefined;
|
|
12
12
|
readonly modelComposition?: ModelCompositionBranch[] | undefined;
|
|
13
|
-
apiVersion
|
|
14
|
-
|
|
13
|
+
private readonly apiVersion;
|
|
14
|
+
private urls;
|
|
15
15
|
constructor(baseUrl: string, httpClient: HttpClientGot, resize?: number | undefined, workspaceId?: string | undefined, modelComposition?: ModelCompositionBranch[] | undefined, apiVersion?: string);
|
|
16
16
|
isImageRequired(instruction: string): Promise<boolean>;
|
|
17
17
|
private resizeIfNeeded;
|
|
@@ -23,9 +23,14 @@ export class InferenceClient {
|
|
|
23
23
|
this.modelComposition = modelComposition;
|
|
24
24
|
this.apiVersion = apiVersion;
|
|
25
25
|
const versionedBaseUrl = urljoin(this.baseUrl, 'api', this.apiVersion);
|
|
26
|
-
|
|
26
|
+
const url = workspaceId
|
|
27
27
|
? urljoin(versionedBaseUrl, 'workspaces', workspaceId)
|
|
28
28
|
: versionedBaseUrl;
|
|
29
|
+
this.urls = {
|
|
30
|
+
inference: urljoin(url, 'inference'),
|
|
31
|
+
isImageRequired: urljoin(url, 'instruction', 'is-image-required'),
|
|
32
|
+
};
|
|
33
|
+
this.httpClient.urlsToRetry = Object.values(this.urls);
|
|
29
34
|
if (this.resize !== undefined && this.resize <= 0) {
|
|
30
35
|
throw new ConfigurationError(`Resize must be a positive number. The current resize value "${this.resize}" is not valid.`);
|
|
31
36
|
}
|
|
@@ -33,11 +38,9 @@ export class InferenceClient {
|
|
|
33
38
|
}
|
|
34
39
|
isImageRequired(instruction) {
|
|
35
40
|
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
-
const
|
|
37
|
-
const requestBody = {
|
|
41
|
+
const response = yield this.httpClient.post(this.urls.isImageRequired, {
|
|
38
42
|
instruction,
|
|
39
|
-
};
|
|
40
|
-
const response = yield this.httpClient.post(url, requestBody);
|
|
43
|
+
});
|
|
41
44
|
return response.body.isImageRequired;
|
|
42
45
|
});
|
|
43
46
|
}
|
|
@@ -53,14 +56,12 @@ export class InferenceClient {
|
|
|
53
56
|
inference(customElements = [], image, instruction) {
|
|
54
57
|
return __awaiter(this, void 0, void 0, function* () {
|
|
55
58
|
const resizedImage = yield this.resizeIfNeeded(customElements, image);
|
|
56
|
-
const
|
|
59
|
+
const response = yield this.httpClient.post(this.urls.inference, {
|
|
57
60
|
image: resizedImage.base64Image,
|
|
58
61
|
instruction,
|
|
59
62
|
customElements,
|
|
60
63
|
modelComposition: this.modelComposition,
|
|
61
|
-
};
|
|
62
|
-
const url = urljoin(this.url, 'inference');
|
|
63
|
-
const response = yield this.httpClient.post(url, requestBody);
|
|
64
|
+
});
|
|
64
65
|
InferenceClient.logMetaInformation(response);
|
|
65
66
|
return InferenceResponse.fromJson(response.body, resizedImage.resizeRatio, image);
|
|
66
67
|
});
|
|
@@ -12,10 +12,14 @@ export declare class HttpClientGot {
|
|
|
12
12
|
} | undefined;
|
|
13
13
|
private headers;
|
|
14
14
|
private askuiGot;
|
|
15
|
+
urlsToRetry: string[];
|
|
15
16
|
constructor(token?: string | undefined, customHeaders?: Record<string, string> | undefined, cookies?: Record<string, string>, proxyAgents?: {
|
|
16
17
|
http: http.Agent;
|
|
17
18
|
https: https.Agent;
|
|
18
19
|
} | undefined);
|
|
20
|
+
private buildGotExtendOptions;
|
|
21
|
+
private shouldRetryOnError;
|
|
22
|
+
private shouldRetryPostRequest;
|
|
19
23
|
private initHeaders;
|
|
20
24
|
private injectHeadersAndCookies;
|
|
21
25
|
post<T>(url: string, data: Record<string | number | symbol, unknown>): Promise<{
|
|
@@ -19,8 +19,55 @@ export class HttpClientGot {
|
|
|
19
19
|
this.cookies = cookies;
|
|
20
20
|
this.proxyAgents = proxyAgents;
|
|
21
21
|
this.headers = {};
|
|
22
|
+
this.urlsToRetry = [];
|
|
22
23
|
this.initHeaders(token, customHeaders);
|
|
23
|
-
|
|
24
|
+
const gotExtendOptions = this.buildGotExtendOptions(proxyAgents);
|
|
25
|
+
this.askuiGot = got.extend(gotExtendOptions);
|
|
26
|
+
}
|
|
27
|
+
buildGotExtendOptions(proxyAgents) {
|
|
28
|
+
const gotExtendOptions = {
|
|
29
|
+
retry: {
|
|
30
|
+
limit: 5,
|
|
31
|
+
methods: ['POST', 'GET', 'PUT', 'HEAD', 'DELETE', 'OPTIONS', 'TRACE'],
|
|
32
|
+
statusCodes: [408, 413, 429, 500, 502, 503, 504, 521, 522, 524],
|
|
33
|
+
errorCodes: [
|
|
34
|
+
'ETIMEDOUT',
|
|
35
|
+
'ECONNRESET',
|
|
36
|
+
'EADDRINUSE',
|
|
37
|
+
'ECONNREFUSED',
|
|
38
|
+
'EPIPE',
|
|
39
|
+
'ENOTFOUND',
|
|
40
|
+
'ENETUNREACH',
|
|
41
|
+
'EAI_AGAIN',
|
|
42
|
+
],
|
|
43
|
+
calculateDelay: ({ attemptCount, retryOptions, error, computedValue, }) => {
|
|
44
|
+
var _a, _b, _c;
|
|
45
|
+
if (attemptCount > retryOptions.limit
|
|
46
|
+
|| !this.shouldRetryOnError(error)) {
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
if (error.response !== undefined
|
|
50
|
+
&& error.response.headers['retry-after'] === undefined) {
|
|
51
|
+
logger.debug(`Request to ${(_a = error.request) === null || _a === void 0 ? void 0 : _a.requestUrl} failed with status code ${(_b = error.response) === null || _b === void 0 ? void 0 : _b.statusCode}.\n${error.message}\nRetrying... (attempt ${attemptCount})`);
|
|
52
|
+
return Math.min(1000 * Math.pow(2, (attemptCount - 1)) + Math.random() * 100, Number.MAX_SAFE_INTEGER);
|
|
53
|
+
}
|
|
54
|
+
logger.debug(`Request to ${(_c = error.request) === null || _c === void 0 ? void 0 : _c.requestUrl} failed.\n${error.message}\nRetrying... (attempt ${attemptCount})`);
|
|
55
|
+
return computedValue;
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
if (proxyAgents) {
|
|
60
|
+
gotExtendOptions.agent = proxyAgents;
|
|
61
|
+
}
|
|
62
|
+
return gotExtendOptions;
|
|
63
|
+
}
|
|
64
|
+
shouldRetryOnError(error) {
|
|
65
|
+
var _a;
|
|
66
|
+
return (((_a = error.request) === null || _a === void 0 ? void 0 : _a.options.method) !== 'POST'
|
|
67
|
+
|| this.shouldRetryPostRequest(error.request));
|
|
68
|
+
}
|
|
69
|
+
shouldRetryPostRequest(request) {
|
|
70
|
+
return (request !== undefined && this.urlsToRetry.includes(request.requestUrl));
|
|
24
71
|
}
|
|
25
72
|
initHeaders(token, customHeaders = {}) {
|
|
26
73
|
const credentials = token ? new Credentials(token) : undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "askui",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.5",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "askui GmbH <info@askui.com> (http://www.askui.com/)",
|
|
6
6
|
"description": "Reliable, automated end-to-end-testing that depends on what is shown on your screen instead of the technology you are running on",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"commander": "8.3.0",
|
|
53
53
|
"fkill": "7.2.1",
|
|
54
54
|
"fs-extra": "10.0.0",
|
|
55
|
-
"got": "11.8.
|
|
55
|
+
"got": "11.8.6",
|
|
56
56
|
"jsdom": "20.0.0",
|
|
57
57
|
"node-machine-id": "1.1.12",
|
|
58
58
|
"pino": "7.8.1",
|