Skip to content

feat(mcp): add --output-max-size for output dir eviction#41021

Open
Skn0tt wants to merge 12 commits into
microsoft:mainfrom
Skn0tt:feat-output-max-size
Open

feat(mcp): add --output-max-size for output dir eviction#41021
Skn0tt wants to merge 12 commits into
microsoft:mainfrom
Skn0tt:feat-output-max-size

Conversation

@Skn0tt
Copy link
Copy Markdown
Member

@Skn0tt Skn0tt commented May 27, 2026

Summary

  • New --output-max-size <bytes> option (CLI / config / env) for the MCP output directory.
  • Before each tracked write, OutputDir evicts the oldest evictable artifacts until the new write fits.
  • Session log and user-supplied workspace files are pinned (never evicted).

Skn0tt added 9 commits May 27, 2026 12:44
Adds an integer-byte budget for the MCP/CLI output directory. Before
each tracked write, the oldest evictable artifacts are deleted to keep
the total under the cap. Session logs and per-tab log files are pinned
(they still count toward the budget, but are never evicted). Trace
artifacts are resolved through the cap but intentionally never report
their size, since a live trace grows unbounded.

Config surface: `outputMaxSize` field, `--output-max-size <bytes>` CLI
flag, and `PLAYWRIGHT_MCP_OUTPUT_MAX_SIZE` env var.

Internally, `Context.outputFile` now returns an `OutputFile` (resolved
through the new per-context `OutputDir`), so every cap-tracked write
flows through a single chokepoint: `OutputFile.write`, `.append`, and
`.trackSize`. Workspace-branch files resolved via `resolveClientFile`
are pinned non-evictable so user files are never auto-deleted.
…ir files as evictable

- In Response.resolveClientFile, files whose suggested filename lands inside
  outputDir are now evictable (workspace files remain pinned).
- Collapse the spec down to two focused tests with helpers inlined.
Collapse parallel _files/_entries maps into one Map<path, OutputFile>;
insertion order encodes age. Single _evict loop replaces _evictForBytes
plus _oldestEvictable. Each write/append/trackSize tracks the file's
own size and re-inserts itself to mark "newest".

Also: Response no longer special-cases suggested filenames; OutputDir.resolve
defaults `evictable` based on whether the resolved path lives inside outputDir.
OutputFile.write/append no longer mkdir on every call; OutputDir.resolve
is now async and ensures the parent dir exists once. Drop the duplicate
mkdir from context.outputFile.
Log resolve, write, append, and evict actions with sizes through the
'pw:mcp:file' channel; drop the redundant log in context.outputFile.
Size 0 means we haven't accounted for the file's bytes, so unlinking
it could delete something we don't own.
@Skn0tt Skn0tt requested a review from pavelfeldman May 27, 2026 12:07
@github-actions

This comment has been minimized.

@github-actions
Copy link
Copy Markdown
Contributor

Test results for "tests 1"

3 failed
❌ [default] › run-tests.spec.ts:1041 › should produce output twice @vscode-extension
❌ [firefox-library] › library/browsertype-basic.spec.ts:34 › should throw when trying to connect with not-chromium @firefox-ubuntu-22.04-node20
❌ [webkit-library] › library/browsertype-basic.spec.ts:34 › should throw when trying to connect with not-chromium @webkit-ubuntu-22.04-node20

3 flaky ⚠️ [chromium-library] › library/video.spec.ts:682 › screencast › should capture full viewport on hidpi `@ubuntu-22.04-chromium-tip-of-tree`
⚠️ [chromium-library] › library/video.spec.ts:275 › screencast › should capture navigation `@chromium-ubuntu-22.04-node24`
⚠️ [chromium-library] › library/inspector/cli-codegen-2.spec.ts:105 › cli codegen › should upload a single file `@chromium-ubuntu-22.04-node20`

43922 passed, 861 skipped


Merge workflow run.

Copy link
Copy Markdown
Member

@pavelfeldman pavelfeldman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made some random comments, but I don't think the approach is quite right. I would examine response for the new output folder entries and would remove the oldest entries instead.

Comment thread packages/playwright-core/src/tools/mcp/program.ts Outdated
Comment thread packages/playwright-core/src/tools/backend/tracing.ts Outdated
Comment thread packages/playwright-core/src/tools/backend/response.ts
Skn0tt added 2 commits May 28, 2026 09:05
Per review on microsoft#41021. We'll file an issue if we want this later.
No caller passes it. Workspace files are classified non-evictable by
OutputDir.resolve via isPathInside; outputDir files are evictable.
Removing the param avoids suggesting client files could be pinned.
Skn0tt added a commit to Skn0tt/playwright that referenced this pull request May 28, 2026
Per review on microsoft#41021. The previous "We don't own writing so we cannot
track file size for this" comment meant traces were pinned outside the
budget, so a single trace could blow the cap unboundedly.

Drop `evictable: false` from the traces directory and, on tracingStop,
walk the produced trace files via OutputDir.trackTree to register their
sizes. Old traces become evictable like any other artifact.

We still can't account for the trace mid-recording (no hooks), but
post-stop accounting is enough to keep multi-trace sessions under cap.
@Skn0tt Skn0tt force-pushed the feat-output-max-size branch from aa6654c to 1883162 Compare May 28, 2026 07:16
@Skn0tt
Copy link
Copy Markdown
Member Author

Skn0tt commented May 28, 2026

I made some random comments, but I don't think the approach is quite right. I would examine response for the new output folder entries and would remove the oldest entries instead.

Is #41031 what you have in mind? I put that up as an alternative PR and updated this one to address your comments.

Here's the main differences I see between the approaches:

  • fs-based evicts across concurrent sessions, write-through evicts only session-owned files
  • write-through uses less I/O for accounting
  • Unless we teach fs-based about patterns for tracesDir, it will partially evict it and leave it in inconsistent state, e.g. missing resources

@Skn0tt Skn0tt requested a review from pavelfeldman May 28, 2026 07:26
@github-actions
Copy link
Copy Markdown
Contributor

Test results for "MCP"

1 failed
❌ [webkit] › mcp/output-max-size.spec.ts:22 › evicts oldest evictable files before write exceeds cap, pinned session.md survives @mcp-macos-latest-webkit

7232 passed, 1113 skipped


Merge workflow run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants