@jrpool/kilotest 61.0.0 → 62.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.devin/config.local.json +2 -1
- package/.markdownlint-cli2.jsonc +0 -1
- package/api/listDiagnoses.ts +13 -3
- package/api/listIssues.ts +8 -4
- package/api/listViolators.ts +5 -3
- package/api/reportDisagreement.test.ts +208 -0
- package/api/reportDisagreement.ts +208 -0
- package/api/routes.test.ts +3 -2
- package/api/routes.ts +20 -1
- package/api/schemas.ts +44 -2
- package/apiIntegration.test.ts +22 -0
- package/docs/SERVICE.md +6 -3
- package/env.example +5 -0
- package/index.ts +14 -1
- package/lhm.plugin.json +337 -7
- package/llms-full.txt +13 -0
- package/llms.txt +1 -0
- package/mcp.test.ts +23 -4
- package/mcp.ts +24 -1
- package/openapi-3.0.yaml +187 -5
- package/openapi.yaml +183 -5
- package/package.json +1 -1
- package/server.json +1 -1
package/api/schemas.ts
CHANGED
|
@@ -73,6 +73,16 @@ export const awaitTestSchema = {
|
|
|
73
73
|
reportID: z.string().describe('Report identifier returned by orderNewTest or orderRetest (example: 260503T0432-x9z)')
|
|
74
74
|
};
|
|
75
75
|
|
|
76
|
+
// reportDisagreement: POST /api/reportDisagreement/{issueID}/{reportID}/{catalogIndex}
|
|
77
|
+
export const reportDisagreementSchema = {
|
|
78
|
+
issueID: z.string().describe('Issue identifier (example: contrastPoor)'),
|
|
79
|
+
reportID: z.string().describe('Identifier of the report (example: 260503T0432-x9z)'),
|
|
80
|
+
catalogIndex: z.string().describe('Identifier of the issue-exhibiting element in the catalog of elements on the page (example: 372)'),
|
|
81
|
+
engineID: z.string().describe('Identifier of the rule engine that produced the disputed diagnosis (example: axe), as shown in the listDiagnoses output'),
|
|
82
|
+
ruleID: z.string().describe('Identifier of the rule whose diagnosis is disputed, as shown in the listDiagnoses output (example: color-contrast); if that output shows null for the rule identifier, use its description of the violation instead'),
|
|
83
|
+
reason: z.string().describe('20- to 1000-character explanation of why the diagnosis is disputed')
|
|
84
|
+
};
|
|
85
|
+
|
|
76
86
|
// listPages takes no input; omitted (mcp.ts already uses inputSchema: {}).
|
|
77
87
|
|
|
78
88
|
// RESPONSE SCHEMAS
|
|
@@ -278,7 +288,7 @@ export const listViolatorsResponseSchema = envelope('GET', z.object({
|
|
|
278
288
|
'tag name': z.unknown().describe('Copied from the report catalog entry; type not guaranteed.'),
|
|
279
289
|
'inner text': z.unknown().describe('Copied from the report catalog entry; type not guaranteed.'),
|
|
280
290
|
'count of rule engines reporting that the element exhibited the issue': z.number(),
|
|
281
|
-
'how to get details about the element': z.object({
|
|
291
|
+
'how to get details about the element': z.object({method: z.literal('GET'), URL: z.string()}),
|
|
282
292
|
'web users can get details about the element at': z.string()
|
|
283
293
|
})).nullable()
|
|
284
294
|
}));
|
|
@@ -297,10 +307,20 @@ export const listDiagnosesResponseSchema = envelope('GET', z.object({
|
|
|
297
307
|
'x, y, width, and height of bounding box': z.unknown().describe('Copied from the report catalog entry; type not guaranteed.')
|
|
298
308
|
}).nullable(),
|
|
299
309
|
'diagnoses of how the element exhibited the issue': z.array(z.object({
|
|
310
|
+
'identifier of the rule engine': z.unknown().describe('Copied from the report act (which); type not guaranteed.'),
|
|
300
311
|
'identifier of the violated rule': z.unknown().describe('Copied from the report instance (ruleID); type not guaranteed.'),
|
|
301
312
|
'description of the violation': z.unknown().describe('Copied from the report instance (what); type not guaranteed.'),
|
|
302
313
|
'severity of the violation on a 0-to-3 scale': z.unknown().describe('Copied from the report instance (ordinalSeverity); type not guaranteed.'),
|
|
303
|
-
'count of violations of the rule by the element': z.number()
|
|
314
|
+
'count of violations of the rule by the element': z.number(),
|
|
315
|
+
'how to report that you disagree with this diagnosis': z.object({
|
|
316
|
+
method: z.literal('POST'),
|
|
317
|
+
URL: z.string(),
|
|
318
|
+
'request body': z.object({
|
|
319
|
+
engineID: z.string(),
|
|
320
|
+
ruleID: z.string(),
|
|
321
|
+
reason: z.string()
|
|
322
|
+
})
|
|
323
|
+
})
|
|
304
324
|
})).or(z.object({error: z.string()})).nullable()
|
|
305
325
|
}));
|
|
306
326
|
|
|
@@ -362,6 +382,28 @@ export const requestFeatureResponseSchema = envelope(
|
|
|
362
382
|
z.null()
|
|
363
383
|
);
|
|
364
384
|
|
|
385
|
+
export const reportDisagreementResponseSchema = envelope(
|
|
386
|
+
'POST',
|
|
387
|
+
z.object({'details about your request': z.union([
|
|
388
|
+
z.object({error: z.string()}),
|
|
389
|
+
z.object({
|
|
390
|
+
'date and time received': z.string(),
|
|
391
|
+
'diagnosis you disagree with': z.object({
|
|
392
|
+
'issue identifier': z.string(),
|
|
393
|
+
'identifier of the rule engine': z.string(),
|
|
394
|
+
'identifier of the violated rule': z.string()
|
|
395
|
+
}),
|
|
396
|
+
disposition: z.string()
|
|
397
|
+
})
|
|
398
|
+
])}),
|
|
399
|
+
z.object({
|
|
400
|
+
engineID: reportDisagreementSchema.engineID,
|
|
401
|
+
ruleID: reportDisagreementSchema.ruleID,
|
|
402
|
+
reason: reportDisagreementSchema.reason
|
|
403
|
+
}),
|
|
404
|
+
z.null()
|
|
405
|
+
);
|
|
406
|
+
|
|
365
407
|
// Identifies the report a successfully ordered or awaited job will produce, once complete.
|
|
366
408
|
const reportIdentifierSchema = z.string().describe('Identifier of the report, to pass to listIssues once the report is ready (example: 260503T0432-x9z).');
|
|
367
409
|
|
package/apiIntegration.test.ts
CHANGED
|
@@ -16,11 +16,13 @@ import {requestHandler} from './index.ts';
|
|
|
16
16
|
|
|
17
17
|
const port = 3998;
|
|
18
18
|
const featureRequestsPath = path.join(import.meta.dirname, 'test/fixtures/apiIntegration/featureRequests.json');
|
|
19
|
+
const disagreementsPath = path.join(import.meta.dirname, 'test/fixtures/apiIntegration/disagreements.json');
|
|
19
20
|
|
|
20
21
|
// SETUP AND TEARDOWN
|
|
21
22
|
|
|
22
23
|
const savedDBDir = process.env.DB_DIR;
|
|
23
24
|
const savedFeatureRequestsPath = process.env.FEATURE_REQUESTS_PATH;
|
|
25
|
+
const savedDisagreementsPath = process.env.DISAGREEMENTS_PATH;
|
|
24
26
|
let server: http.Server;
|
|
25
27
|
|
|
26
28
|
before(async () => {
|
|
@@ -31,6 +33,9 @@ before(async () => {
|
|
|
31
33
|
process.env.FEATURE_REQUESTS_PATH = featureRequestsPath;
|
|
32
34
|
await fs.mkdir(path.dirname(featureRequestsPath), {recursive: true});
|
|
33
35
|
await fs.writeFile(featureRequestsPath, '[]\n');
|
|
36
|
+
// The same for diagnosis disagreements.
|
|
37
|
+
process.env.DISAGREEMENTS_PATH = disagreementsPath;
|
|
38
|
+
await fs.writeFile(disagreementsPath, '[]\n');
|
|
34
39
|
server = http.createServer(requestHandler);
|
|
35
40
|
await new Promise<void>(resolve => server.listen(port, () => resolve()));
|
|
36
41
|
});
|
|
@@ -48,6 +53,12 @@ after(async () => {
|
|
|
48
53
|
else {
|
|
49
54
|
delete process.env.FEATURE_REQUESTS_PATH;
|
|
50
55
|
}
|
|
56
|
+
if (savedDisagreementsPath !== undefined) {
|
|
57
|
+
process.env.DISAGREEMENTS_PATH = savedDisagreementsPath;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
delete process.env.DISAGREEMENTS_PATH;
|
|
61
|
+
}
|
|
51
62
|
await fs.rm(path.dirname(featureRequestsPath), {recursive: true, force: true});
|
|
52
63
|
server.closeAllConnections?.();
|
|
53
64
|
await new Promise<void>(resolve => {
|
|
@@ -106,3 +117,14 @@ test('POST /api/requestFeature parses a JSON body and returns a JSON response th
|
|
|
106
117
|
assert.equal(details.error, undefined);
|
|
107
118
|
assert.equal(details.disposition, 'received and logged; manager notified');
|
|
108
119
|
});
|
|
120
|
+
|
|
121
|
+
test('POST /api/reportDisagreement parses path parameters and a JSON body and returns a JSON response through the HTTP routing layer', async () => {
|
|
122
|
+
const {body} = await request('POST', '/api/reportDisagreement/linkNoText/260101T0000-mix/0', {
|
|
123
|
+
engineID: 'axe',
|
|
124
|
+
ruleID: 'r11',
|
|
125
|
+
reason: 'The element does have an accessible name'
|
|
126
|
+
});
|
|
127
|
+
const details = body['response content']['details about your request'];
|
|
128
|
+
assert.equal(details.error, undefined);
|
|
129
|
+
assert.equal(details.disposition, 'received and logged; manager notified');
|
|
130
|
+
});
|
package/docs/SERVICE.md
CHANGED
|
@@ -409,9 +409,11 @@ Alerts are sent to the maintainer in the following conditions:
|
|
|
409
409
|
|
|
410
410
|
7. **MCP feature request received**: When a user submits a feature request via the MCP server's `requestFeature` tool, an alert is sent with subject `"MCP feature request received"`, including the text of the feature request, and the request is also appended to `db/featureRequests.json`, the same way tutorial comments are appended to their own files (see item 1), so that a manager can review or delete it later via `/deleteNotesForm.html`.
|
|
411
411
|
|
|
412
|
-
8. **
|
|
412
|
+
8. **Diagnosis disagreement received**: When a user reports disagreement with a diagnosis via the API’s or MCP server’s `reportDisagreement` operation, an alert is sent with subject `"Kilotest: diagnosis disagreement received"`, including the reason, the disputed diagnosis (rule engine, rule, issue, element, and report), and the disagreement is also appended to `db/disagreements.json`, so that a manager can review it and, when warranted, propose a correction to the `testaro-issues` classification (see item 3 for how such corrections take effect).
|
|
413
413
|
|
|
414
|
-
9. **
|
|
414
|
+
9. **WAVE balance low**: When Kilotest detects that the account balance for the WAVE API service (used for accessibility testing) has fallen below a threshold, an alert is sent with subject `"Kilotest: WAVE balance low"`, indicating the number of credits remaining.
|
|
415
|
+
|
|
416
|
+
10. **AI service balance low**: When Kilotest detects that the account balance for an AI service account (such as Anthropic) has fallen below a threshold, an alert is sent with subject `"Kilotest: AI service [N] balance low"`, indicating the approximate remaining balance in dollars and the estimated cost per job.
|
|
415
417
|
|
|
416
418
|
### Alert configuration
|
|
417
419
|
|
|
@@ -427,7 +429,7 @@ If any of these five variables is missing or empty at alert time, the alert is n
|
|
|
427
429
|
|
|
428
430
|
### Inbox size limits
|
|
429
431
|
|
|
430
|
-
|
|
432
|
+
Five submission types (test requests and retest requests together, web tutorial comments, AI tutorial comments, MCP feature requests, and diagnosis disagreements) are each held in a pending "inbox" (`db/jobs/testRequests.json`, `db/comments/tutorialWeb.json`, `db/comments/tutorialAI.json`, `db/featureRequests.json`, and `db/disagreements.json` respectively) awaiting manual review by the maintainer. Each inbox has a maximum size; once reached, a new, distinct submission is rejected (with a message suggesting the requester instead post to the [GitHub issues page](https://github.com/jrpool/kilotest/issues) or email `info@kilotest.com`) rather than added, so neither the inbox file nor the manager alert emails it generates can grow without bound (see GitHub issue #3, abuse type 3, repeated/automated submissions). This is modeled on a full mailbox rejecting new mail, rather than on a submission rate limit: it is the backlog size itself, not how quickly it grows, that costs the maintainer review time and risks unbounded storage. Every alert sent for an accepted submission reports the resulting inbox count against its cap, so a maintainer returning after an absence can immediately see how close an inbox is to full.
|
|
431
433
|
|
|
432
434
|
Each cap defaults to 20 and can be set independently via an environment variable:
|
|
433
435
|
|
|
@@ -435,6 +437,7 @@ Each cap defaults to 20 and can be set independently via an environment variable
|
|
|
435
437
|
2. **`TUTORIAL_WEB_COMMENTS_MAX`**: The maximum number of comments held on the web tutorial page (`/tutorialWeb.html`).
|
|
436
438
|
3. **`TUTORIAL_AI_COMMENTS_MAX`**: The maximum number of comments held on the AI agent tutorial page (`/tutorialAI.html`).
|
|
437
439
|
4. **`FEATURE_REQUESTS_MAX`**: The maximum number of feature requests held via the MCP server's `requestFeature` tool.
|
|
440
|
+
5. **`DISAGREEMENTS_MAX`**: The maximum number of disagreements with diagnoses held via the API’s or MCP server’s `reportDisagreement` operation.
|
|
438
441
|
|
|
439
442
|
Each variable, if set, must be a non-negative integer; if unset, empty, or not a non-negative integer, the default of 20 is used instead. A value of `0` means no limit: that inbox is never treated as full, regardless of size. Unlike the alert-configuration variables above, these are not required: an unset value never disables the limit, it only selects the default size.
|
|
440
443
|
|
package/env.example
CHANGED
|
@@ -35,6 +35,8 @@ TUTORIAL_WEB_COMMENTS_PATH=__placeholder__
|
|
|
35
35
|
TUTORIAL_AI_COMMENTS_PATH=__placeholder__
|
|
36
36
|
# Path of the feature requests file (defaults to db/featureRequests.json).
|
|
37
37
|
FEATURE_REQUESTS_PATH=__placeholder__
|
|
38
|
+
# Path of the diagnosis disagreements file (defaults to db/disagreements.json).
|
|
39
|
+
DISAGREEMENTS_PATH=__placeholder__
|
|
38
40
|
|
|
39
41
|
# Inbox size limits: each defaults to 20 if unset, empty, or not a non-negative integer.
|
|
40
42
|
# A value of 0 means no limit.
|
|
@@ -47,6 +49,9 @@ TUTORIAL_WEB_COMMENTS_MAX=__placeholder__
|
|
|
47
49
|
TUTORIAL_AI_COMMENTS_MAX=__placeholder__
|
|
48
50
|
# Maximum number of feature requests held via the MCP server's requestFeature tool.
|
|
49
51
|
FEATURE_REQUESTS_MAX=__placeholder__
|
|
52
|
+
# Maximum number of disagreements with diagnoses held via the MCP server's
|
|
53
|
+
# reportDisagreement tool.
|
|
54
|
+
DISAGREEMENTS_MAX=__placeholder__
|
|
50
55
|
# Maximum number of jobs allowed in the job queue (db/jobs/queue) at once. Shared by every
|
|
51
56
|
# path that enqueues a job: manager approval of a pending test/retest request, and the
|
|
52
57
|
# orderNewTest/orderRetest MCP tools, which enqueue directly.
|
package/index.ts
CHANGED
|
@@ -88,6 +88,7 @@ import {response as requestNewTestAPI} from './api/requestNewTest.ts';
|
|
|
88
88
|
import {response as orderNewTestAPI} from './api/orderNewTest.ts';
|
|
89
89
|
import {response as orderRetestAPI} from './api/orderRetest.ts';
|
|
90
90
|
import {response as awaitTestAPI} from './api/awaitTest.ts';
|
|
91
|
+
import {response as reportDisagreementAPI} from './api/reportDisagreement.ts';
|
|
91
92
|
|
|
92
93
|
// ENVIRONMENT
|
|
93
94
|
|
|
@@ -190,6 +191,7 @@ const apiRespond: {
|
|
|
190
191
|
orderNewTest: ApiResponder;
|
|
191
192
|
orderRetest: ApiResponder;
|
|
192
193
|
awaitTest: ApiResponder;
|
|
194
|
+
reportDisagreement: ApiResponder;
|
|
193
195
|
} = {
|
|
194
196
|
getReport: getReportAPI,
|
|
195
197
|
listDiagnoses: listDiagnosesAPI,
|
|
@@ -201,7 +203,8 @@ const apiRespond: {
|
|
|
201
203
|
requestNewTest: requestNewTestAPI,
|
|
202
204
|
orderNewTest: orderNewTestAPI,
|
|
203
205
|
orderRetest: orderRetestAPI,
|
|
204
|
-
awaitTest: awaitTestAPI
|
|
206
|
+
awaitTest: awaitTestAPI,
|
|
207
|
+
reportDisagreement: reportDisagreementAPI
|
|
205
208
|
};
|
|
206
209
|
|
|
207
210
|
// CONSTANTS
|
|
@@ -1396,6 +1399,16 @@ const handleRequest = async (request: IncomingMessage, response: ServerResponse)
|
|
|
1396
1399
|
setHeaders('application/json', null, 'ultra');
|
|
1397
1400
|
response.end(JSON.stringify(responseBody));
|
|
1398
1401
|
}
|
|
1402
|
+
// Otherwise, if the service is to receive a disagreement with a diagnosis:
|
|
1403
|
+
else if (segments[0] === 'reportDisagreement') {
|
|
1404
|
+
const {engineID, ruleID, reason} = postData as {engineID: string; ruleID: string; reason: string};
|
|
1405
|
+
// Get the response body.
|
|
1406
|
+
const responseBody = await apiRespond.reportDisagreement(segments.slice(1).concat(engineID, ruleID, reason));
|
|
1407
|
+
await recordPageMetric('apiOperations', 'reportDisagreement');
|
|
1408
|
+
// Send it.
|
|
1409
|
+
setHeaders('application/json', null, 'ultra');
|
|
1410
|
+
response.end(JSON.stringify(responseBody));
|
|
1411
|
+
}
|
|
1399
1412
|
// Otherwise, if the service is to order an immediate, automatically approved test:
|
|
1400
1413
|
else if (segments[0] === 'orderNewTest') {
|
|
1401
1414
|
const {description, URL, reason} = postData as {description: string; URL: string; reason: string};
|
package/lhm.plugin.json
CHANGED
|
@@ -1241,17 +1241,17 @@
|
|
|
1241
1241
|
"how to get details about the element": {
|
|
1242
1242
|
"type": "object",
|
|
1243
1243
|
"properties": {
|
|
1244
|
-
"
|
|
1245
|
-
"type": "string"
|
|
1246
|
-
},
|
|
1247
|
-
"request method": {
|
|
1244
|
+
"method": {
|
|
1248
1245
|
"type": "string",
|
|
1249
1246
|
"const": "GET"
|
|
1247
|
+
},
|
|
1248
|
+
"URL": {
|
|
1249
|
+
"type": "string"
|
|
1250
1250
|
}
|
|
1251
1251
|
},
|
|
1252
1252
|
"required": [
|
|
1253
|
-
"
|
|
1254
|
-
"
|
|
1253
|
+
"method",
|
|
1254
|
+
"URL"
|
|
1255
1255
|
],
|
|
1256
1256
|
"additionalProperties": false
|
|
1257
1257
|
},
|
|
@@ -3371,6 +3371,336 @@
|
|
|
3371
3371
|
"taskSupport": "forbidden"
|
|
3372
3372
|
}
|
|
3373
3373
|
},
|
|
3374
|
+
{
|
|
3375
|
+
"name": "reportDisagreement",
|
|
3376
|
+
"description": "Reports that you disagree with a diagnosis shown by the listDiagnoses tool; queued for manager review. Use this after listDiagnoses when you believe a rule violation was incorrectly diagnosed or classified into an issue, providing the engineID and ruleID shown in the diagnosis and your reason. Returns a confirmation with disposition details.",
|
|
3377
|
+
"inputSchema": {
|
|
3378
|
+
"type": "object",
|
|
3379
|
+
"properties": {
|
|
3380
|
+
"issueID": {
|
|
3381
|
+
"type": "string",
|
|
3382
|
+
"description": "Issue identifier (example: contrastPoor)"
|
|
3383
|
+
},
|
|
3384
|
+
"reportID": {
|
|
3385
|
+
"type": "string",
|
|
3386
|
+
"description": "Identifier of the report (example: 260503T0432-x9z)"
|
|
3387
|
+
},
|
|
3388
|
+
"catalogIndex": {
|
|
3389
|
+
"type": "string",
|
|
3390
|
+
"description": "Identifier of the issue-exhibiting element in the catalog of elements on the page (example: 372)"
|
|
3391
|
+
},
|
|
3392
|
+
"engineID": {
|
|
3393
|
+
"type": "string",
|
|
3394
|
+
"description": "Identifier of the rule engine that produced the disputed diagnosis (example: axe), as shown in the listDiagnoses output"
|
|
3395
|
+
},
|
|
3396
|
+
"ruleID": {
|
|
3397
|
+
"type": "string",
|
|
3398
|
+
"description": "Identifier of the rule whose diagnosis is disputed, as shown in the listDiagnoses output (example: color-contrast); if that output shows null for the rule identifier, use its description of the violation instead"
|
|
3399
|
+
},
|
|
3400
|
+
"reason": {
|
|
3401
|
+
"type": "string",
|
|
3402
|
+
"description": "20- to 1000-character explanation of why the diagnosis is disputed"
|
|
3403
|
+
}
|
|
3404
|
+
},
|
|
3405
|
+
"required": [
|
|
3406
|
+
"issueID",
|
|
3407
|
+
"reportID",
|
|
3408
|
+
"catalogIndex",
|
|
3409
|
+
"engineID",
|
|
3410
|
+
"ruleID",
|
|
3411
|
+
"reason"
|
|
3412
|
+
],
|
|
3413
|
+
"$schema": "http://json-schema.org/draft-07/schema#"
|
|
3414
|
+
},
|
|
3415
|
+
"outputSchema": {
|
|
3416
|
+
"type": "object",
|
|
3417
|
+
"properties": {
|
|
3418
|
+
"tool collection": {
|
|
3419
|
+
"$ref": "#/definitions/ToolsFacts"
|
|
3420
|
+
},
|
|
3421
|
+
"tool name": {
|
|
3422
|
+
"type": "string"
|
|
3423
|
+
},
|
|
3424
|
+
"this request": {
|
|
3425
|
+
"type": "object",
|
|
3426
|
+
"properties": {
|
|
3427
|
+
"description": {
|
|
3428
|
+
"type": "string"
|
|
3429
|
+
},
|
|
3430
|
+
"method": {
|
|
3431
|
+
"type": "string",
|
|
3432
|
+
"const": "POST"
|
|
3433
|
+
},
|
|
3434
|
+
"URL": {
|
|
3435
|
+
"type": "string"
|
|
3436
|
+
},
|
|
3437
|
+
"body": {
|
|
3438
|
+
"type": "object",
|
|
3439
|
+
"properties": {
|
|
3440
|
+
"engineID": {
|
|
3441
|
+
"type": "string",
|
|
3442
|
+
"description": "Identifier of the rule engine that produced the disputed diagnosis (example: axe), as shown in the listDiagnoses output"
|
|
3443
|
+
},
|
|
3444
|
+
"ruleID": {
|
|
3445
|
+
"type": "string",
|
|
3446
|
+
"description": "Identifier of the rule whose diagnosis is disputed, as shown in the listDiagnoses output (example: color-contrast); if that output shows null for the rule identifier, use its description of the violation instead"
|
|
3447
|
+
},
|
|
3448
|
+
"reason": {
|
|
3449
|
+
"type": "string",
|
|
3450
|
+
"description": "20- to 1000-character explanation of why the diagnosis is disputed"
|
|
3451
|
+
}
|
|
3452
|
+
},
|
|
3453
|
+
"required": [
|
|
3454
|
+
"engineID",
|
|
3455
|
+
"ruleID",
|
|
3456
|
+
"reason"
|
|
3457
|
+
],
|
|
3458
|
+
"additionalProperties": false
|
|
3459
|
+
},
|
|
3460
|
+
"closest ancestor request": {
|
|
3461
|
+
"anyOf": [
|
|
3462
|
+
{
|
|
3463
|
+
"$ref": "#/definitions/RequestReference"
|
|
3464
|
+
},
|
|
3465
|
+
{
|
|
3466
|
+
"type": "null"
|
|
3467
|
+
}
|
|
3468
|
+
]
|
|
3469
|
+
}
|
|
3470
|
+
},
|
|
3471
|
+
"required": [
|
|
3472
|
+
"description",
|
|
3473
|
+
"method",
|
|
3474
|
+
"URL",
|
|
3475
|
+
"body",
|
|
3476
|
+
"closest ancestor request"
|
|
3477
|
+
],
|
|
3478
|
+
"additionalProperties": false
|
|
3479
|
+
},
|
|
3480
|
+
"URLs of similar requests for web users": {
|
|
3481
|
+
"type": "null"
|
|
3482
|
+
},
|
|
3483
|
+
"response metadata": {
|
|
3484
|
+
"$ref": "#/definitions/ResponseMetadata"
|
|
3485
|
+
},
|
|
3486
|
+
"response content": {
|
|
3487
|
+
"type": "object",
|
|
3488
|
+
"properties": {
|
|
3489
|
+
"details about your request": {
|
|
3490
|
+
"anyOf": [
|
|
3491
|
+
{
|
|
3492
|
+
"type": "object",
|
|
3493
|
+
"properties": {
|
|
3494
|
+
"error": {
|
|
3495
|
+
"type": "string"
|
|
3496
|
+
}
|
|
3497
|
+
},
|
|
3498
|
+
"required": [
|
|
3499
|
+
"error"
|
|
3500
|
+
],
|
|
3501
|
+
"additionalProperties": false
|
|
3502
|
+
},
|
|
3503
|
+
{
|
|
3504
|
+
"type": "object",
|
|
3505
|
+
"properties": {
|
|
3506
|
+
"date and time received": {
|
|
3507
|
+
"type": "string"
|
|
3508
|
+
},
|
|
3509
|
+
"diagnosis you disagree with": {
|
|
3510
|
+
"type": "object",
|
|
3511
|
+
"properties": {
|
|
3512
|
+
"issue identifier": {
|
|
3513
|
+
"type": "string"
|
|
3514
|
+
},
|
|
3515
|
+
"identifier of the rule engine": {
|
|
3516
|
+
"type": "string"
|
|
3517
|
+
},
|
|
3518
|
+
"identifier of the violated rule": {
|
|
3519
|
+
"type": "string"
|
|
3520
|
+
}
|
|
3521
|
+
},
|
|
3522
|
+
"required": [
|
|
3523
|
+
"issue identifier",
|
|
3524
|
+
"identifier of the rule engine",
|
|
3525
|
+
"identifier of the violated rule"
|
|
3526
|
+
],
|
|
3527
|
+
"additionalProperties": false
|
|
3528
|
+
},
|
|
3529
|
+
"disposition": {
|
|
3530
|
+
"type": "string"
|
|
3531
|
+
}
|
|
3532
|
+
},
|
|
3533
|
+
"required": [
|
|
3534
|
+
"date and time received",
|
|
3535
|
+
"diagnosis you disagree with",
|
|
3536
|
+
"disposition"
|
|
3537
|
+
],
|
|
3538
|
+
"additionalProperties": false
|
|
3539
|
+
}
|
|
3540
|
+
]
|
|
3541
|
+
}
|
|
3542
|
+
},
|
|
3543
|
+
"required": [
|
|
3544
|
+
"details about your request"
|
|
3545
|
+
],
|
|
3546
|
+
"additionalProperties": false
|
|
3547
|
+
}
|
|
3548
|
+
},
|
|
3549
|
+
"required": [
|
|
3550
|
+
"tool collection",
|
|
3551
|
+
"tool name",
|
|
3552
|
+
"this request",
|
|
3553
|
+
"URLs of similar requests for web users",
|
|
3554
|
+
"response metadata",
|
|
3555
|
+
"response content"
|
|
3556
|
+
],
|
|
3557
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3558
|
+
"additionalProperties": false,
|
|
3559
|
+
"definitions": {
|
|
3560
|
+
"ToolsFacts": {
|
|
3561
|
+
"type": "object",
|
|
3562
|
+
"properties": {
|
|
3563
|
+
"name": {
|
|
3564
|
+
"type": "string"
|
|
3565
|
+
},
|
|
3566
|
+
"description": {
|
|
3567
|
+
"type": "object",
|
|
3568
|
+
"properties": {
|
|
3569
|
+
"what Kilotest does": {
|
|
3570
|
+
"type": "string"
|
|
3571
|
+
},
|
|
3572
|
+
"how to retrieve findings": {
|
|
3573
|
+
"type": "object",
|
|
3574
|
+
"properties": {
|
|
3575
|
+
"level 1": {
|
|
3576
|
+
"type": "string"
|
|
3577
|
+
},
|
|
3578
|
+
"level 2": {
|
|
3579
|
+
"type": "string"
|
|
3580
|
+
},
|
|
3581
|
+
"level 3": {
|
|
3582
|
+
"type": "string"
|
|
3583
|
+
},
|
|
3584
|
+
"level 4": {
|
|
3585
|
+
"type": "string"
|
|
3586
|
+
}
|
|
3587
|
+
},
|
|
3588
|
+
"required": [
|
|
3589
|
+
"level 1",
|
|
3590
|
+
"level 2",
|
|
3591
|
+
"level 3",
|
|
3592
|
+
"level 4"
|
|
3593
|
+
],
|
|
3594
|
+
"additionalProperties": false
|
|
3595
|
+
},
|
|
3596
|
+
"how to generate more findings": {
|
|
3597
|
+
"type": "object",
|
|
3598
|
+
"properties": {
|
|
3599
|
+
"new testing": {
|
|
3600
|
+
"type": "string"
|
|
3601
|
+
},
|
|
3602
|
+
"retesting": {
|
|
3603
|
+
"type": "string"
|
|
3604
|
+
},
|
|
3605
|
+
"latency": {
|
|
3606
|
+
"type": "string"
|
|
3607
|
+
},
|
|
3608
|
+
"confirmation": {
|
|
3609
|
+
"type": "string"
|
|
3610
|
+
}
|
|
3611
|
+
},
|
|
3612
|
+
"required": [
|
|
3613
|
+
"new testing",
|
|
3614
|
+
"retesting",
|
|
3615
|
+
"latency",
|
|
3616
|
+
"confirmation"
|
|
3617
|
+
],
|
|
3618
|
+
"additionalProperties": false
|
|
3619
|
+
}
|
|
3620
|
+
},
|
|
3621
|
+
"required": [
|
|
3622
|
+
"what Kilotest does",
|
|
3623
|
+
"how to retrieve findings",
|
|
3624
|
+
"how to generate more findings"
|
|
3625
|
+
],
|
|
3626
|
+
"additionalProperties": false,
|
|
3627
|
+
"description": "Explanation of what Kilotest does and how to use its tools."
|
|
3628
|
+
},
|
|
3629
|
+
"URL": {
|
|
3630
|
+
"type": "string",
|
|
3631
|
+
"description": "URL of the Kilotest MCP server."
|
|
3632
|
+
},
|
|
3633
|
+
"web users can obtain similar functionalities at": {
|
|
3634
|
+
"type": "string"
|
|
3635
|
+
}
|
|
3636
|
+
},
|
|
3637
|
+
"required": [
|
|
3638
|
+
"name",
|
|
3639
|
+
"description",
|
|
3640
|
+
"URL",
|
|
3641
|
+
"web users can obtain similar functionalities at"
|
|
3642
|
+
],
|
|
3643
|
+
"additionalProperties": false
|
|
3644
|
+
},
|
|
3645
|
+
"RequestReference": {
|
|
3646
|
+
"type": "object",
|
|
3647
|
+
"properties": {
|
|
3648
|
+
"tool name": {
|
|
3649
|
+
"type": "string"
|
|
3650
|
+
},
|
|
3651
|
+
"description": {
|
|
3652
|
+
"type": "string"
|
|
3653
|
+
},
|
|
3654
|
+
"method": {
|
|
3655
|
+
"type": "string",
|
|
3656
|
+
"enum": [
|
|
3657
|
+
"GET",
|
|
3658
|
+
"POST"
|
|
3659
|
+
]
|
|
3660
|
+
},
|
|
3661
|
+
"URL": {
|
|
3662
|
+
"type": "string"
|
|
3663
|
+
}
|
|
3664
|
+
},
|
|
3665
|
+
"required": [
|
|
3666
|
+
"tool name",
|
|
3667
|
+
"description",
|
|
3668
|
+
"method",
|
|
3669
|
+
"URL"
|
|
3670
|
+
],
|
|
3671
|
+
"additionalProperties": false
|
|
3672
|
+
},
|
|
3673
|
+
"ResponseMetadata": {
|
|
3674
|
+
"type": "object",
|
|
3675
|
+
"properties": {
|
|
3676
|
+
"identifier": {
|
|
3677
|
+
"type": "string",
|
|
3678
|
+
"description": "Unique identifier of this response (timestamp and random suffix)."
|
|
3679
|
+
},
|
|
3680
|
+
"date and time": {
|
|
3681
|
+
"type": "string",
|
|
3682
|
+
"description": "UTC date and time when the response was generated, in ISO 8601 format."
|
|
3683
|
+
}
|
|
3684
|
+
},
|
|
3685
|
+
"required": [
|
|
3686
|
+
"identifier",
|
|
3687
|
+
"date and time"
|
|
3688
|
+
],
|
|
3689
|
+
"additionalProperties": false
|
|
3690
|
+
}
|
|
3691
|
+
}
|
|
3692
|
+
},
|
|
3693
|
+
"annotations": {
|
|
3694
|
+
"title": "Report disagreement with a diagnosis",
|
|
3695
|
+
"readOnlyHint": false,
|
|
3696
|
+
"destructiveHint": false,
|
|
3697
|
+
"idempotentHint": false,
|
|
3698
|
+
"openWorldHint": false
|
|
3699
|
+
},
|
|
3700
|
+
"execution": {
|
|
3701
|
+
"taskSupport": "forbidden"
|
|
3702
|
+
}
|
|
3703
|
+
},
|
|
3374
3704
|
{
|
|
3375
3705
|
"name": "orderNewTest",
|
|
3376
3706
|
"description": "Orders testing of a page that has no report yet, with automated approval or rejection and immediate enqueueing if approved. Use this instead of requestNewTest when immediate testing is wanted; testing typically takes 2 to 4 minutes. Returns an order confirmation and disposition details, including, if approved, a report identifier (timestamp and job identifier) and a question about whether to wait for completion with the awaitTest tool.",
|
|
@@ -4392,5 +4722,5 @@
|
|
|
4392
4722
|
}
|
|
4393
4723
|
}
|
|
4394
4724
|
],
|
|
4395
|
-
"version": "
|
|
4725
|
+
"version": "62.0.0"
|
|
4396
4726
|
}
|
package/llms-full.txt
CHANGED
|
@@ -124,6 +124,19 @@ Kilotest offers these tools:
|
|
|
124
124
|
- path: `/api/requestFeature`
|
|
125
125
|
- payload properties
|
|
126
126
|
- `feature`: description and motivation of the feature improvement or the new feature
|
|
127
|
+
- `reportDisagreement`
|
|
128
|
+
- method: `POST`
|
|
129
|
+
- purpose: report disagreement with a diagnosis shown by `listDiagnoses` of how an element exhibited an issue
|
|
130
|
+
- path: `/api/reportDisagreement/{issueID}/{reportID}/{catalogIndex}`
|
|
131
|
+
- parameters
|
|
132
|
+
- `issueID`: identifier of the issue
|
|
133
|
+
- `reportID`: identifier of the report, with YYMMDDTHHmm format for its initial segment (example: 260503T0432-x9z)
|
|
134
|
+
- `catalogIndex`: index of the catalog entry of the element
|
|
135
|
+
- source of parameters: response to a `listDiagnoses` request
|
|
136
|
+
- payload properties
|
|
137
|
+
- `engineID`: identifier of the rule engine that produced the disputed diagnosis, shown in the `listDiagnoses` response
|
|
138
|
+
- `ruleID`: identifier of the rule whose diagnosis is disputed, shown in the `listDiagnoses` response, or, if it is null, the description of the violation
|
|
139
|
+
- `reason`: 20- to 1000-character explanation of why the diagnosis is disputed
|
|
127
140
|
- `orderNewTest`
|
|
128
141
|
- method: `POST`
|
|
129
142
|
- purpose: order immediate, automatically approved testing of one web page about which no report is available, instead of waiting for manual approval
|
package/llms.txt
CHANGED
|
@@ -12,6 +12,7 @@ Kilotest integrates an ensemble of 12 rule engines, with about 1,300 rules, to t
|
|
|
12
12
|
- Request testing of a web page: `/api/requestNewTest` (`POST`)
|
|
13
13
|
- Request retesting of a web page: `/api/requestRetest/{reportID}` (`POST`)
|
|
14
14
|
- Request adding or improving a feature: `/api/requestFeature` (`POST`)
|
|
15
|
+
- Report disagreement with a diagnosis: `/api/reportDisagreement/{issueID}/{reportID}/{catalogIndex}` (`POST`)
|
|
15
16
|
- Order immediate, automatically approved testing of a web page: `/api/orderNewTest` (`POST`)
|
|
16
17
|
- Order immediate, automatically approved retesting of a web page: `/api/orderRetest/{reportID}` (`POST`)
|
|
17
18
|
- Wait for a job ordered via orderNewTest or orderRetest to complete: `/api/awaitTest/{reportID}` (`POST`)
|