chore: save downloads to outputDir (#310)
This commit is contained in:
@@ -20,10 +20,9 @@ import os from 'os';
|
||||
import path from 'path';
|
||||
import { devices } from 'playwright';
|
||||
|
||||
import { sanitizeForFilePath } from './tools/utils.js';
|
||||
|
||||
import type { Config, ToolCapability } from '../config.js';
|
||||
import type { BrowserContextOptions, LaunchOptions } from 'playwright';
|
||||
import { sanitizeForFilePath } from './tools/utils.js';
|
||||
|
||||
export type CLIOptions = {
|
||||
browser?: string;
|
||||
|
||||
@@ -23,6 +23,7 @@ import { Tab } from './tab.js';
|
||||
import type { ImageContent, TextContent } from '@modelcontextprotocol/sdk/types.js';
|
||||
import type { ModalState, Tool, ToolActionResult } from './tools/tool.js';
|
||||
import type { Config } from '../config.js';
|
||||
import { outputFile } from './config.js';
|
||||
|
||||
type PendingAction = {
|
||||
dialogShown: ManualPromise<void>;
|
||||
@@ -38,6 +39,7 @@ export class Context {
|
||||
private _currentTab: Tab | undefined;
|
||||
private _modalStates: (ModalState & { tab: Tab })[] = [];
|
||||
private _pendingAction: PendingAction | undefined;
|
||||
private _downloads: { download: playwright.Download, finished: boolean, outputFile: string }[] = [];
|
||||
|
||||
constructor(tools: Tool[], config: Config) {
|
||||
this.tools = tools;
|
||||
@@ -164,6 +166,17 @@ ${code.join('\n')}
|
||||
};
|
||||
}
|
||||
|
||||
if (this._downloads.length) {
|
||||
result.push('', '### Downloads');
|
||||
for (const entry of this._downloads) {
|
||||
if (entry.finished)
|
||||
result.push(`- Downloaded file ${entry.download.suggestedFilename()} to ${entry.outputFile}`);
|
||||
else
|
||||
result.push(`- Downloading file ${entry.download.suggestedFilename()} ...`);
|
||||
}
|
||||
result.push('');
|
||||
}
|
||||
|
||||
if (this.tabs().length > 1)
|
||||
result.push(await this.listTabsMarkdown(), '');
|
||||
|
||||
@@ -228,6 +241,17 @@ ${code.join('\n')}
|
||||
this._pendingAction?.dialogShown.resolve();
|
||||
}
|
||||
|
||||
async downloadStarted(tab: Tab, download: playwright.Download) {
|
||||
const entry = {
|
||||
download,
|
||||
finished: false,
|
||||
outputFile: await outputFile(this.config, download.suggestedFilename())
|
||||
};
|
||||
this._downloads.push(entry);
|
||||
await download.saveAs(entry.outputFile);
|
||||
entry.finished = true;
|
||||
}
|
||||
|
||||
private _onPageCreated(page: playwright.Page) {
|
||||
const tab = new Tab(this, page, tab => this._onPageClosed(tab));
|
||||
this._tabs.push(tab);
|
||||
|
||||
@@ -48,6 +48,9 @@ export class Tab {
|
||||
}, this);
|
||||
});
|
||||
page.on('dialog', dialog => this.context.dialogShown(this, dialog));
|
||||
page.on('download', download => {
|
||||
void this.context.downloadStarted(this, download);
|
||||
});
|
||||
page.setDefaultNavigationTimeout(60000);
|
||||
page.setDefaultTimeout(5000);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ const pdf = defineTool({
|
||||
|
||||
handle: async context => {
|
||||
const tab = context.currentTabOrDie();
|
||||
const fileName = await outputFile(context.config, `page-${new Date().toISOString()}'.pdf'`);
|
||||
const fileName = await outputFile(context.config, `page-${new Date().toISOString()}.pdf`);
|
||||
|
||||
const code = [
|
||||
`// Save page as ${fileName}`,
|
||||
|
||||
Reference in New Issue
Block a user