diff --git a/README.md b/README.md index 844ce5d..972511f 100644 --- a/README.md +++ b/README.md @@ -393,7 +393,7 @@ The daemon routes `POST /tool/:name` requests through the registry, applies Zod | `close_tab` | Closes a browser tab matching a given role or URL. Falls back to the extension tab if the active tab is closed. | | `wait_for_notification` | Waits for the extension notification popup to appear within a timeout. Returns the notification page URL. | | **Discovery** | | -| `describe_screen` | Captures a comprehensive screen snapshot: extension state, visible test IDs, trimmed a11y tree with refs, optional screenshot, and prior knowledge from historical sessions. | +| `describe_screen` | Captures a comprehensive screen snapshot: extension state, visible test IDs, trimmed a11y tree with refs, and optional screenshot. | | `accessibility_snapshot` | Captures a trimmed accessibility tree of the current page with deterministic refs (`e1`, `e2`, ...). Supports scoping to a root CSS selector. | | `list_testids` | Collects all visible `data-testid` attributes from the current page with text previews and visibility status. | | **State** | | @@ -456,7 +456,6 @@ The `KnowledgeStore` provides cross-session learning by recording every tool exe - **Step Recording**: Each tool invocation captures the tool name, input, outcome, observation (extension state, visible test IDs, a11y nodes), and timing. - **Session Metadata**: Sessions are tagged with goals, flow tags, and free-form tags for filtering. -- **Prior Knowledge**: Before tool execution, the store can generate context from historical sessions — similar steps, suggested actions, and patterns to avoid — based on the current screen state. - **Search**: Token-based search with synonym expansion across sessions, scored by relevance to screen, URL, test IDs, and a11y nodes. - **Sensitive Data Handling**: Input text for password fields and other sensitive inputs is automatically redacted. Recorded `clipboard` and `device_clipboard` text and all CDP `params` are replaced with `[REDACTED]`, including within `run_steps`. Echoes in the same step's error messages/details, tool targets, observations, and artifact paths are also scrubbed. Raw input strings of at least eight characters match substrings; shorter strings match whole values only. JSON-escaped echoes use the original raw string length to select the matching policy. Structural step metadata and diagnostic error codes are preserved. Tools and HTTP responses retain the original values. @@ -596,7 +595,7 @@ mm describe-screen | `mm click [--timeout ] [--selector ] [--testid ] [--within ]` | Clicks an element by its accessibility reference (e.g., `e3`). The ref comes from a prior `describe-screen` call. Waits for the element to be visible before clicking. The `--timeout` covers the entire operation (visibility wait + click action). Default: 15s. Use `--within` to scope the target inside a parent element (`testid:`, `selector:`, or a bare a11y ref). | | `mm type [--timeout ] [--selector ] [--testid ] [--within ]` | Types text into an input element identified by its accessibility reference. Clears the field first, then sets the new value (uses Playwright's `fill()`). Accepts `--timeout` for the total time budget (default: 15s). Use `--within` to scope the target inside a parent element. | | `mm get-text [--timeout ] [--selector ] [--testid ] [--within ]` | Reads the text content of an element. Returns the inner text, target descriptor, and character length. Accepts `--timeout` for the total time budget (default: 15s). Useful for asserting visible values without screenshots. | -| `mm describe-screen` | Captures the full screen state: extension info, visible test IDs, a trimmed accessibility tree with deterministic refs (`e1`, `e2`, ...), and prior knowledge from historical sessions. This is the primary command for understanding what's on screen before interacting. | +| `mm describe-screen` | Captures the full screen state: extension info, visible test IDs, and a trimmed accessibility tree with deterministic refs (`e1`, `e2`, ...). This is the primary command for understanding what's on screen before interacting. | | `mm screenshot [--name ]` | Takes a full-page screenshot of the current page. Saves to the artifacts directory. Use `--name` to set a descriptive filename. | | `mm wait-for [--timeout ] [--selector ] [--testid ] [--within ]` | Blocks until an element identified by its accessibility reference becomes visible, or the timeout expires. Default timeout is 15 seconds. Use `--within` to scope the target inside a parent element. | | `mm wait-for-notification [--timeout ]` | Waits for the extension notification popup to appear within a timeout. Returns the notification page URL. | diff --git a/SKILL.md b/SKILL.md index 68e918b..b6c3061 100644 --- a/SKILL.md +++ b/SKILL.md @@ -17,7 +17,7 @@ mm cleanup --shutdown # 5. Clean up when done **Critical rules:** - **Always `describe-screen` before interacting.** Refs like `e1`, `e2` are ephemeral — they change after every action. -- **Always `describe-screen` after interacting** — OR use inline `observations` from mutating tool responses. Mutating tools (click, type, navigate, etc.) return an `observations` object with fresh `state`, `testIds`, and `a11y` refs. You can use these refs directly for the next interaction without calling `describe-screen`. Call `describe-screen` when you need `priorKnowledge` or screenshots. +- **Always `describe-screen` after interacting** — OR use inline `observations` from mutating tool responses. Mutating tools (click, type, navigate, etc.) return an `observations` object with fresh `state`, `testIds`, and `a11y` refs. You can use these refs directly for the next interaction without calling `describe-screen`. Call `describe-screen` when you need the full tree or screenshots. - **One target per command.** Specify exactly ONE of: a11y ref (`e5`), testId, or CSS selector. - **Errors are structured.** Check the `error.code` field to decide recovery strategy (see Error Codes below). @@ -32,7 +32,7 @@ Tool responses include different data based on the tool's category: | **Discovery** | describe_screen, list_testids, accessibility_snapshot, screenshot | Data is already in `result` | | **Batch** | run_steps | Controlled by `includeObservations` param | -**Observation Compaction:** Mutating tool observations are **compacted** before returning: option runs of 3 or more under a combobox or listbox are replaced with a single summary node (e.g., `"55 options (refs e2–e56)"`). The `describe-screen` tool always returns the **full, unfiltered** a11y tree — use it when you need the complete option list or `priorKnowledge`. +**Observation Compaction:** Mutating tool observations are **compacted** before returning: option runs of 3 or more under a combobox or listbox are replaced with a single summary node (e.g., `"55 options (refs e2–e56)"`). The `describe-screen` tool always returns the **full, unfiltered** a11y tree — use it when you need the complete option list. **Diff-Based Observations:** After the first mutating tool call sets a baseline, subsequent mutations return **diff-based** observations. The `observations.a11y.diff` field (when present) shows what changed: @@ -73,7 +73,7 @@ You can use the `ref` values from `observations.a11y.nodes` for the next interac - Use `observations.state` for quick checks (screen name, loading status, balance, etc.) - Use `observations.a11y.nodes` with the compact refs for the next interaction -- Call `describe-screen` only when you need the full tree or `priorKnowledge` +- Call `describe-screen` only when you need the full tree ```bash mm click e3 # mutating: response includes fresh observations @@ -83,7 +83,6 @@ mm type e1 "0.01" # use ref from previous response Call `describe-screen` explicitly when you need: -- `priorKnowledge` (historical actions for this screen) - A screenshot via `includeScreenshot` - Full context after unexpected navigation - The complete, unfiltered a11y tree (e.g., all options in a dropdown) @@ -197,7 +196,6 @@ mm serve [--background] - **Active tab**: the currently focused tab's role and URL (if tracked) - **Test IDs**: visible `data-testid` attributes with text previews - **A11y tree**: interactive elements with deterministic refs (`e1`, `e2`, ...) -- **Prior knowledge**: suggested actions from past sessions on this screen ``` mm describe-screen @@ -240,7 +238,7 @@ Useful when you know a `testId` value and want to verify it exists. Prefer `desc #### `mm accessibility-snapshot` -Captures just the trimmed accessibility tree with deterministic refs. Lighter than `describe-screen` (no state, no prior knowledge, no test IDs). +Captures just the trimmed accessibility tree with deterministic refs. Lighter than `describe-screen` (no state, no test IDs). ``` mm accessibility-snapshot [--root ] @@ -678,21 +676,11 @@ Every interaction command (`click`, `type`, `get-text`, `wait-for`) needs a targ | Method | Format | Stability | When to use | | ---------------- | ------------------- | ------------------------------- | ---------------------------------------------------- | | **a11y ref** | `e1`, `e2`, ... | Ephemeral (per describe-screen) | Default — use refs from the latest `describe-screen` | -| **testId** | `data-testid` value | Stable across sessions | When you know the testId from prior knowledge | +| **testId** | `data-testid` value | Stable across sessions | When you know the testId from earlier output | | **CSS selector** | Any CSS selector | Fragile | Last resort fallback | **Prefer a11y refs.** They come directly from the accessibility tree and map to ARIA selectors, making them the most reliable for the current screen state. -## Prior Knowledge - -When you call `describe-screen`, the response may include a `priorKnowledge` section with: - -- **`similarSteps`**: Past tool invocations on the same screen with confidence scores -- **`suggestedNextActions`**: Ranked actions based on historical success (e.g., "click confirm button") -- **`avoid`**: Targets that frequently fail on this screen — skip these - -Use prior knowledge to guide your actions, but always verify against the current a11y tree. - ## Error Codes When a command fails, the response includes `error.code`. Use this to decide what to do: @@ -827,18 +815,6 @@ mm --project ../metamask-extension launch mm --project ../metamask-extension describe-screen ``` -### Using Prior Knowledge - -```bash -mm launch --state default --goal "Test send flow" --flow-tags send -mm describe-screen -# Response includes priorKnowledge.suggestedNextActions: -# [{ action: "click", preferredTarget: { type: "testId", value: "send-button" }, confidence: 0.85 }] -# Use the suggestion but verify the target exists in the current a11y tree -mm click e3 -mm cleanup --shutdown -``` - ## Project-Specific Commands diff --git a/src/knowledge-store/knowledge-store.test.ts b/src/knowledge-store/knowledge-store.test.ts index 35377ad..7e29076 100644 --- a/src/knowledge-store/knowledge-store.test.ts +++ b/src/knowledge-store/knowledge-store.test.ts @@ -166,7 +166,7 @@ describe('core', () => { }); describe('exported helpers', () => { - it('createDefaultObservation returns base observation without prior knowledge', () => { + it('createDefaultObservation returns base observation with defaults', () => { const state: ExtensionState = { isLoaded: true, currentUrl: 'chrome-extension://test/home.html', @@ -186,46 +186,6 @@ describe('core', () => { testIds: [], a11y: { nodes: [] }, }); - expect(observation.priorKnowledge).toBeUndefined(); - }); - - it('createDefaultObservation includes provided prior knowledge', () => { - const state: ExtensionState = { - isLoaded: true, - currentUrl: 'chrome-extension://test/home.html', - extensionId: 'test-ext', - isUnlocked: true, - currentScreen: 'home', - accountAddress: '0x1234', - networkName: 'Localhost 8545', - chainId: 1337, - balance: '25 ETH', - }; - const priorKnowledge = { - schemaVersion: 1 as const, - generatedAt: '2024-01-15T10:30:00.000Z', - query: { - windowHours: 48, - usedFlowTags: ['send'], - usedFilters: { sinceHours: 48 }, - candidateSessions: 1, - candidateSteps: 2, - }, - relatedSessions: [], - similarSteps: [], - suggestedNextActions: [], - }; - - const observation = createDefaultObservation( - state, - [{ testId: 'send-btn', tag: 'button', visible: true }], - [{ ref: 'e1', role: 'button', name: 'Send', path: [] }], - priorKnowledge, - ); - - expect(observation.priorKnowledge).toStrictEqual(priorKnowledge); - expect(observation.testIds).toHaveLength(1); - expect(observation.a11y.nodes).toHaveLength(1); }); it('createKnowledgeStore returns a KnowledgeStore instance', () => { diff --git a/src/knowledge-store/knowledge-store.ts b/src/knowledge-store/knowledge-store.ts index c18a923..3a57e96 100644 --- a/src/knowledge-store/knowledge-store.ts +++ b/src/knowledge-store/knowledge-store.ts @@ -1765,26 +1765,18 @@ export class KnowledgeStore { * @param state - Extension state snapshot * @param testIds - Array of visible test IDs * @param a11yNodes - Array of accessibility nodes - * @param priorKnowledge - Optional prior knowledge from history * @returns Observation object for step recording */ export function createDefaultObservation( state: ExtensionState, testIds: TestIdItem[] = [], a11yNodes: A11yNodeTrimmed[] = [], - priorKnowledge?: PriorKnowledgeV1, ): StepRecordObservation { - const observation: StepRecordObservation = { + return { state, testIds, a11y: { nodes: a11yNodes }, }; - - if (priorKnowledge) { - observation.priorKnowledge = priorKnowledge; - } - - return observation; } /** diff --git a/src/knowledge-store/utils/redaction.test.ts b/src/knowledge-store/utils/redaction.test.ts index 62083f9..4aa4933 100644 --- a/src/knowledge-store/utils/redaction.test.ts +++ b/src/knowledge-store/utils/redaction.test.ts @@ -296,13 +296,6 @@ describe('redactRecordedSecrets', () => { const echo = `echo ${secret}; ${JSON.stringify(secret)}`; const redactedEcho = 'echo [REDACTED]; "[REDACTED]"'; const record = stepRecord(); - const historyMetadata = { - sessionId: record.sessionId, - timestamp: record.timestamp, - tool: 'cdp', - labels: ['interaction'], - confidence: 1, - }; record.tool.target = { selector: echo, testId: echo, a11yRef: echo }; record.outcome.error = { code: 'MM_CDP_FAILED', @@ -341,59 +334,6 @@ describe('redactRecordedSecrets', () => { ], diff: { added: [echo], removed: [echo], unchanged: 2 }, }; - observation.priorKnowledge = { - schemaVersion: 1, - generatedAt: record.timestamp, - query: { - windowHours: 48, - usedFlowTags: ['onboarding'], - usedFilters: { screen: echo }, - candidateSessions: 1, - candidateSteps: 1, - }, - relatedSessions: [ - { - sessionId: record.sessionId, - createdAt: record.timestamp, - goal: echo, - flowTags: ['onboarding'], - tags: ['test'], - }, - ], - similarSteps: [ - { - ...historyMetadata, - screen: echo, - snippet: echo, - target: { testId: echo }, - a11yHint: { role: 'button', name: echo }, - }, - ], - suggestedNextActions: [ - { - rank: 1, - action: 'type', - rationale: echo, - confidence: 1, - preferredTarget: { - type: 'a11yHint', - value: { role: 'button', name: echo }, - }, - fallbackTargets: [ - { type: 'testId', value: echo }, - { type: 'selector', value: echo }, - ], - }, - ], - avoid: [ - { - rationale: echo, - target: { selector: echo }, - errorCode: 'EXAMPLE', - frequency: 1, - }, - ], - }; const original = structuredClone(record); // Intentional exact matches prove structural metadata survives redaction. const structuralStrings = [ @@ -402,11 +342,8 @@ describe('redactRecordedSecrets', () => { 'button', 'element', 'e2', - 'type', - 'a11yHint', 'testId', 'notification', - 'EXAMPLE', 'MM_CDP_FAILED', 'error-recovery', record.sessionId, @@ -449,47 +386,6 @@ describe('redactRecordedSecrets', () => { nodes: [{ ref: 'e2', role: 'button', name: redactedEcho }], diff: { added: [redactedEcho], removed: [redactedEcho], unchanged: 2 }, }, - priorKnowledge: { - generatedAt: record.timestamp, - query: { usedFilters: { screen: redactedEcho } }, - relatedSessions: [ - { - sessionId: record.sessionId, - createdAt: record.timestamp, - goal: redactedEcho, - }, - ], - similarSteps: [ - { - ...historyMetadata, - screen: redactedEcho, - snippet: redactedEcho, - target: { testId: redactedEcho }, - a11yHint: { role: 'button', name: redactedEcho }, - }, - ], - suggestedNextActions: [ - { - action: 'type', - rationale: redactedEcho, - preferredTarget: { - type: 'a11yHint', - value: { role: 'button', name: redactedEcho }, - }, - fallbackTargets: [ - { type: 'testId', value: redactedEcho }, - { type: 'selector', value: redactedEcho }, - ], - }, - ], - avoid: [ - { - errorCode: 'EXAMPLE', - rationale: redactedEcho, - target: { selector: redactedEcho }, - }, - ], - }, }); expect(record).toStrictEqual(original); }); diff --git a/src/knowledge-store/utils/redaction.ts b/src/knowledge-store/utils/redaction.ts index 9c4bb80..313ed6d 100644 --- a/src/knowledge-store/utils/redaction.ts +++ b/src/knowledge-store/utils/redaction.ts @@ -1,7 +1,3 @@ -import type { - PriorKnowledgeTarget, - PriorKnowledgeV1, -} from '../../tools/types/knowledge.js'; import type { StepRecord, StepRecordObservation, @@ -143,81 +139,6 @@ function createSecretRedactor( }; } -/** - * Redact a suggested target's text while keeping its type and accessibility role. - * - * @param target - The suggested target. - * @param redactor - The secret-matching operations. - * @returns A redacted target. - */ -function redactKnowledgeTarget( - target: PriorKnowledgeTarget, - redactor: SecretRedactor, -): PriorKnowledgeTarget { - if (target.type === 'a11yHint') { - return { - ...target, - value: { ...target.value, name: redactor.text(target.value.name) }, - }; - } - return { ...target, value: redactor.text(target.value) }; -} - -/** - * Redact historical free text, retaining session IDs, timestamps, and diagnostics. - * - * @param knowledge - The prior knowledge attached to an observation. - * @param redactor - The secret-matching operations. - * @returns A redacted copy of the prior knowledge. - */ -function redactPriorKnowledge( - knowledge: PriorKnowledgeV1, - redactor: SecretRedactor, -): PriorKnowledgeV1 { - const sanitized: PriorKnowledgeV1 = { - ...knowledge, - query: { - ...knowledge.query, - usedFilters: redactor.value(knowledge.query.usedFilters), - }, - relatedSessions: knowledge.relatedSessions.map((session) => ({ - ...session, - goal: redactor.value(session.goal), - })), - similarSteps: knowledge.similarSteps.map((step) => { - const sanitizedStep = { - ...step, - screen: redactor.text(step.screen), - snippet: redactor.text(step.snippet), - target: redactor.value(step.target), - }; - if (step.a11yHint) { - sanitizedStep.a11yHint = { - ...step.a11yHint, - name: redactor.text(step.a11yHint.name), - }; - } - return sanitizedStep; - }), - suggestedNextActions: knowledge.suggestedNextActions.map((action) => ({ - ...action, - rationale: redactor.text(action.rationale), - preferredTarget: redactKnowledgeTarget(action.preferredTarget, redactor), - fallbackTargets: action.fallbackTargets?.map((target) => - redactKnowledgeTarget(target, redactor), - ), - })), - }; - if (knowledge.avoid) { - sanitized.avoid = knowledge.avoid.map((item) => ({ - ...item, - rationale: redactor.text(item.rationale), - target: redactor.value(item.target), - })); - } - return sanitized; -} - /** * Redact observation text while retaining accessibility refs, roles, and tags. * @@ -281,7 +202,6 @@ export function redactRecordedSecrets( } const { error } = record.outcome; const screenshot = record.artifacts?.screenshot; - const { priorKnowledge } = record.observation; const sanitized: StepRecord = { ...record, tool: { ...record.tool }, @@ -304,11 +224,5 @@ export function redactRecordedSecrets( screenshot: { ...screenshot, path: redactor.value(screenshot.path) }, }; } - if (priorKnowledge) { - sanitized.observation.priorKnowledge = redactPriorKnowledge( - priorKnowledge, - redactor, - ); - } return sanitized; } diff --git a/src/server/create-server.test.ts b/src/server/create-server.test.ts index 32f5f0b..fe48670 100644 --- a/src/server/create-server.test.ts +++ b/src/server/create-server.test.ts @@ -47,7 +47,6 @@ vi.mock('../knowledge-store/knowledge-store.js', () => { searchSteps: vi.fn().mockResolvedValue([]), summarizeSession: vi.fn().mockResolvedValue({ stepCount: 0, recipe: [] }), listSessions: vi.fn().mockResolvedValue([]), - generatePriorKnowledge: vi.fn().mockResolvedValue(undefined), getAllSessionIds: vi.fn().mockResolvedValue([]), resolveSessionIds: vi.fn().mockResolvedValue([]), }; diff --git a/src/server/observation-compaction.test.ts b/src/server/observation-compaction.test.ts index 033c41f..a917f07 100644 --- a/src/server/observation-compaction.test.ts +++ b/src/server/observation-compaction.test.ts @@ -45,9 +45,6 @@ function createObservation( nodes, ...(overrides.a11y?.diff ? { diff: overrides.a11y.diff } : {}), }, - ...(overrides.priorKnowledge - ? { priorKnowledge: overrides.priorKnowledge } - : {}), } as StepRecordObservation; } @@ -194,14 +191,12 @@ describe('compactObservation', () => { it('preserves non-a11y fields by reference while returning a new object', () => { const state = { connected: true }; const testIds = [{ testId: 'submit', tag: 'button', visible: true }]; - const priorKnowledge = { schemaVersion: 1, notes: ['cached'] }; const observation = { state, testIds, a11y: { nodes: [createNode('e1', 'combobox'), ...createOptionRun(4, 2)], }, - priorKnowledge, } as unknown as StepRecordObservation; const result = compactObservation(observation); @@ -209,7 +204,6 @@ describe('compactObservation', () => { expect(result).not.toBe(observation); expect(result.state).toBe(state); expect(result.testIds).toBe(testIds); - expect(result.priorKnowledge).toBe(priorKnowledge); expect(result.a11y).not.toBe(observation.a11y); expect(result.a11y.nodes).toStrictEqual([ observation.a11y.nodes[0], @@ -543,19 +537,4 @@ describe('diffObservation', () => { expect(result.state).toBe(state); expect(result.testIds).toBe(testIds); }); - - it('preserves the current priorKnowledge', () => { - const priorKnowledge = { - schemaVersion: 1, - notes: ['cached'], - } as unknown as StepRecordObservation['priorKnowledge']; - const previous = createObservation([]); - const current = createObservation([createNode('e1', 'button')], { - priorKnowledge, - }); - - const result = diffObservation(current, previous); - - expect(result.priorKnowledge).toBe(priorKnowledge); - }); }); diff --git a/src/server/observation-compaction.ts b/src/server/observation-compaction.ts index e525c8d..a96196d 100644 --- a/src/server/observation-compaction.ts +++ b/src/server/observation-compaction.ts @@ -256,6 +256,5 @@ export function diffObservation( unchanged: unchangedCount, }, }, - priorKnowledge: current.priorKnowledge, }; } diff --git a/src/tools/discovery-tools.test.ts b/src/tools/discovery-tools.test.ts index ca28c12..3ac5e66 100644 --- a/src/tools/discovery-tools.test.ts +++ b/src/tools/discovery-tools.test.ts @@ -37,18 +37,6 @@ function createMockContext( const page = createMockPage(); const sessionManager = createMockSessionManager({ hasActive, - sessionId: 'test-session-123', - sessionMetadata: { - schemaVersion: 1, - sessionId: 'test-session-123', - createdAt: '2026-02-04T00:00:00.000Z', - goal: 'Test discovery', - flowTags: ['discovery'], - tags: [], - launch: { - stateMode: 'default', - }, - }, }); return { @@ -56,9 +44,7 @@ function createMockContext( page, refMap: new Map(), workflowContext: {}, - knowledgeStore: { - generatePriorKnowledge: vi.fn().mockResolvedValue(undefined), - }, + knowledgeStore: {}, driver: hasActive ? new PlaywrightPlatformDriver(() => page, sessionManager as any) : undefined, @@ -421,61 +407,6 @@ describe('discovery-tools', () => { }); }); - it('generates prior knowledge from context', async () => { - const context = createMockContext(); - const mockTestIds: TestIdItem[] = [ - { testId: 'send-btn', tag: 'button', visible: true }, - ]; - const mockNodes: A11yNodeTrimmed[] = [ - { ref: 'e1', role: 'button', name: 'Send', path: [] }, - ]; - const mockPriorKnowledge = { - schemaVersion: 1 as const, - generatedAt: '2026-02-04T00:00:00.000Z', - query: { - currentScreen: 'home', - currentUrl: 'chrome-extension://ext-123/home.html', - visibleTestIds: mockTestIds, - a11yNodes: mockNodes, - currentSessionFlowTags: ['discovery'], - }, - relatedSessions: [], - similarSteps: [], - suggestedNextActions: [], - }; - - vi.spyOn(discoveryModule, 'collectTestIds').mockResolvedValue( - mockTestIds, - ); - vi.spyOn(discoveryModule, 'collectTrimmedA11ySnapshot').mockResolvedValue( - { - nodes: mockNodes, - refMap: new Map([['e1', 'role=button[name="Send"]']]), - }, - ); - vi.mocked( - context.knowledgeStore.generatePriorKnowledge, - ).mockResolvedValue(mockPriorKnowledge as any); - - const result = await describeScreenTool({}, context); - - expect(result.ok).toBe(true); - if (result.ok) { - expect(result.result.priorKnowledge).toStrictEqual(mockPriorKnowledge); - } - expect( - context.knowledgeStore.generatePriorKnowledge, - ).toHaveBeenCalledWith( - expect.objectContaining({ - currentScreen: 'home', - visibleTestIds: mockTestIds, - a11yNodes: mockNodes, - currentSessionFlowTags: ['discovery'], - }), - 'test-session-123', - ); - }); - it('updates refMap in session manager', async () => { const context = createMockContext(); const mockRefMap = new Map([['e1', 'role=button[name="OK"]']]); diff --git a/src/tools/discovery-tools.ts b/src/tools/discovery-tools.ts index 134c78c..1d690d7 100644 --- a/src/tools/discovery-tools.ts +++ b/src/tools/discovery-tools.ts @@ -6,7 +6,6 @@ import type { DescribeScreenResult, ListTestIdsInput, ListTestIdsResult, - PriorKnowledgeContext, } from './types'; import { ErrorCodes } from './types'; import { DEFAULT_TESTID_LIMIT } from './utils/constants.js'; @@ -108,7 +107,7 @@ export async function accessibilitySnapshotTool( } /** - * Captures a full screen description including state, test IDs, a11y, and prior knowledge. + * Captures a full screen description including state, test IDs, a11y, and an optional screenshot. * * @param input - The describe-screen options including screenshot flags. * @param context - The tool execution context. @@ -165,27 +164,12 @@ export async function describeScreenTool( }; } - const sessionMetadata = context.sessionManager.getSessionMetadata(); - const priorKnowledgeContext: PriorKnowledgeContext = { - currentScreen: state.currentScreen, - currentUrl: state.currentUrl, - visibleTestIds: testIds, - a11yNodes: nodes, - currentSessionFlowTags: sessionMetadata?.flowTags, - }; - - const priorKnowledge = await context.knowledgeStore.generatePriorKnowledge( - priorKnowledgeContext, - context.sessionManager.getSessionId(), - ); - return createToolSuccess({ state, activeTab, testIds: { items: testIds }, a11y: { nodes }, screenshot, - priorKnowledge, }); } catch (error) { const errorInfo = classifyDiscoveryError(error); diff --git a/src/tools/driver-delegation.test.ts b/src/tools/driver-delegation.test.ts index 6d4ce5c..a2e4099 100644 --- a/src/tools/driver-delegation.test.ts +++ b/src/tools/driver-delegation.test.ts @@ -79,9 +79,7 @@ function createContextWithDriver(driver: IPlatformDriver): ToolContext { page: page as any, refMap: new Map(), workflowContext: {} as any, - knowledgeStore: { - generatePriorKnowledge: vi.fn().mockResolvedValue(undefined), - } as any, + knowledgeStore: {} as any, toolRegistry: new Map(), driver, } as unknown as ToolContext; @@ -96,9 +94,7 @@ function createContextWithoutDriver(): ToolContext { page: page as any, refMap: new Map(), workflowContext: {} as any, - knowledgeStore: { - generatePriorKnowledge: vi.fn().mockResolvedValue(undefined), - } as any, + knowledgeStore: {} as any, toolRegistry: new Map(), driver: undefined, } as unknown as ToolContext; @@ -434,9 +430,7 @@ describe('tool delegation to context.driver', () => { page: {} as any, refMap: new Map(), workflowContext: {} as any, - knowledgeStore: { - generatePriorKnowledge: vi.fn().mockResolvedValue(undefined), - } as any, + knowledgeStore: {} as any, toolRegistry: new Map(), driver, } as unknown as ToolContext; @@ -534,9 +528,7 @@ describe('tool delegation to context.driver', () => { page: {} as any, refMap: new Map(), workflowContext: {} as any, - knowledgeStore: { - generatePriorKnowledge: vi.fn().mockResolvedValue(undefined), - } as any, + knowledgeStore: {} as any, toolRegistry: new Map(), driver, } as unknown as ToolContext; diff --git a/src/tools/test-utils/mock-factories.test.ts b/src/tools/test-utils/mock-factories.test.ts index 0987102..34a8423 100644 --- a/src/tools/test-utils/mock-factories.test.ts +++ b/src/tools/test-utils/mock-factories.test.ts @@ -121,7 +121,6 @@ describe('mock-factories', () => { expect(typeof mock.searchSteps).toBe('function'); expect(typeof mock.summarizeSession).toBe('function'); expect(typeof mock.listSessions).toBe('function'); - expect(typeof mock.generatePriorKnowledge).toBe('function'); expect(typeof mock.writeSessionMetadata).toBe('function'); }); diff --git a/src/tools/test-utils/mock-factories.ts b/src/tools/test-utils/mock-factories.ts index f19ee1c..73df9d4 100644 --- a/src/tools/test-utils/mock-factories.ts +++ b/src/tools/test-utils/mock-factories.ts @@ -174,7 +174,6 @@ export function createMockKnowledgeStore( }, ), listSessions: vi.fn().mockResolvedValue(options.sessions ?? []), - generatePriorKnowledge: vi.fn().mockResolvedValue(undefined), writeSessionMetadata: vi.fn().mockResolvedValue('test-session-123'), }; } diff --git a/src/tools/types/step-record.ts b/src/tools/types/step-record.ts index 175ad89..a5cc6e5 100644 --- a/src/tools/types/step-record.ts +++ b/src/tools/types/step-record.ts @@ -1,5 +1,4 @@ import type { TestIdItem, A11yNodeTrimmed } from './discovery.js'; -import type { PriorKnowledgeV1 } from './knowledge.js'; import type { ExtensionState } from '../../capabilities/types.js'; export const FLOW_TAGS = [ @@ -72,7 +71,6 @@ export type StepRecordObservation = { unchanged: number; }; }; - priorKnowledge?: PriorKnowledgeV1; }; export type StepRecordArtifacts = { diff --git a/src/tools/types/tool-outputs.ts b/src/tools/types/tool-outputs.ts index 58a2167..98d5920 100644 --- a/src/tools/types/tool-outputs.ts +++ b/src/tools/types/tool-outputs.ts @@ -1,5 +1,4 @@ import type { TestIdItem, A11yNodeTrimmed } from './discovery.js'; -import type { PriorKnowledgeV1 } from './knowledge.js'; import type { NetworkMockRequestRecord, NetworkMockRouteRule, @@ -72,7 +71,6 @@ export type DescribeScreenResult = { nodes: A11yNodeTrimmed[]; }; screenshot: ScreenshotInfo; - priorKnowledge?: PriorKnowledgeV1; }; export type ScreenshotToolResult = {