agent-reader 1.1.1 → 1.1.2

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/README.md CHANGED
@@ -232,6 +232,7 @@ Claude Desktop 配置(`claude_desktop_config.json`):
232
232
  ## 云环境部署
233
233
 
234
234
  在 Docker/CI 中,Agent Reader 会自动检测环境并在需要时为 Puppeteer 关闭沙盒参数(`--no-sandbox` 等)。
235
+ 在部分非标准云环境里,`auto` 模式首次失败时也会自动重试一次 `no-sandbox`,减少手动排障。
235
236
 
236
237
  手动覆盖方式:
237
238
 
@@ -17,7 +17,7 @@ const program = new Command();
17
17
  program
18
18
  .name('agent-reader')
19
19
  .description('AI Agent output beautifier and slideshow generator')
20
- .version('1.1.1');
20
+ .version('1.1.2');
21
21
 
22
22
  setupCommonCommandOptions(
23
23
  program
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-reader",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "AI Agent 的文档美化引擎 — 一键把 Markdown 变成漂亮网页、Word、PDF 和幻灯片",
5
5
  "main": "index.js",
6
6
  "directories": {
@@ -690,30 +690,15 @@ export function createPandocFallbackWarnings(platform = process.platform) {
690
690
  ];
691
691
  }
692
692
 
693
- export async function exportPDF(html, options = {}) {
694
- const {
695
- pageSize = 'A4',
696
- landscape = false,
697
- outDir = os.tmpdir(),
698
- fileName = 'output.pdf',
699
- htmlPath,
700
- sandbox,
701
- } = options;
702
-
703
- let puppeteer;
704
- try {
705
- const mod = await import('puppeteer');
706
- puppeteer = mod.default || mod;
707
- } catch {
708
- throw new Error('Puppeteer is not installed. Install optional dependency: npm install puppeteer');
709
- }
710
-
711
- const warnings = [];
712
- const pdfPath = path.join(path.resolve(outDir), fileName);
713
- const resolvedSandboxMode = resolveSandboxMode(sandbox);
714
- const launchArgs = landscape ? ['--allow-file-access-from-files'] : [];
715
- launchArgs.push(...getSandboxArgs(resolvedSandboxMode));
716
-
693
+ async function renderPdfWithPuppeteer({
694
+ puppeteer,
695
+ launchArgs,
696
+ html,
697
+ htmlPath,
698
+ pageSize,
699
+ landscape,
700
+ pdfPath,
701
+ }) {
717
702
  const browser = await puppeteer.launch({
718
703
  headless: true,
719
704
  args: launchArgs,
@@ -731,7 +716,7 @@ export async function exportPDF(html, options = {}) {
731
716
  });
732
717
  }
733
718
 
734
- // Wait for images and fonts to finish loading before generating PDF
719
+ // Wait for images and fonts to finish loading before generating PDF.
735
720
  await page.evaluate(() =>
736
721
  Promise.all([
737
722
  document.fonts?.ready,
@@ -808,7 +793,72 @@ blockquote { break-inside: avoid; }`,
808
793
  tagged: true,
809
794
  });
810
795
  } finally {
811
- await browser.close();
796
+ await browser.close().catch(() => {});
797
+ }
798
+ }
799
+
800
+ export async function exportPDF(html, options = {}) {
801
+ const {
802
+ pageSize = 'A4',
803
+ landscape = false,
804
+ outDir = os.tmpdir(),
805
+ fileName = 'output.pdf',
806
+ htmlPath,
807
+ sandbox,
808
+ puppeteerInstance,
809
+ sandboxRuntime,
810
+ } = options;
811
+
812
+ let puppeteer = puppeteerInstance;
813
+ try {
814
+ if (!puppeteer) {
815
+ const mod = await import('puppeteer');
816
+ puppeteer = mod.default || mod;
817
+ }
818
+ } catch {
819
+ throw new Error('Puppeteer is not installed. Install optional dependency: npm install puppeteer');
820
+ }
821
+
822
+ const warnings = [];
823
+ const pdfPath = path.join(path.resolve(outDir), fileName);
824
+ const resolvedSandboxMode = resolveSandboxMode(sandbox);
825
+ const baseArgs = landscape ? ['--allow-file-access-from-files'] : [];
826
+ const primaryArgs = [...baseArgs, ...getSandboxArgs(resolvedSandboxMode, sandboxRuntime)];
827
+ const canRetryWithNoSandbox = resolvedSandboxMode === 'auto'
828
+ && !primaryArgs.includes('--no-sandbox');
829
+
830
+ try {
831
+ await renderPdfWithPuppeteer({
832
+ puppeteer,
833
+ launchArgs: primaryArgs,
834
+ html,
835
+ htmlPath,
836
+ pageSize,
837
+ landscape,
838
+ pdfPath,
839
+ });
840
+ } catch (primaryError) {
841
+ if (!canRetryWithNoSandbox) {
842
+ throw primaryError;
843
+ }
844
+
845
+ const fallbackArgs = [...baseArgs, ...SANDBOX_DISABLED_ARGS];
846
+ try {
847
+ await renderPdfWithPuppeteer({
848
+ puppeteer,
849
+ launchArgs: fallbackArgs,
850
+ html,
851
+ htmlPath,
852
+ pageSize,
853
+ landscape,
854
+ pdfPath,
855
+ });
856
+ warnings.push('sandbox_auto_retry_off');
857
+ } catch (fallbackError) {
858
+ throw new Error(
859
+ `PDF export failed in auto mode and fallback off mode: ${fallbackError.message} (auto error: ${primaryError.message})`,
860
+ );
861
+ }
812
862
  }
813
863
 
814
864
  const stat = await fs.stat(pdfPath);
package/src/mcp/server.js CHANGED
@@ -72,7 +72,7 @@ async function saveHtmlResult(html, outputDir, name = 'output') {
72
72
 
73
73
  const server = new McpServer({
74
74
  name: 'agent-reader',
75
- version: '1.1.1',
75
+ version: '1.1.2',
76
76
  });
77
77
 
78
78
  server.registerTool(