diff --git a/docs/TOOLS.md b/docs/TOOLS.md index 52d9c2f8..0af19459 100644 --- a/docs/TOOLS.md +++ b/docs/TOOLS.md @@ -341,7 +341,7 @@ searchCapability → describeCapability → invokeCapability | Tool | What it does | |---|---| | `startAccessibilityScan` | Start a web accessibility scan of a page URL and retrieve a local CSV report path. Optional settings: `wcagVersion` (WCAG 2.0–2.2 at A/AA/AAA, or RGAA 4.1), `bestPractices`, `needsReview`, `advancedRules` and `experimentalRules`; the answer states the settings the scan ran with. To scan the same page again (for example after a fix), pass the earlier scan's `scanId`: that starts a new run of that scan with its saved settings, which `fetchAccessibilityIssues` can compare with `compareWith: "previous"`. Mobile apps are scanned through an App Automate run instead (`setupBrowserStackAppAutomateTests` with `accessibility: true`). | -| `accessibilityExpert` | Ask the A11y Expert (WCAG 2.0/2.1/2.2, mobile/web usability, best practices). | +| `accessibilityExpert` | **Deprecated, to be removed.** Ask the A11y Expert (WCAG 2.0/2.1/2.2, mobile/web usability, best practices). | | `createAccessibilityAuthConfig` | Create an authentication configuration (form-based or basic) for accessibility scans behind a login. | | `getAccessibilityAuthConfig` | Retrieve an existing accessibility authentication configuration by ID. | | `fetchAccessibilityIssues` | Fetch accessibility issues, with pagination, from a Website Scanner run, an Automated Tests build (web) or App Accessibility build (mobile app, by the build id the SDK prints), a Workflow Analyzer report, an App Accessibility manual report (`appReportId`), or a report's dashboard link (a Website Scanner link is read by the run's build id, however old the scan; a Workflow Analyzer link by the report id it carries). Once the tests or scan have finished, a report that is still processing is not waited on: the answer says to call again in a minute or two; a run still in progress is read as it is, with a note. For an app build with no scans, lists the likely causes. | diff --git a/src/tools/accessibility.ts b/src/tools/accessibility.ts index 840fb519..e2d95611 100644 --- a/src/tools/accessibility.ts +++ b/src/tools/accessibility.ts @@ -158,6 +158,13 @@ async function initializeReportFetcher( return reportFetcher; } +/** + * accessibilityExpert is going away; until it is removed it still answers, with this note, + * which names what to use instead so an agent stops reaching for it. + */ +const ACCESSIBILITY_EXPERT_DEPRECATED = + "Note: accessibilityExpert is deprecated and will be removed in a future release. To list or filter a report's issues, for example those failing a WCAG criterion, use fetchAccessibilityIssues and answer from its result; to scan a page, use startAccessibilityScan. For advice on a report, such as how to raise its score or which issues to fix first, call askBrowserStackAI with product a11y and give the user its answer. If askBrowserStackAI says it is not enabled for this account, answer from the report's issues."; + async function executeAccessibilityRAG( args: { query: string }, server: McpServer, @@ -172,14 +179,18 @@ async function executeAccessibilityRAG( ); const { query, shortened, kept } = fitExpertQuery(args.query); const answer = await queryAccessibilityRAG(query, config); - if (!shortened) return answer; return { ...answer, content: [ - { - type: "text", - text: `The question was ${args.query.length} characters; the knowledge base takes at most ${EXPERT_QUERY_MAX_CHARS}, so ${query.length} were sent: its ${kept ?? "opening"}. If the answer misses the point, ask again more briefly.`, - }, + { type: "text", text: ACCESSIBILITY_EXPERT_DEPRECATED }, + ...(shortened + ? [ + { + type: "text" as const, + text: `The question was ${args.query.length} characters; the knowledge base takes at most ${EXPERT_QUERY_MAX_CHARS}, so ${query.length} were sent: its ${kept ?? "opening"}. If the answer misses the point, ask again more briefly.`, + }, + ] + : []), ...(answer.content ?? []), ], }; @@ -1983,7 +1994,7 @@ export default function addAccessibilityTools( tools.accessibilityExpert = server.tool( "accessibilityExpert", - "Answer accessibility, a11y, and WCAG questions using BrowserStack's accessibility knowledge base.", + "Deprecated, to be removed: answers accessibility, a11y, and WCAG questions from BrowserStack's accessibility knowledge base.", { query: z .string() @@ -1992,7 +2003,7 @@ export default function addAccessibilityTools( ), }, { - title: "Accessibility Expert", + title: "Accessibility Expert (deprecated)", readOnlyHint: true, openWorldHint: false, destructiveHint: false, diff --git a/tests/tools/accessibilityExpertQuery.test.ts b/tests/tools/accessibilityExpertQuery.test.ts index eac8c925..9397a997 100644 --- a/tests/tools/accessibilityExpertQuery.test.ts +++ b/tests/tools/accessibilityExpertQuery.test.ts @@ -100,16 +100,19 @@ describe("accessibilityExpert with a long question", () => { const result = await ask(query); const sent: string = rag.query.mock.calls[0][0]; - expect(result.content[0].text).toBe( + expect(result.content[0].text).toMatch(/^Note: accessibilityExpert is deprecated/); + expect(result.content[1].text).toBe( `The question was ${query.length} characters; the knowledge base takes at most ${EXPERT_QUERY_MAX_CHARS}, so ${sent.length} were sent: its ${kept}. If the answer misses the point, ask again more briefly.`, ); expect(result.content.at(-1).text).toBe("Answer."); }); - it("adds no note to a question within the limit", async () => { + it("adds only the deprecation note to a question within the limit", async () => { const result = await ask(QUESTION); expect(rag.query.mock.calls[0][0]).toBe(QUESTION); - expect(result.content).toEqual([{ type: "text", text: "Answer." }]); + expect(result.content).toHaveLength(2); + expect(result.content[0].text).toMatch(/^Note: accessibilityExpert is deprecated/); + expect(result.content[1]).toEqual({ type: "text", text: "Answer." }); }); });