@jrpool/kilotest 36.2.0 → 37.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/alerts.js +1 -1
- package/{AI-TOOL.md → docs/AI-TOOL.md} +1 -1
- package/eslint.config.mjs +4 -1
- package/index.js +6 -5
- package/llms-full.txt +5 -5
- package/llms.txt +2 -2
- package/mcp.js +12 -12
- package/openapi.yaml +63 -13
- package/package.json +1 -1
- package/reportIssue/api.js +4 -4
- package/reportIssues/api.js +4 -4
- package/reportList/api.js +75 -0
- package/researchAgent.js +2 -2
- package/target/api.js +6 -6
- package/testRecForm/api.js +1 -1
- package/tutorial/index.js +15 -5
- package/util.js +7 -1
- package/targets/api.js +0 -99
- /package/{IDEAS.md → docs/IDEAS.md} +0 -0
- /package/{SERVICE.md → docs/SERVICE.md} +0 -0
package/alerts.js
CHANGED
|
@@ -19,7 +19,7 @@ const ALERT_FROM = process.env.ALERT_FROM;
|
|
|
19
19
|
// FUNCTIONS
|
|
20
20
|
|
|
21
21
|
// Sends an email alert to a manager.
|
|
22
|
-
exports.sendAlert = (subject, body) => new Promise(
|
|
22
|
+
exports.sendAlert = (subject, body) => new Promise(resolve => {
|
|
23
23
|
// If the alert configuration is complete:
|
|
24
24
|
if (MANAGER_EMAIL && ALERT_API_HOST && ALERT_API_PATH && ALERT_API_KEY && ALERT_FROM) {
|
|
25
25
|
const payload = JSON.stringify({
|
|
@@ -185,4 +185,4 @@ The [Perplexity documentation](https://www.perplexity.ai/help-center/en/articles
|
|
|
185
185
|
|
|
186
186
|
Once the compatibility of Kilotest as a connector with AI platforms of two different vendors had been confirmed, the focus of work returned to completion of the missing endpoints of the API. The first was an endpoint that would let a model efficiently search for an available report about a particular web page.
|
|
187
187
|
|
|
188
|
-
The new `
|
|
188
|
+
The new `summarizeQualityOfMatchingWebPages` tool provides inputs for fragments of a description and of a URL hostname of a web page and responds with summary data about all and only the available reports of pages that match at least one of those fragments, where matching means either including or being included by the provided fragment, case-insensitively.
|
package/eslint.config.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import globals from "globals";
|
|
|
3
3
|
import json from "@eslint/json";
|
|
4
4
|
import markdown from "@eslint/markdown";
|
|
5
5
|
import css from "@eslint/css";
|
|
6
|
-
import {
|
|
6
|
+
import {defineConfig} from "eslint/config";
|
|
7
7
|
|
|
8
8
|
export default defineConfig([
|
|
9
9
|
{
|
|
@@ -18,6 +18,9 @@ export default defineConfig([
|
|
|
18
18
|
extends: ["js/recommended"],
|
|
19
19
|
languageOptions: {
|
|
20
20
|
globals: globals.node
|
|
21
|
+
},
|
|
22
|
+
rules: {
|
|
23
|
+
"no-control-regex": "off"
|
|
21
24
|
}
|
|
22
25
|
},
|
|
23
26
|
{
|
package/index.js
CHANGED
|
@@ -30,6 +30,7 @@ const {
|
|
|
30
30
|
} = require('./util');
|
|
31
31
|
const {handleMCP, mcpPath} = require('./mcp');
|
|
32
32
|
const fs = require('fs/promises');
|
|
33
|
+
const {handleComment} = require('./tutorial/index');
|
|
33
34
|
const http = require('http');
|
|
34
35
|
const https = require('https');
|
|
35
36
|
const path = require('path');
|
|
@@ -342,10 +343,10 @@ const requestHandler = async (request, response) => {
|
|
|
342
343
|
// Otherwise, if it is for an API service:
|
|
343
344
|
else if (pageName === 'api') {
|
|
344
345
|
const [service, ... specs] = pathTail.split('/');
|
|
345
|
-
// If the service is provision of
|
|
346
|
-
if (service === '
|
|
346
|
+
// If the service is provision of a list of all available reports:
|
|
347
|
+
if (service === 'reportList') {
|
|
347
348
|
// Get the response (potentially error) data.
|
|
348
|
-
const responseData = await require(path.join(__dirname, '
|
|
349
|
+
const responseData = await require(path.join(__dirname, 'reportList', 'api')).response(specs);
|
|
349
350
|
// Send them.
|
|
350
351
|
setHeaders('application/json', null, 'ultra');
|
|
351
352
|
response.end(JSON.stringify(responseData));
|
|
@@ -702,7 +703,7 @@ const requestHandler = async (request, response) => {
|
|
|
702
703
|
// Otherwise, if the first segment is the report finding service:
|
|
703
704
|
else if (segments[0] === 'target') {
|
|
704
705
|
const {what = '', hostname = ''} = postData;
|
|
705
|
-
// If the payload contains a description fragment or
|
|
706
|
+
// If the payload contains a description fragment or hostname fragment:
|
|
706
707
|
if (what || hostname) {
|
|
707
708
|
// Process the request and get the response data.
|
|
708
709
|
const responseData = await require(path.join(__dirname, 'target', 'api'))
|
|
@@ -762,7 +763,7 @@ const requestHandler = async (request, response) => {
|
|
|
762
763
|
else if (pageName === 'tutorialComment.html') {
|
|
763
764
|
const {content} = postData;
|
|
764
765
|
setHeaders('application/json', null, 'low');
|
|
765
|
-
const answerData = await
|
|
766
|
+
const answerData = await handleComment(content);
|
|
766
767
|
if (answerData.status === 'ok') {
|
|
767
768
|
response.end(JSON.stringify({status: 'ok'}));
|
|
768
769
|
}
|
package/llms-full.txt
CHANGED
|
@@ -82,10 +82,10 @@ The implementation is currently in an alpha phase and offers 4 tools:
|
|
|
82
82
|
- payload properties
|
|
83
83
|
- `what`: all or part of a description of the page
|
|
84
84
|
- `hostname`: all or part of the hostname of the page
|
|
85
|
-
- `
|
|
85
|
+
- `getListOfAllAvailableReports`
|
|
86
86
|
- method: `GET`
|
|
87
|
-
- purpose:
|
|
88
|
-
- path: `/api/
|
|
87
|
+
- purpose: get a list of all available reports
|
|
88
|
+
- path: `/api/reportList`
|
|
89
89
|
- caveat: Cached results are likely to be stale and should not be used
|
|
90
90
|
- `describeQualityOfOneWebPage`
|
|
91
91
|
- method: `GET`
|
|
@@ -94,7 +94,7 @@ The implementation is currently in an alpha phase and offers 4 tools:
|
|
|
94
94
|
- parameters
|
|
95
95
|
- `timeStamp`: initial segment of report identifier
|
|
96
96
|
- `jobID`: final segment of report identifier
|
|
97
|
-
- source of parameters: response to a `
|
|
97
|
+
- source of parameters: response to a `getListOfAllAvailableReports` request
|
|
98
98
|
- `describeOneIssueFromOneReport`
|
|
99
99
|
- method: `GET`
|
|
100
100
|
- purpose: provide details about one issue from one report
|
|
@@ -156,7 +156,7 @@ More information about Kilotest features and internals:
|
|
|
156
156
|
|
|
157
157
|
### For language models and AI platforms
|
|
158
158
|
|
|
159
|
-
- [AI-TOOL file](https://github.com/jrpool/kilotest/blob/main/AI-TOOL.md)
|
|
159
|
+
- [AI-TOOL file](https://github.com/jrpool/kilotest/blob/main/docs/AI-TOOL.md)
|
|
160
160
|
- [OpenAPI specification for Kilotest](https://kilotest.com/openapi.yaml)
|
|
161
161
|
- [Tool caller for testing](https://github.com/jrpool/kilotest/blob/main/researchAgent.js)
|
|
162
162
|
|
package/llms.txt
CHANGED
|
@@ -8,8 +8,8 @@ There is a [detailed explanation of Kilotest and its capabilities for LLMs](http
|
|
|
8
8
|
|
|
9
9
|
## API
|
|
10
10
|
|
|
11
|
-
- [
|
|
12
|
-
- [Get
|
|
11
|
+
- [Get summaries of reports about a specified web page](/api/target)
|
|
12
|
+
- [Get a list of all available reports](/api/reportList)
|
|
13
13
|
- Get summarized test results from one report: `/api/reportIssues/{timeStamp}/{jobID}`
|
|
14
14
|
- Get details about one issue from one report: `/api/reportIssue/{issueID}/{timeStamp}/{jobID}`
|
|
15
15
|
- Recommend testing of a web page: `/api/testRecForm` (requires `POST` request)
|
package/mcp.js
CHANGED
|
@@ -10,7 +10,7 @@ const {StreamableHTTPServerTransport} = require('@modelcontextprotocol/sdk/serve
|
|
|
10
10
|
const {z} = require('zod');
|
|
11
11
|
const {isReportAvailable, isURL} = require('./util');
|
|
12
12
|
const targetAPI = require('./target/api');
|
|
13
|
-
const
|
|
13
|
+
const reportListAPI = require('./reportList/api');
|
|
14
14
|
const reportIssuesAPI = require('./reportIssues/api');
|
|
15
15
|
const reportIssueAPI = require('./reportIssue/api');
|
|
16
16
|
const testRecFormAPI = require('./testRecForm/api');
|
|
@@ -27,10 +27,10 @@ const createMCPServer = () => {
|
|
|
27
27
|
server.registerTool(
|
|
28
28
|
'summarizeQualityOfMatchingWebPages',
|
|
29
29
|
{
|
|
30
|
-
description: 'Returns summary data from every available Kilotest report about the front-end quality (i.e. accessibility, usability, and standards conformity) of web pages that match the description or hostname fragment of a web page that you have provided. Matching is case-insensitive and succeeds if the page property either is included by or includes the specified
|
|
30
|
+
description: 'Returns summary data from every available Kilotest report about the front-end quality (i.e. accessibility, usability, and standards conformity) of web pages that match the description or hostname fragment of a web page that you have provided. Matching is case-insensitive and succeeds if the page property either is included by or includes the specified fragment.',
|
|
31
31
|
inputSchema: {
|
|
32
32
|
what: z.string().describe('All or part of a description of the web page.'),
|
|
33
|
-
|
|
33
|
+
hostname: z.string().describe('All or part of the hostname of the URL of the web page.')
|
|
34
34
|
},
|
|
35
35
|
annotations: {
|
|
36
36
|
title: 'Summarize the quality of matching web pages',
|
|
@@ -40,18 +40,18 @@ const createMCPServer = () => {
|
|
|
40
40
|
openWorldHint: false
|
|
41
41
|
}
|
|
42
42
|
},
|
|
43
|
-
async ({what,
|
|
44
|
-
const result = await targetAPI.response([what,
|
|
43
|
+
async ({what, hostname}) => {
|
|
44
|
+
const result = await targetAPI.response([what, hostname]);
|
|
45
45
|
return {content: [{type: 'text', text: JSON.stringify(result)}]};
|
|
46
46
|
}
|
|
47
47
|
);
|
|
48
48
|
server.registerTool(
|
|
49
|
-
'
|
|
49
|
+
'getListOfAllAvailableReports',
|
|
50
50
|
{
|
|
51
|
-
description: 'Returns
|
|
51
|
+
description: 'Returns a list of all available Kilotest reports; each report describes the results of a job that tested one web page for front-end quality (i.e. accessibility, usability, and standards conformity).',
|
|
52
52
|
inputSchema: {},
|
|
53
53
|
annotations: {
|
|
54
|
-
title: '
|
|
54
|
+
title: 'Get a list of all available reports',
|
|
55
55
|
readOnlyHint: true,
|
|
56
56
|
idempotentHint: true,
|
|
57
57
|
destructiveHint: false,
|
|
@@ -59,14 +59,14 @@ const createMCPServer = () => {
|
|
|
59
59
|
}
|
|
60
60
|
},
|
|
61
61
|
async () => {
|
|
62
|
-
const result = await
|
|
62
|
+
const result = await reportListAPI.response();
|
|
63
63
|
return {content: [{type: 'text', text: JSON.stringify(result)}]};
|
|
64
64
|
}
|
|
65
65
|
);
|
|
66
66
|
server.registerTool(
|
|
67
67
|
'describeQualityOfOneWebPage',
|
|
68
68
|
{
|
|
69
|
-
description: 'Returns data from a specified Kilotest report about issues for the front-end quality (i.e. accessibility, usability, and standards conformity) of a web page. The required timeStamp and jobID parameters identify the report and are obtained from a
|
|
69
|
+
description: 'Returns data from a specified Kilotest report about issues for the front-end quality (i.e. accessibility, usability, and standards conformity) of a web page. The required timeStamp and jobID parameters identify the report and are obtained from a getListOfAllAvailableReports response.',
|
|
70
70
|
inputSchema: {
|
|
71
71
|
timeStamp: z.string().describe('Report timestamp in YYMMDDTHHMM format, e.g. 260503T0432'),
|
|
72
72
|
jobID: z.string().describe('Job identifier, e.g. x9z')
|
|
@@ -109,9 +109,9 @@ const createMCPServer = () => {
|
|
|
109
109
|
server.registerTool(
|
|
110
110
|
'recommendQualityTestingOfOneWebPage',
|
|
111
111
|
{
|
|
112
|
-
description: 'Recommends a web page for Kilotest to test for front-end quality (i.e. accessibility, usability, and standards conformity). Do not call this tool until after you call
|
|
112
|
+
description: 'Recommends a web page for Kilotest to test for front-end quality (i.e. accessibility, usability, and standards conformity). Do not call this tool until after you call getListOfAllAvailableReports to check whether a report about the page, or a related page that satisfies your requirements, is available and to understand the naming conventions for pages.',
|
|
113
113
|
inputSchema: {
|
|
114
|
-
what: z.string().describe('Short description of the page, following the naming conventions visible in the
|
|
114
|
+
what: z.string().describe('Short description of the page, following the naming conventions visible in the getListOfAllAvailableReports response'),
|
|
115
115
|
url: z.string().describe('Full HTTPS URL of the page to test'),
|
|
116
116
|
why: z.string().describe('Reason for recommending this page for testing')
|
|
117
117
|
},
|
package/openapi.yaml
CHANGED
|
@@ -17,7 +17,7 @@ paths:
|
|
|
17
17
|
post:
|
|
18
18
|
operationId: summarizeQualityOfMatchingWebPages
|
|
19
19
|
summary: Summarize the quality of matching web pages
|
|
20
|
-
description: Get summary data from the available reports about web pages whose descriptions or hostnames match your specifications. Matching is case-insensitive and succeeds at least 1 specification is included by or includes the corresponding property of a tested page. The data include the name and URL of each tested web page, when the testing was performed, how many front-end quality (i.e. accessibility, usability, and standards conformity) issues were reported, and URLs for retrieving more detailed data from the report.
|
|
20
|
+
description: Get summary data from the available reports about web pages whose descriptions or hostnames match your specifications. Matching is case-insensitive and succeeds if at least 1 specification is included by or includes the corresponding property of a tested page. The data include the name and URL of each tested web page, when the testing was performed, how many front-end quality (i.e. accessibility, usability, and standards conformity) issues were reported, and URLs for retrieving more detailed data from the report.
|
|
21
21
|
requestBody:
|
|
22
22
|
description: Page specifications
|
|
23
23
|
required: true
|
|
@@ -33,24 +33,24 @@ paths:
|
|
|
33
33
|
schema:
|
|
34
34
|
$ref: '#/components/schemas/TargetsResponse'
|
|
35
35
|
|
|
36
|
-
/api/
|
|
36
|
+
/api/reportList:
|
|
37
37
|
get:
|
|
38
|
-
operationId:
|
|
39
|
-
summary:
|
|
40
|
-
description: Get
|
|
38
|
+
operationId: getListOfAllAvailableReports
|
|
39
|
+
summary: Get a list of all available reports
|
|
40
|
+
description: Get a list of all available reports. Each report describes the results of a job that tested a web page for front-end quality (i.e. accessibility, usability, and standards conformity). For each report, the list identifies which page was tested and when and provides URLs to begin incremental retrieval of the test results.
|
|
41
41
|
responses:
|
|
42
42
|
'200':
|
|
43
|
-
description:
|
|
43
|
+
description: List of all available reports
|
|
44
44
|
content:
|
|
45
45
|
application/json:
|
|
46
46
|
schema:
|
|
47
|
-
$ref: '#/components/schemas/
|
|
47
|
+
$ref: '#/components/schemas/ReportListResponse'
|
|
48
48
|
|
|
49
49
|
/api/testRecForm:
|
|
50
50
|
post:
|
|
51
51
|
operationId: recommendQualityTestingOfOneWebPage
|
|
52
52
|
summary: Recommend quality testing of one web page
|
|
53
|
-
description: Submit a recommendation for Kilotest to test, for the first time, a particular web page for front-end quality (i.e. accessibility, usability, and standards conformity). Recommendations are typically approved and the testing completed within a day, whereupon the results can be found with the
|
|
53
|
+
description: Submit a recommendation for Kilotest to test, for the first time, a particular web page for front-end quality (i.e. accessibility, usability, and standards conformity). Recommendations are typically approved and the testing completed within a day, whereupon the results can be found with the getListOfAllAvailableReports operation. Before submitting a recommendation, use the getListOfAllAvailableReports operation to ensure that no report about the page is available, and also to see the stylistic rules for the naming of pages. An attempt to recommend a page for testing will fail if a report about the page is already available.
|
|
54
54
|
requestBody:
|
|
55
55
|
description: Test recommendation specifications
|
|
56
56
|
required: true
|
|
@@ -70,7 +70,7 @@ paths:
|
|
|
70
70
|
get:
|
|
71
71
|
operationId: describeQualityOfOneWebPage
|
|
72
72
|
summary: Describe quality of one web page
|
|
73
|
-
description: Get data about the quality of a specified Kilotest report. The data about each issue include its priority, the rule engines that reported it, the number of HTML elements exhibiting it, and URLs for retrieving element-level detail. The timeStamp and jobID parameters identify the report and are available in the response from the
|
|
73
|
+
description: Get data about the quality of a specified Kilotest report. The data about each issue include its priority, the rule engines that reported it, the number of HTML elements exhibiting it, and URLs for retrieving element-level detail. The timeStamp and jobID parameters identify the report and are available in the response from the getListOfAllAvailableReports operation.
|
|
74
74
|
parameters:
|
|
75
75
|
- name: timeStamp
|
|
76
76
|
in: path
|
|
@@ -146,10 +146,14 @@ components:
|
|
|
146
146
|
summary:
|
|
147
147
|
type: string
|
|
148
148
|
description: Natural-language description of this response and of Kilotest. Provides context for an agent encountering Kilotest for the first time.
|
|
149
|
-
tool name:
|
|
149
|
+
tool collection name:
|
|
150
150
|
type: string
|
|
151
151
|
examples:
|
|
152
152
|
- Kilotest
|
|
153
|
+
tool name:
|
|
154
|
+
type: string
|
|
155
|
+
examples:
|
|
156
|
+
- getListOfAllAvailableReports
|
|
153
157
|
request:
|
|
154
158
|
type: object
|
|
155
159
|
properties:
|
|
@@ -158,6 +162,8 @@ components:
|
|
|
158
162
|
properties:
|
|
159
163
|
identifier:
|
|
160
164
|
type: string
|
|
165
|
+
examples:
|
|
166
|
+
- reportList
|
|
161
167
|
description:
|
|
162
168
|
type: string
|
|
163
169
|
method:
|
|
@@ -167,7 +173,7 @@ components:
|
|
|
167
173
|
- POST
|
|
168
174
|
payload:
|
|
169
175
|
type: object
|
|
170
|
-
description:
|
|
176
|
+
description: The request payload, if method type is POST, or otherwise omitted.
|
|
171
177
|
URLs:
|
|
172
178
|
type: object
|
|
173
179
|
properties:
|
|
@@ -197,6 +203,7 @@ components:
|
|
|
197
203
|
description: Unique identifier for this response instance.
|
|
198
204
|
date and time:
|
|
199
205
|
type: string
|
|
206
|
+
description: UTC date and time when the response was generated, in ISO 8601 format.
|
|
200
207
|
format: date-time
|
|
201
208
|
|
|
202
209
|
TestRecForm:
|
|
@@ -306,12 +313,44 @@ components:
|
|
|
306
313
|
$ref: '#/components/schemas/RuleEnginesSummary'
|
|
307
314
|
rule engines that reported issues:
|
|
308
315
|
$ref: '#/components/schemas/RuleEnginesSummary'
|
|
309
|
-
URLs for getting data
|
|
316
|
+
URLs for getting data about the reported issues:
|
|
310
317
|
$ref: '#/components/schemas/NextTierURLs'
|
|
311
318
|
URL for getting the full technical report as JSON:
|
|
312
319
|
type: string
|
|
313
320
|
format: uri
|
|
314
321
|
|
|
322
|
+
ReportListItem:
|
|
323
|
+
type: object
|
|
324
|
+
description: Summary data about a single available report.
|
|
325
|
+
properties:
|
|
326
|
+
identifier:
|
|
327
|
+
type: string
|
|
328
|
+
examples:
|
|
329
|
+
- 260504T1659-029
|
|
330
|
+
creation date and time:
|
|
331
|
+
type: string
|
|
332
|
+
format: date-time
|
|
333
|
+
days since the creation date:
|
|
334
|
+
type: integer
|
|
335
|
+
tested web page:
|
|
336
|
+
type: object
|
|
337
|
+
properties:
|
|
338
|
+
description:
|
|
339
|
+
type: string
|
|
340
|
+
URL:
|
|
341
|
+
type: string
|
|
342
|
+
format: uri
|
|
343
|
+
whether a later report about the same page exists:
|
|
344
|
+
type: boolean
|
|
345
|
+
description: If true, a more recent report about this page is available. If you want the latest results, use that report instead.
|
|
346
|
+
URLs for incrementally getting facts from the report:
|
|
347
|
+
$ref: '#/components/schemas/NextTierURLs'
|
|
348
|
+
size of the report in bytes:
|
|
349
|
+
type: integer
|
|
350
|
+
URL to get the entire report as machine-oriented JSON:
|
|
351
|
+
type: string
|
|
352
|
+
format: uri
|
|
353
|
+
|
|
315
354
|
Target:
|
|
316
355
|
type: object
|
|
317
356
|
properties:
|
|
@@ -322,7 +361,7 @@ components:
|
|
|
322
361
|
type: string
|
|
323
362
|
description: All or part of the hostname of the web page. The hostname omits the scheme and the path.
|
|
324
363
|
|
|
325
|
-
|
|
364
|
+
ReportListResponse:
|
|
326
365
|
allOf:
|
|
327
366
|
- $ref: '#/components/schemas/CommonResponseFields'
|
|
328
367
|
- type: object
|
|
@@ -330,6 +369,17 @@ components:
|
|
|
330
369
|
available reports:
|
|
331
370
|
type: array
|
|
332
371
|
description: One entry per available Kilotest report, in alphabetical order by page description and, in case of multiple reports per page, in order of creation date and time. Reports are matched by page description, not page URL, so, if only the URL of a page has changed between reports, the reports are treated as reports about the same page.
|
|
372
|
+
items:
|
|
373
|
+
$ref: '#/components/schemas/ReportListItem'
|
|
374
|
+
|
|
375
|
+
TargetsResponse:
|
|
376
|
+
allOf:
|
|
377
|
+
- $ref: '#/components/schemas/CommonResponseFields'
|
|
378
|
+
- type: object
|
|
379
|
+
properties:
|
|
380
|
+
matching reports:
|
|
381
|
+
type: array
|
|
382
|
+
description: One entry per available matching Kilotest report. A report is matching if its page description or hostname contains or is contained by a specified description or hostname fragment, respectively.
|
|
333
383
|
items:
|
|
334
384
|
$ref: '#/components/schemas/TargetsItem'
|
|
335
385
|
|
package/package.json
CHANGED
package/reportIssue/api.js
CHANGED
|
@@ -106,13 +106,13 @@ exports.response = async args => {
|
|
|
106
106
|
const thisHost = process.env.THIS_KILOTEST_HOST;
|
|
107
107
|
// Get a response.
|
|
108
108
|
const content = {
|
|
109
|
-
summary: `This document fulfills a request made by a language model to a Kilotest tool. The model requested data, drawn from a Kilotest report, about one of the issues for the front-end quality (i.e. accessibility, usability, and
|
|
109
|
+
summary: `This document fulfills a request made by a language model to a Kilotest tool. The model requested data, drawn from a Kilotest report, about one of the issues for the front-end quality (i.e. accessibility, usability, and standards conformity) of a web page. Kilotest, with the help of Testaro, Testilo, and an ensemble of ten rule engines, performs tests on web pages, using a combination of rule- and machine-learning-based methods, and produces reports. Kilotest exposes several API endpoints to recommend web pages for testing and to obtain information from Kilotest reports. To learn more about Kilotest and the advantages of testing with an ensemble of rule engines, visit the deployed instance of Kilotest (${process.env.DEPLOYED_KILOTEST_HOST}), which contains an introduction on its home page and a tutorial.`,
|
|
110
110
|
'tool collection name': 'Kilotest',
|
|
111
111
|
'tool name': 'describeOneIssueFromOneReport',
|
|
112
112
|
request: {
|
|
113
113
|
'type of request': {
|
|
114
114
|
identifier: 'reportIssue',
|
|
115
|
-
description: 'Describe one issue from one
|
|
115
|
+
description: 'Describe one issue from one report.'
|
|
116
116
|
},
|
|
117
117
|
method: 'GET',
|
|
118
118
|
URLs: {
|
|
@@ -123,8 +123,8 @@ exports.response = async args => {
|
|
|
123
123
|
identifier: 'describeQualityOfOneWebPage',
|
|
124
124
|
description: 'Describe the quality of one web page.',
|
|
125
125
|
URLs: {
|
|
126
|
-
'for you': `${thisHost}/api/reportIssues`,
|
|
127
|
-
'for humans': `${thisHost}/reportIssues.html`
|
|
126
|
+
'for you': `${thisHost}/api/reportIssues/${timeStamp}/${jobID}`,
|
|
127
|
+
'for humans': `${thisHost}/reportIssues.html/${timeStamp}/${jobID}`
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
},
|
package/reportIssues/api.js
CHANGED
|
@@ -63,7 +63,7 @@ exports.response = async args => {
|
|
|
63
63
|
const thisHost = process.env.THIS_KILOTEST_HOST;
|
|
64
64
|
// Get a response.
|
|
65
65
|
const content = {
|
|
66
|
-
summary: `This document fulfills a request made by a language model to a Kilotest tool. The model requested data from a Kilotest report about the front-end quality (i.e. accessibility, usability, and
|
|
66
|
+
summary: `This document fulfills a request made by a language model to a Kilotest tool. The model requested data from a Kilotest report about the front-end quality (i.e. accessibility, usability, and standards conformity) of a web page. Kilotest, with the help of Testaro, Testilo, and an ensemble of ten rule engines, performs tests on web pages, using a combination of rule- and machine-learning-based methods, and produces reports. Kilotest exposes several API endpoints to recommend web pages for testing and to obtain information from Kilotest reports. To learn more about Kilotest and the advantages of testing with an ensemble of rule engines, visit the deployed instance of Kilotest (${process.env.DEPLOYED_KILOTEST_HOST}), which contains an introduction on its home page and a tutorial.`,
|
|
67
67
|
'tool collection name': 'Kilotest',
|
|
68
68
|
'tool name': 'describeQualityOfOneWebPage',
|
|
69
69
|
request: {
|
|
@@ -77,10 +77,10 @@ exports.response = async args => {
|
|
|
77
77
|
'equivalent URL for humans': `${thisHost}/reportIssues.html/${timeStamp}/${jobID}`
|
|
78
78
|
},
|
|
79
79
|
'closest ancestor request': {
|
|
80
|
-
identifier: '
|
|
81
|
-
description: '
|
|
80
|
+
identifier: 'getListOfAllAvailableReports',
|
|
81
|
+
description: 'Get a list of all available reports.',
|
|
82
82
|
URLs: {
|
|
83
|
-
'for you': `${thisHost}/api/
|
|
83
|
+
'for you': `${thisHost}/api/reportList`,
|
|
84
84
|
'for humans': `${thisHost}/targets.html`
|
|
85
85
|
}
|
|
86
86
|
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/*
|
|
2
|
+
api.js
|
|
3
|
+
Responds to the reportList API request.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// IMPORTS
|
|
7
|
+
|
|
8
|
+
const {
|
|
9
|
+
getAgoDays,
|
|
10
|
+
getDateTime,
|
|
11
|
+
getLogs,
|
|
12
|
+
getNowStamp,
|
|
13
|
+
getRandomString,
|
|
14
|
+
getReportSize
|
|
15
|
+
} = require('../util');
|
|
16
|
+
|
|
17
|
+
// CONSTANTS
|
|
18
|
+
|
|
19
|
+
const thisHost = process.env.THIS_KILOTEST_HOST;
|
|
20
|
+
|
|
21
|
+
// FUNCTIONS
|
|
22
|
+
|
|
23
|
+
// Returns a response to an API request for reports.
|
|
24
|
+
exports.response = async () => {
|
|
25
|
+
const reportsFacts = [];
|
|
26
|
+
// Get the available logs, with added job names.
|
|
27
|
+
const availableLogs = await getLogs();
|
|
28
|
+
// For each of them:
|
|
29
|
+
for (const availableLog of availableLogs) {
|
|
30
|
+
const {jobName} = availableLog;
|
|
31
|
+
const [timeStamp, jobID] = jobName.split('-');
|
|
32
|
+
const reportSize = await getReportSize(timeStamp, jobID);
|
|
33
|
+
const {superseded, url, what} = availableLog;
|
|
34
|
+
reportsFacts.push({
|
|
35
|
+
identifier: jobName,
|
|
36
|
+
'creation date and time': getDateTime(timeStamp),
|
|
37
|
+
'days since the creation date': getAgoDays(timeStamp),
|
|
38
|
+
'tested web page': {
|
|
39
|
+
description: what,
|
|
40
|
+
URL: url
|
|
41
|
+
},
|
|
42
|
+
'whether a later report about the same page exists': !! superseded,
|
|
43
|
+
'URLs for incrementally getting facts from the report': {
|
|
44
|
+
'for you': `${thisHost}/api/reportIssues/${timeStamp}/${jobID}`,
|
|
45
|
+
'for humans': `${thisHost}/reportIssues.html/${timeStamp}/${jobID}`
|
|
46
|
+
},
|
|
47
|
+
'size of the report in bytes': reportSize,
|
|
48
|
+
'URL to get the entire report as machine-oriented JSON': `${thisHost}/fullReport.json/${timeStamp}/${jobID}`
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
// Get a response.
|
|
52
|
+
const content = {
|
|
53
|
+
summary: `This document fulfills a request made by a language model to a Kilotest tool. The model asked which reports about the front-end quality (i.e. accessibility, usability, and standards conformity) of web pages are available from Kilotest. Each report describes the results of a job that tested one web page. Kilotest, with the help of Testaro, Testilo, and an ensemble of ten rule engines, performs more than a thousand tests on a public web page, using a combination of rule- and machine-learning-based methods. Kilotest exposes API endpoints and web UI URLs to recommend web pages for testing and to obtain information from Kilotest reports. You and your users can learn more about Kilotest and the advantages of testing with an ensemble of rule engines at the deployed instance of Kilotest (${process.env.DEPLOYED_KILOTEST_HOST}).`,
|
|
54
|
+
'tool collection name': 'Kilotest',
|
|
55
|
+
'tool name': 'getListOfAllAvailableReports',
|
|
56
|
+
request: {
|
|
57
|
+
'type of request': {
|
|
58
|
+
identifier: 'reportList',
|
|
59
|
+
description: 'Get a list of all available reports. Each report describes the results of a job that tested a web page for front-end quality (i.e. accessibility, usability, and standards conformity). For each report, the list identifies which page was tested and when and provides URLs to begin incremental retrieval of the test results.'
|
|
60
|
+
},
|
|
61
|
+
method: 'GET',
|
|
62
|
+
URLs: {
|
|
63
|
+
'URL of your request': `${thisHost}/api/reportList`,
|
|
64
|
+
'equivalent URL for humans': `${thisHost}/targets.html`
|
|
65
|
+
},
|
|
66
|
+
'closest ancestor request': null
|
|
67
|
+
},
|
|
68
|
+
'response metadata': {
|
|
69
|
+
identifier: `${getNowStamp()}-${getRandomString(3)}`,
|
|
70
|
+
'date and time': new Date().toISOString(),
|
|
71
|
+
},
|
|
72
|
+
'available reports': reportsFacts
|
|
73
|
+
};
|
|
74
|
+
return content;
|
|
75
|
+
};
|
package/researchAgent.js
CHANGED
|
@@ -115,9 +115,9 @@ const requestService = async () => {
|
|
|
115
115
|
if (content.error) {
|
|
116
116
|
return;
|
|
117
117
|
}
|
|
118
|
-
console.log('======================\nRequest 2:
|
|
118
|
+
console.log('======================\nRequest 2: List all available reports');
|
|
119
119
|
method = 'GET';
|
|
120
|
-
path = '/api/
|
|
120
|
+
path = '/api/reportList';
|
|
121
121
|
content = await submitRequest(results, path, method);
|
|
122
122
|
reports = content?.['available reports'] ?? [];
|
|
123
123
|
if (content.error || ! Array.isArray(reports) || ! reports.length) {
|
package/target/api.js
CHANGED
|
@@ -78,7 +78,7 @@ exports.response = async args => {
|
|
|
78
78
|
'number of HTML elements reported as exhibiting issues': violatorCount,
|
|
79
79
|
'URLs for getting data about the reported issues': {
|
|
80
80
|
'for you': `${thisHost}/api/reportIssues/${timeStamp}/${jobID}`,
|
|
81
|
-
'for humans': `${thisHost}/reportIssues/${timeStamp}/${jobID}`
|
|
81
|
+
'for humans': `${thisHost}/reportIssues.html/${timeStamp}/${jobID}`
|
|
82
82
|
},
|
|
83
83
|
'URL for getting the full technical report as JSON': `${thisHost}/fullReport.json/${timeStamp}/${jobID}`
|
|
84
84
|
});
|
|
@@ -86,13 +86,13 @@ exports.response = async args => {
|
|
|
86
86
|
}
|
|
87
87
|
// Get a response.
|
|
88
88
|
const content = {
|
|
89
|
-
summary: `This document fulfills a request made by a language model to the Kilotest API. The model asked whether Kilotest had tested a specified web page for front-end quality (i.e. accessibility, usability, and standards conformity) and had made a report of the test results available. The response provides summary information about all and only the available reports of pages that match at least one of the provided fragments, where matching means either including or being included by the provided fragment, case-insensitively. Kilotest, with the help of Testaro, Testilo, and an ensemble of ten rule engines, performs tests on web pages, using a combination of rule- and machine-learning-based methods, and produces reports. Kilotest exposes API endpoints to recommend web pages for testing and to obtain information from Kilotest reports. To learn more about Kilotest and the
|
|
89
|
+
summary: `This document fulfills a request made by a language model to the Kilotest API. The model asked whether Kilotest had tested a specified web page for front-end quality (i.e. accessibility, usability, and standards conformity) and had made a report of the test results available. The response provides summary information about all and only the available reports of pages that match at least one of the provided fragments, where matching means either including or being included by the provided fragment, case-insensitively. Kilotest, with the help of Testaro, Testilo, and an ensemble of ten rule engines, performs tests on web pages, using a combination of rule- and machine-learning-based methods, and produces reports. Kilotest exposes API endpoints to recommend web pages for testing and to obtain information from Kilotest reports. To learn more about Kilotest and the advantages of testing with an ensemble of rule engines, visit the deployed instance of Kilotest (${process.env.DEPLOYED_KILOTEST_HOST}), whose home page contains an introduction and a link to a tutorial.`,
|
|
90
90
|
'tool collection name': 'Kilotest',
|
|
91
|
-
'tool name': '
|
|
91
|
+
'tool name': 'summarizeQualityOfMatchingWebPages',
|
|
92
92
|
request: {
|
|
93
93
|
'type of request': {
|
|
94
|
-
identifier: '
|
|
95
|
-
description: '
|
|
94
|
+
identifier: 'target',
|
|
95
|
+
description: 'Summarize the quality of matching web pages.'
|
|
96
96
|
},
|
|
97
97
|
method: 'POST',
|
|
98
98
|
payload: {
|
|
@@ -109,7 +109,7 @@ exports.response = async args => {
|
|
|
109
109
|
identifier: `${getNowStamp()}-${getRandomString(3)}`,
|
|
110
110
|
'date and time': new Date().toISOString(),
|
|
111
111
|
},
|
|
112
|
-
'reports
|
|
112
|
+
'matching reports': matchingReports
|
|
113
113
|
};
|
|
114
114
|
return content;
|
|
115
115
|
};
|
package/testRecForm/api.js
CHANGED
|
@@ -26,7 +26,7 @@ exports.response = async (what, url, why) => {
|
|
|
26
26
|
);
|
|
27
27
|
// Get a response.
|
|
28
28
|
const content = {
|
|
29
|
-
summary: `This response acknowledges a request made by a language model to a Kilotest tool. The model recommended that Kilotest test, for the first time, the ${what} web page at ${url} for front-end quality (i.e. accessibility, usability, and standards conformity). A Kilotest manager usually approves a recommendation within a day. When the recommendation is approved, the testing will be performed and results will become available. You can check for the availability of the results at ${thisHost}/api/
|
|
29
|
+
summary: `This response acknowledges a request made by a language model to a Kilotest tool. The model recommended that Kilotest test, for the first time, the ${what} web page at ${url} for front-end quality (i.e. accessibility, usability, and standards conformity). A Kilotest manager usually approves a recommendation within a day. When the recommendation is approved, the testing will be performed and results will become available. You can check for the availability of the results at ${thisHost}/api/reportList. Kilotest performs its testing with the help of Testaro, Testilo, and an ensemble of ten rule engines, using a combination of rule- and machine-learning-based methods. Kilotest exposes several API endpoints and several web UI URLs to obtain information from Kilotest reports. To learn more about Kilotest and the advantages of testing with an ensemble of rule engines, visit the deployed instance of Kilotest (${process.env.DEPLOYED_KILOTEST_HOST}), which contains an introduction on its home page and a tutorial.`,
|
|
30
30
|
'tool collection name': 'Kilotest',
|
|
31
31
|
'tool name': 'recommendQualityTestingOfOneWebPage',
|
|
32
32
|
request: {
|
package/tutorial/index.js
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
// IMPORTS
|
|
7
7
|
|
|
8
|
-
const {
|
|
8
|
+
const {sendAlert} = require('../alerts');
|
|
9
|
+
const {getJSON, getNowStamp} = require('../util');
|
|
9
10
|
const fs = require('fs/promises');
|
|
10
11
|
const path = require('path');
|
|
11
12
|
|
|
@@ -31,7 +32,7 @@ exports.answer = async () => {
|
|
|
31
32
|
};
|
|
32
33
|
};
|
|
33
34
|
// Sanitizes and saves a tutorial comment to comments.json.
|
|
34
|
-
exports.
|
|
35
|
+
exports.handleComment = async content => {
|
|
35
36
|
if (!content || typeof content !== 'string') {
|
|
36
37
|
return {status: 'error', message: 'No content provided'};
|
|
37
38
|
}
|
|
@@ -41,13 +42,22 @@ exports.saveComment = async content => {
|
|
|
41
42
|
}
|
|
42
43
|
let comments = [];
|
|
43
44
|
try {
|
|
45
|
+
// Get the existing comments.
|
|
44
46
|
const existing = await fs.readFile(commentsPath, 'utf8');
|
|
45
47
|
comments = JSON.parse(existing);
|
|
46
48
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
// If there are none:
|
|
50
|
+
catch {
|
|
51
|
+
// Initialize a comments array.
|
|
49
52
|
}
|
|
50
|
-
|
|
53
|
+
// Add the comment to the existing ones.
|
|
54
|
+
comments.push({
|
|
55
|
+
timeStamp: getNowStamp(),
|
|
56
|
+
content: sanitized
|
|
57
|
+
});
|
|
58
|
+
// Save the revised comments.
|
|
51
59
|
await fs.writeFile(commentsPath, getJSON(comments));
|
|
60
|
+
// Send an alert to the manager.
|
|
61
|
+
await sendAlert('New tutorial comment received', 'A new tutorial comment has been received.');
|
|
52
62
|
return {status: 'ok'};
|
|
53
63
|
};
|
package/util.js
CHANGED
|
@@ -489,7 +489,7 @@ exports.getPOSTData = request => new Promise(resolve => {
|
|
|
489
489
|
});
|
|
490
490
|
// Returns the waiting test and retest recommendations.
|
|
491
491
|
const getRecs = exports.getRecs = async () => {
|
|
492
|
-
let recs
|
|
492
|
+
let recs;
|
|
493
493
|
let recsJSON;
|
|
494
494
|
try {
|
|
495
495
|
recsJSON = await fs.readFile(recsPath, 'utf8');
|
|
@@ -764,3 +764,9 @@ exports.isReportAvailable = async (what, url) => {
|
|
|
764
764
|
const miniURLs = logs.map(log => minifyURL(log.url));
|
|
765
765
|
return whats.includes(what) || miniURLs.includes(minifyURL(url));
|
|
766
766
|
};
|
|
767
|
+
// Returns the size of a report.
|
|
768
|
+
exports.getReportSize = async (timeStamp, jobID) => {
|
|
769
|
+
const reportStat = await fs.stat(path.join(reportsPath, `${timeStamp}-${jobID}.json`));
|
|
770
|
+
const reportSize = reportStat.size;
|
|
771
|
+
return reportSize;
|
|
772
|
+
};
|
package/targets/api.js
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
api.js
|
|
3
|
-
Responds to the targets request.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
// IMPORTS
|
|
7
|
-
|
|
8
|
-
const {
|
|
9
|
-
getLogs,
|
|
10
|
-
getNowStamp,
|
|
11
|
-
getRandomString,
|
|
12
|
-
getReportData
|
|
13
|
-
} = require('../util');
|
|
14
|
-
|
|
15
|
-
// CONSTANTS
|
|
16
|
-
|
|
17
|
-
const thisHost = process.env.THIS_KILOTEST_HOST;
|
|
18
|
-
|
|
19
|
-
// FUNCTIONS
|
|
20
|
-
|
|
21
|
-
// Returns a response to a targets request.
|
|
22
|
-
exports.response = async () => {
|
|
23
|
-
const availableReports = [];
|
|
24
|
-
// Get the non-hidden logs.
|
|
25
|
-
const targetLogs = await getLogs();
|
|
26
|
-
// For each log:
|
|
27
|
-
for (const targetLog of targetLogs) {
|
|
28
|
-
const {jobName} = targetLog;
|
|
29
|
-
const [timeStamp, jobID] = jobName.split('-');
|
|
30
|
-
const {superseded, url, what} = targetLog;
|
|
31
|
-
// Get data about its report.
|
|
32
|
-
const data = await getReportData(timeStamp, jobID);
|
|
33
|
-
const {
|
|
34
|
-
creationDate,
|
|
35
|
-
daysAgo,
|
|
36
|
-
issueCount,
|
|
37
|
-
toolNames,
|
|
38
|
-
toolCount,
|
|
39
|
-
reporterNames,
|
|
40
|
-
reporterCount,
|
|
41
|
-
violatorCount,
|
|
42
|
-
preventedToolNames,
|
|
43
|
-
preventedToolCount
|
|
44
|
-
} = data;
|
|
45
|
-
availableReports.push({
|
|
46
|
-
identifier: jobName,
|
|
47
|
-
'creation date': creationDate,
|
|
48
|
-
'days since the creation date': daysAgo,
|
|
49
|
-
'tested web page': {
|
|
50
|
-
description: what,
|
|
51
|
-
URL: url
|
|
52
|
-
},
|
|
53
|
-
'whether a later report about the same page exists': !! superseded,
|
|
54
|
-
'rule engines that tried to test the page': {
|
|
55
|
-
number: toolCount,
|
|
56
|
-
names: toolNames
|
|
57
|
-
},
|
|
58
|
-
'rule engines that were unable to test the page': {
|
|
59
|
-
number: preventedToolCount,
|
|
60
|
-
names: preventedToolNames
|
|
61
|
-
},
|
|
62
|
-
'rule engines that reported issues': {
|
|
63
|
-
number: reporterCount,
|
|
64
|
-
names: reporterNames
|
|
65
|
-
},
|
|
66
|
-
'number of issues reported': issueCount,
|
|
67
|
-
'number of HTML elements reported as exhibiting issues': violatorCount,
|
|
68
|
-
'URLs for getting data about the reported issues': {
|
|
69
|
-
'for you': `${thisHost}/api/reportIssues/${timeStamp}/${jobID}`,
|
|
70
|
-
'for humans': `${thisHost}/reportIssues/${timeStamp}/${jobID}`
|
|
71
|
-
},
|
|
72
|
-
'URL for getting the full technical report as JSON': `${thisHost}/fullReport.json/${timeStamp}/${jobID}`
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
// Get a response.
|
|
76
|
-
const content = {
|
|
77
|
-
summary: `This document fulfills a request made by a language model to a Kilotest tool. The model requested data about the web pages that Kilotest had tested for front-end quality (i.e. accessibility, usability, and standards conformity) and, for each page, statistics about the results of the tests. Kilotest, with the help of Testaro, Testilo, and an ensemble of ten rule engines, performs tests on web pages, using a combination of rule- and machine-learning-based methods, and produces reports. Kilotest exposes API endpoints and web UI URLs to recommend web pages for testing and to obtain information from Kilotest reports. To learn more about Kilotest and the advangages of testing with an ensemble of rule engines, visit the deployed instance of Kilotest (${process.env.DEPLOYED_KILOTEST_HOST}), whose home page contains an introduction and a link to a tutorial.`,
|
|
78
|
-
'tool collection name': 'Kilotest',
|
|
79
|
-
'tool name': 'summarizeQualityOfAllTestedWebPages',
|
|
80
|
-
request: {
|
|
81
|
-
'type of request': {
|
|
82
|
-
identifier: 'targets',
|
|
83
|
-
description: 'Summarize the quality of all tested web pages.'
|
|
84
|
-
},
|
|
85
|
-
method: 'GET',
|
|
86
|
-
URLs: {
|
|
87
|
-
'URL of your request': `${thisHost}/api/targets`,
|
|
88
|
-
'equivalent URL for humans': `${thisHost}/targets.html`
|
|
89
|
-
},
|
|
90
|
-
'closest ancestor request': null
|
|
91
|
-
},
|
|
92
|
-
'response metadata': {
|
|
93
|
-
identifier: `${getNowStamp()}-${getRandomString(3)}`,
|
|
94
|
-
'date and time': new Date().toISOString(),
|
|
95
|
-
},
|
|
96
|
-
'available reports': availableReports
|
|
97
|
-
};
|
|
98
|
-
return content;
|
|
99
|
-
};
|
|
File without changes
|
|
File without changes
|