@vint.tri/report_gen_mcp 1.5.44 → 1.5.48
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/dist/charts/index.d.ts +7 -0
- package/dist/charts/index.d.ts.map +1 -0
- package/dist/charts/index.js +6 -0
- package/dist/images/index.d.ts +4 -0
- package/dist/images/index.d.ts.map +1 -0
- package/dist/images/index.js +3 -0
- package/dist/images/pollinations.d.ts +2 -2
- package/dist/images/pollinations.d.ts.map +1 -1
- package/dist/images/pollinations.js +1 -1
- package/dist/images/urlImages.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/mcp/imageGenerationServer.d.ts.map +1 -1
- package/dist/mcp/imageGenerationServer.js +18 -5
- package/dist/mcp/index.d.ts +3 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +2 -0
- package/dist/tools/index.d.ts +4 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +3 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/reportGenerator.d.ts.map +1 -1
- package/dist/utils/reportGenerator.js +120 -9
- package/package.json +1 -1
- package/test_apple_report_fix.js +0 -93
- package/test_fix_verification.js +0 -44
- package/test_real_scenario.js +0 -45
- package/test_with_existing_image.js +0 -77
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/charts/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/images/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AACjI,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -10,8 +10,8 @@ export declare const generatedImageSchema: z.ZodObject<{
|
|
|
10
10
|
}, "strip", z.ZodTypeAny, {
|
|
11
11
|
width: number;
|
|
12
12
|
height: number;
|
|
13
|
-
prompt: string;
|
|
14
13
|
model: string;
|
|
14
|
+
prompt: string;
|
|
15
15
|
nologo: boolean;
|
|
16
16
|
enhance: boolean;
|
|
17
17
|
seed?: number | undefined;
|
|
@@ -43,5 +43,5 @@ export declare const imageUrlSchema: z.ZodObject<{
|
|
|
43
43
|
export declare function generateImageUrl(params: z.infer<typeof generatedImageSchema>): string;
|
|
44
44
|
export declare function renderGeneratedImage(params: z.infer<typeof generatedImageSchema>): Promise<string>;
|
|
45
45
|
export declare function renderImageUrl(params: z.infer<typeof imageUrlSchema>): Promise<string>;
|
|
46
|
-
export { generatedImageSchema as pollinationsImageSchema, renderGeneratedImage as renderPollinationsImage
|
|
46
|
+
export { generatedImageSchema as pollinationsImageSchema, renderGeneratedImage as renderPollinationsImage };
|
|
47
47
|
//# sourceMappingURL=pollinations.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pollinations.d.ts","sourceRoot":"","sources":["../../src/images/pollinations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;EAQ/B,CAAC;AAGH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;EAKzB,CAAC;AAGH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,GAAG,MAAM,CAgBrF;AAGD,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAUxG;AAGD,wBAAsB,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAc5F;AAED,OAAO,EACL,oBAAoB,IAAI,uBAAuB,EAC/C,oBAAoB,IAAI,uBAAuB,
|
|
1
|
+
{"version":3,"file":"pollinations.d.ts","sourceRoot":"","sources":["../../src/images/pollinations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;EAQ/B,CAAC;AAGH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;EAKzB,CAAC;AAGH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,GAAG,MAAM,CAgBrF;AAGD,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAUxG;AAGD,wBAAsB,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAc5F;AAED,OAAO,EACL,oBAAoB,IAAI,uBAAuB,EAC/C,oBAAoB,IAAI,uBAAuB,EAChD,CAAC"}
|
|
@@ -62,4 +62,4 @@ export async function renderImageUrl(params) {
|
|
|
62
62
|
</div>
|
|
63
63
|
`;
|
|
64
64
|
}
|
|
65
|
-
export { generatedImageSchema as pollinationsImageSchema, renderGeneratedImage as renderPollinationsImage
|
|
65
|
+
export { generatedImageSchema as pollinationsImageSchema, renderGeneratedImage as renderPollinationsImage };
|
|
@@ -7,8 +7,8 @@ export declare const urlImageSchema: z.ZodObject<{
|
|
|
7
7
|
embed: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
8
8
|
outputPath: z.ZodOptional<z.ZodString>;
|
|
9
9
|
}, "strip", z.ZodTypeAny, {
|
|
10
|
-
embed: boolean;
|
|
11
10
|
url: string;
|
|
11
|
+
embed: boolean;
|
|
12
12
|
alt?: string | undefined;
|
|
13
13
|
width?: number | undefined;
|
|
14
14
|
height?: number | undefined;
|
package/dist/index.js
CHANGED
|
@@ -109,7 +109,7 @@ if (process.argv.length === 2) {
|
|
|
109
109
|
// No command specified, run in stdio mode using MCP SDK
|
|
110
110
|
const mcpServer = new McpServer({
|
|
111
111
|
name: "report_gen_mcp",
|
|
112
|
-
version: "1.5.
|
|
112
|
+
version: "1.5.48"
|
|
113
113
|
}, {
|
|
114
114
|
// Disable health check to prevent automatic calls
|
|
115
115
|
capabilities: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"imageGenerationServer.d.ts","sourceRoot":"","sources":["../../src/mcp/imageGenerationServer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAeH,UAAU,uBAAuB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED,cAAM,cAAc;IAClB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,eAAe,CAA0B;;IAiBjD,OAAO,CAAC,aAAa;IAIf,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAE,OAAO,CAAC,uBAAuB,CAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAuE9G;
|
|
1
|
+
{"version":3,"file":"imageGenerationServer.d.ts","sourceRoot":"","sources":["../../src/mcp/imageGenerationServer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAeH,UAAU,uBAAuB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED,cAAM,cAAc;IAClB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,eAAe,CAA0B;;IAiBjD,OAAO,CAAC,aAAa;IAIf,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAE,OAAO,CAAC,uBAAuB,CAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAuE9G;AA8OD,iBAAe,IAAI,kBASlB;AAOD,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -204,7 +204,8 @@ app.registerTool("generate_image_to_file", {
|
|
|
204
204
|
guidance_scale: z.string().optional().describe("Сила следования промпту (1.0-20.0)"),
|
|
205
205
|
negative_prompt: z.string().optional().describe("Негативный промпт (что НЕ включать в изображение)"),
|
|
206
206
|
num_inference_steps: z.string().optional().describe("Количество шагов генерации (1-50)"),
|
|
207
|
-
seed: z.string().optional().describe("Seed для воспроизводимости (0 = случайный)")
|
|
207
|
+
seed: z.string().optional().describe("Seed для воспроизводимости (0 = случайный)"),
|
|
208
|
+
reportsDir: z.string().optional().describe("Директория отчетов, если используется HTTP сервер (для формирования относительного пути)")
|
|
208
209
|
},
|
|
209
210
|
}, async (args) => {
|
|
210
211
|
try {
|
|
@@ -212,6 +213,7 @@ app.registerTool("generate_image_to_file", {
|
|
|
212
213
|
const prompt = args.prompt || "";
|
|
213
214
|
const directory = args.directory || "";
|
|
214
215
|
const filename = args.filename || "";
|
|
216
|
+
const reportsDir = args.reportsDir || ""; // reportsDir from report_gen_mcp
|
|
215
217
|
if (!prompt) {
|
|
216
218
|
throw new Error("Параметр 'prompt' обязателен");
|
|
217
219
|
}
|
|
@@ -250,9 +252,13 @@ app.registerTool("generate_image_to_file", {
|
|
|
250
252
|
}
|
|
251
253
|
// Проверяем базовый каталог из переменной окружения
|
|
252
254
|
const baseSaveDirectory = process.env.IMG_SAVE_BASE_DIR || "";
|
|
253
|
-
|
|
255
|
+
let fullDirectory = baseSaveDirectory
|
|
254
256
|
? path.normalize(path.join(baseSaveDirectory, directory))
|
|
255
257
|
: path.normalize(directory);
|
|
258
|
+
// If reportsDir is provided, save relative to it for HTTP serving
|
|
259
|
+
if (reportsDir) {
|
|
260
|
+
fullDirectory = path.join(reportsDir, directory);
|
|
261
|
+
}
|
|
256
262
|
// Создаем каталог если не существует
|
|
257
263
|
await fs.ensureDir(fullDirectory);
|
|
258
264
|
// Формируем полный путь к файлу
|
|
@@ -260,14 +266,21 @@ app.registerTool("generate_image_to_file", {
|
|
|
260
266
|
// Сохраняем изображение
|
|
261
267
|
const imageBuffer = Buffer.from(base64Data, 'base64');
|
|
262
268
|
await fs.writeFile(outputPath, imageBuffer);
|
|
263
|
-
//
|
|
264
|
-
|
|
269
|
+
// Determine the URI to return
|
|
270
|
+
let finalUri = outputPath; // Default to local path
|
|
271
|
+
// If reportsDir was used, construct an HTTP-friendly relative path
|
|
272
|
+
if (reportsDir) {
|
|
273
|
+
const relativePath = path.relative(reportsDir, outputPath);
|
|
274
|
+
// Assuming the HTTP server serves reportsDir as its root for /reports
|
|
275
|
+
// The actual serverBaseUrl will be prepended by the caller (report_gen_mcp)
|
|
276
|
+
finalUri = `${directory.startsWith('/') ? '' : '/'}${path.join(directory, filename)}`;
|
|
277
|
+
}
|
|
265
278
|
// Возвращаем результат
|
|
266
279
|
return {
|
|
267
280
|
content: [
|
|
268
281
|
{
|
|
269
282
|
type: "text",
|
|
270
|
-
text: `✅ Изображение успешно сгенерировано и сохранено в '${outputPath}' (URI: ${
|
|
283
|
+
text: `✅ Изображение успешно сгенерировано и сохранено в '${outputPath}' (URI: ${finalUri})`
|
|
271
284
|
}
|
|
272
285
|
]
|
|
273
286
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,IAAI,uBAAuB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACvF,OAAO,EAAE,IAAI,IAAI,0BAA0B,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './reportGenerator.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reportGenerator.d.ts","sourceRoot":"","sources":["../../src/utils/reportGenerator.ts"],"names":[],"mappings":"AAKA,wBAAsB,cAAc,CAClC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"reportGenerator.d.ts","sourceRoot":"","sources":["../../src/utils/reportGenerator.ts"],"names":[],"mappings":"AAKA,wBAAsB,cAAc,CAClC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAmQ9C"}
|
|
@@ -22,10 +22,71 @@ export async function generateReport(htmlDocument, outputFile, serverBaseUrl) {
|
|
|
22
22
|
if (!head.querySelector('style')) {
|
|
23
23
|
const style = document.createElement('style');
|
|
24
24
|
style.textContent = `
|
|
25
|
-
body {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
body {
|
|
26
|
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
27
|
+
line-height: 1.6;
|
|
28
|
+
color: #333;
|
|
29
|
+
margin: 0;
|
|
30
|
+
padding: 40px;
|
|
31
|
+
background-color: #f4f7f6;
|
|
32
|
+
}
|
|
33
|
+
h1, h2, h3, h4, h5, h6 {
|
|
34
|
+
color: #2c3e50;
|
|
35
|
+
margin-top: 1.5em;
|
|
36
|
+
margin-bottom: 0.5em;
|
|
37
|
+
line-height: 1.2;
|
|
38
|
+
}
|
|
39
|
+
h1 { font-size: 2.5em; border-bottom: 2px solid #3498db; padding-bottom: 10px; }
|
|
40
|
+
h2 { font-size: 2em; color: #3498db; }
|
|
41
|
+
p {
|
|
42
|
+
margin-bottom: 1em;
|
|
43
|
+
}
|
|
44
|
+
.container {
|
|
45
|
+
max-width: 900px;
|
|
46
|
+
margin: 0 auto;
|
|
47
|
+
background-color: #ffffff;
|
|
48
|
+
padding: 30px;
|
|
49
|
+
border-radius: 8px;
|
|
50
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
|
51
|
+
}
|
|
52
|
+
.chart-container {
|
|
53
|
+
width: 100%;
|
|
54
|
+
max-width: 700px;
|
|
55
|
+
margin: 40px auto;
|
|
56
|
+
padding: 20px;
|
|
57
|
+
background-color: #fdfdfd;
|
|
58
|
+
border-radius: 8px;
|
|
59
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
|
60
|
+
}
|
|
61
|
+
img {
|
|
62
|
+
max-width: 100%;
|
|
63
|
+
height: auto;
|
|
64
|
+
display: block;
|
|
65
|
+
margin: 20px auto;
|
|
66
|
+
border-radius: 8px;
|
|
67
|
+
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
|
68
|
+
}
|
|
69
|
+
table {
|
|
70
|
+
width: 100%;
|
|
71
|
+
border-collapse: collapse;
|
|
72
|
+
margin: 20px 0;
|
|
73
|
+
}
|
|
74
|
+
th, td {
|
|
75
|
+
border: 1px solid #ddd;
|
|
76
|
+
padding: 10px;
|
|
77
|
+
text-align: left;
|
|
78
|
+
}
|
|
79
|
+
th {
|
|
80
|
+
background-color: #ecf0f1;
|
|
81
|
+
color: #2c3e50;
|
|
82
|
+
}
|
|
83
|
+
a {
|
|
84
|
+
color: #3498db;
|
|
85
|
+
text-decoration: none;
|
|
86
|
+
}
|
|
87
|
+
a:hover {
|
|
88
|
+
text-decoration: underline;
|
|
89
|
+
}
|
|
29
90
|
`;
|
|
30
91
|
head.appendChild(style);
|
|
31
92
|
}
|
|
@@ -53,15 +114,65 @@ export async function generateReport(htmlDocument, outputFile, serverBaseUrl) {
|
|
|
53
114
|
scriptTag.remove();
|
|
54
115
|
}
|
|
55
116
|
});
|
|
56
|
-
// 4. Process all img elements to handle local images
|
|
117
|
+
// 4. Process all img elements to handle local images or generate them
|
|
57
118
|
const images = document.querySelectorAll('img');
|
|
58
119
|
for (const img of Array.from(images)) {
|
|
59
120
|
const src = img.getAttribute('src');
|
|
60
|
-
|
|
61
|
-
|
|
121
|
+
const generatePrompt = img.getAttribute('data-generate-image'); // New attribute for AI generation
|
|
122
|
+
if (generatePrompt) {
|
|
123
|
+
// If data-generate-image attribute is present, try to generate image
|
|
124
|
+
try {
|
|
125
|
+
console.log(`Generating image for prompt: "${generatePrompt}"`);
|
|
126
|
+
// Use generate_image_to_file to get an HTTP link
|
|
127
|
+
const imageFileName = `generated-image-${Date.now()}.jpeg`; // Unique filename
|
|
128
|
+
const imageOutputDir = path.join(outputDirPath, 'generated_images'); // Save in a subfolder
|
|
129
|
+
const result = await use_mcp_tool('image-generator-ts', // The name of your image generation MCP server
|
|
130
|
+
'generate_image_to_file', {
|
|
131
|
+
prompt: generatePrompt,
|
|
132
|
+
directory: imageOutputDir,
|
|
133
|
+
filename: imageFileName
|
|
134
|
+
});
|
|
135
|
+
if (result && result.content && result.content[0] && result.content[0].text) {
|
|
136
|
+
// Extract the URL from the success message
|
|
137
|
+
const match = result.content[0].text.match(/URI:\s*(https?:\/\/.+)/);
|
|
138
|
+
if (match && match[1]) {
|
|
139
|
+
const httpUrl = match[1];
|
|
140
|
+
img.setAttribute('src', httpUrl);
|
|
141
|
+
img.removeAttribute('data-generate-image'); // Remove attribute after processing
|
|
142
|
+
console.log(`✅ Successfully generated image for prompt: "${generatePrompt}" and set HTTP source: ${httpUrl}`);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
console.warn(`⚠️ Failed to extract HTTP URL from image generation result:`, result.content[0].text);
|
|
146
|
+
// Fallback to placeholder if URL extraction fails
|
|
147
|
+
const width = img.getAttribute('width') ? parseInt(img.getAttribute('width')) : 300;
|
|
148
|
+
const height = img.getAttribute('height') ? parseInt(img.getAttribute('height')) : 200;
|
|
149
|
+
const placeholderSvg = `<svg width="${width}" height="${height}" xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="#f0f0f0"/><text x="50%" y="50%" font-family="Arial" font-size="16" fill="#666" text-anchor="middle" dy=".3em">Failed to get image URL</text></svg>`;
|
|
150
|
+
img.setAttribute('src', `data:image/svg+xml;base64,${Buffer.from(placeholderSvg).toString('base64')}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
console.warn(`⚠️ Failed to generate image for prompt: "${generatePrompt}". No valid result returned.`, JSON.stringify(result));
|
|
155
|
+
// Fallback to placeholder if generation fails or returns no data
|
|
156
|
+
const width = img.getAttribute('width') ? parseInt(img.getAttribute('width')) : 300;
|
|
157
|
+
const height = img.getAttribute('height') ? parseInt(img.getAttribute('height')) : 200;
|
|
158
|
+
const placeholderSvg = `<svg width="${width}" height="${height}" xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="#f0f0f0"/><text x="50%" y="50%" font-family="Arial" font-size="16" fill="#666" text-anchor="middle" dy=".3em">Image generation failed</text></svg>`;
|
|
159
|
+
img.setAttribute('src', `data:image/svg+xml;base64,${Buffer.from(placeholderSvg).toString('base64')}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
console.error(`❌ Error generating image for prompt "${generatePrompt}":`, error);
|
|
164
|
+
// Fallback to placeholder if an error occurs during generation
|
|
165
|
+
const width = img.getAttribute('width') ? parseInt(img.getAttribute('width')) : 300;
|
|
166
|
+
const height = img.getAttribute('height') ? parseInt(img.getAttribute('height')) : 200;
|
|
167
|
+
const placeholderSvg = `<svg width="${width}" height="${height}" xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="#f0f0f0"/><text x="50%" y="50%" font-family="Arial" font-size="16" fill="#666" text-anchor="middle" dy=".3em">Error during generation</text></svg>`;
|
|
168
|
+
img.setAttribute('src', `data:image/svg+xml;base64,${Buffer.from(placeholderSvg).toString('base64')}`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
else if (src) {
|
|
172
|
+
// Process existing local images if no generation prompt is given
|
|
173
|
+
// Check if it's a local file (not a URL or data URI)
|
|
62
174
|
if (!src.startsWith('http://') && !src.startsWith('https://') && !src.startsWith('data:')) {
|
|
63
175
|
try {
|
|
64
|
-
// Try to read the image file first
|
|
65
176
|
const imageSourcePath = path.resolve(process.cwd(), src);
|
|
66
177
|
await fs.access(imageSourcePath); // This will throw if file doesn't exist
|
|
67
178
|
// If file exists, process it normally
|
|
@@ -92,7 +203,7 @@ export async function generateReport(htmlDocument, outputFile, serverBaseUrl) {
|
|
|
92
203
|
}
|
|
93
204
|
}
|
|
94
205
|
catch (error) {
|
|
95
|
-
console.warn(
|
|
206
|
+
console.warn(`⚠️ Failed to process local image ${src}:`, error);
|
|
96
207
|
// If file doesn't exist or processing fails, keep original src
|
|
97
208
|
// This allows the browser to potentially load the image if it becomes available
|
|
98
209
|
// or handle it according to its own fallback mechanisms
|
package/package.json
CHANGED
package/test_apple_report_fix.js
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { generateReport } from './dist/utils/reportGenerator.js';
|
|
2
|
-
import fs from 'fs-extra';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
|
|
5
|
-
async function testAppleReportFix() {
|
|
6
|
-
// Create a test HTML similar to your Apple report
|
|
7
|
-
const htmlContent = `
|
|
8
|
-
<!DOCTYPE html>
|
|
9
|
-
<html>
|
|
10
|
-
<head>
|
|
11
|
-
<title>Отчет о прибылях Apple за 2024 год</title>
|
|
12
|
-
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
13
|
-
<style>
|
|
14
|
-
body { font-family: Arial, sans-serif; padding: 20px; }
|
|
15
|
-
h1, h2 { color: #1a5276; }
|
|
16
|
-
img { max-width: 100%; height: auto; display: block; margin: 20px auto; }
|
|
17
|
-
</style>
|
|
18
|
-
</head>
|
|
19
|
-
<body>
|
|
20
|
-
<h1>Отчет о прибылях Apple за 2024 год</h1>
|
|
21
|
-
<p>В 2024 году компания Apple показала значительный рост прибыли по сравнению с предыдущими годами.</p>
|
|
22
|
-
|
|
23
|
-
<h2>График прибыли</h2>
|
|
24
|
-
<img src="profit_chart.png" alt="График прибыли">
|
|
25
|
-
|
|
26
|
-
<h2>Данные по кварталам</h2>
|
|
27
|
-
<canvas id="quarterlyChart" width="400" height="200"></canvas>
|
|
28
|
-
<script>
|
|
29
|
-
var ctx = document.getElementById('quarterlyChart').getContext('2d');
|
|
30
|
-
var quarterlyChart = new Chart(ctx, {
|
|
31
|
-
type: 'bar',
|
|
32
|
-
data: {
|
|
33
|
-
labels: ['Q1', 'Q2', 'Q3', 'Q4'],
|
|
34
|
-
datasets: [{
|
|
35
|
-
label: 'Прибыль (млрд $)',
|
|
36
|
-
data: [25.2, 28.5, 32.1, 35.8],
|
|
37
|
-
backgroundColor: 'rgba(54, 162, 235, 0.6)'
|
|
38
|
-
}]
|
|
39
|
-
},
|
|
40
|
-
options: {
|
|
41
|
-
scales: {
|
|
42
|
-
y: {
|
|
43
|
-
beginAtZero: true
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
</script>
|
|
49
|
-
|
|
50
|
-
<p>Как видно из графика, прибыль компании увеличилась на 15% по сравнению с 2023 годом.</p>
|
|
51
|
-
</body>
|
|
52
|
-
</html>`;
|
|
53
|
-
|
|
54
|
-
// Generate report with server base URL (simulating MCP server mode)
|
|
55
|
-
const outputPath = path.resolve('.', 'apple_report_fixed.html');
|
|
56
|
-
const serverBaseUrl = 'http://localhost:55453/reports';
|
|
57
|
-
|
|
58
|
-
console.log('Testing Apple report generation with missing image...');
|
|
59
|
-
const result = await generateReport(htmlContent, outputPath, serverBaseUrl);
|
|
60
|
-
|
|
61
|
-
// Read the generated report
|
|
62
|
-
const generatedContent = fs.readFileSync(outputPath, 'utf8');
|
|
63
|
-
|
|
64
|
-
console.log('Generated report saved to:', result.filePath);
|
|
65
|
-
console.log('\nChecking results...');
|
|
66
|
-
|
|
67
|
-
// Check if the report contains the expected elements
|
|
68
|
-
if (generatedContent.includes('data:image/svg+xml;base64')) {
|
|
69
|
-
console.log('✅ SUCCESS: Missing profit_chart.png converted to SVG placeholder');
|
|
70
|
-
} else {
|
|
71
|
-
console.log('❌ FAILED: Missing image not handled properly');
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Check if chart processing worked
|
|
75
|
-
if (generatedContent.includes('data-chart-script')) {
|
|
76
|
-
console.log('✅ SUCCESS: Quarterly chart processed correctly');
|
|
77
|
-
} else {
|
|
78
|
-
console.log('❌ FAILED: Charts not processed');
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Check if HTTP URL was generated for the report
|
|
82
|
-
if (generatedContent.includes(serverBaseUrl)) {
|
|
83
|
-
console.log('✅ SUCCESS: Server base URL applied correctly');
|
|
84
|
-
} else {
|
|
85
|
-
console.log('ℹ️ INFO: No HTTP URLs needed (using base64 fallback)');
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
console.log('\n✅ Test completed successfully!');
|
|
89
|
-
console.log('Open the generated file in browser to verify:');
|
|
90
|
-
console.log(result.filePath);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
testAppleReportFix().catch(console.error);
|
package/test_fix_verification.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { generateReport } from './dist/utils/reportGenerator.js';
|
|
2
|
-
import fs from 'fs-extra';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
|
|
5
|
-
async function testFix() {
|
|
6
|
-
// Read the test HTML file with missing image
|
|
7
|
-
const htmlContent = fs.readFileSync('test_missing_image.html', 'utf8');
|
|
8
|
-
|
|
9
|
-
// Generate report with server base URL (simulating MCP server mode)
|
|
10
|
-
const outputPath = path.resolve('.', 'test_fix_output.html');
|
|
11
|
-
const serverBaseUrl = 'http://localhost:3000/reports';
|
|
12
|
-
|
|
13
|
-
console.log('Testing report generation with missing image...');
|
|
14
|
-
const result = await generateReport(htmlContent, outputPath, serverBaseUrl);
|
|
15
|
-
|
|
16
|
-
// Read the generated report
|
|
17
|
-
const generatedContent = fs.readFileSync(outputPath, 'utf8');
|
|
18
|
-
|
|
19
|
-
console.log('Generated report saved to:', result.filePath);
|
|
20
|
-
console.log('\nChecking results...');
|
|
21
|
-
|
|
22
|
-
// Check if the report contains the expected elements
|
|
23
|
-
if (generatedContent.includes('data:image')) {
|
|
24
|
-
console.log('✅ SUCCESS: Missing image converted to base64 fallback');
|
|
25
|
-
} else if (generatedContent.includes('nonexistent_image.png')) {
|
|
26
|
-
console.log('❌ FAILED: Image still using original path');
|
|
27
|
-
} else {
|
|
28
|
-
console.log('⚠️ UNKNOWN: Image handling result unclear');
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Check if chart processing worked
|
|
32
|
-
if (generatedContent.includes('data-chart-script')) {
|
|
33
|
-
console.log('✅ SUCCESS: Charts processed correctly');
|
|
34
|
-
} else {
|
|
35
|
-
console.log('❌ FAILED: Charts not processed');
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
console.log('\nGenerated HTML preview:');
|
|
39
|
-
console.log('======================');
|
|
40
|
-
// Show first 1000 characters to avoid overwhelming output
|
|
41
|
-
console.log(generatedContent.substring(0, 1000) + (generatedContent.length > 1000 ? '...' : ''));
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
testFix().catch(console.error);
|
package/test_real_scenario.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { generateReport } from './dist/utils/reportGenerator.js';
|
|
2
|
-
import fs from 'fs-extra';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
|
|
5
|
-
async function testRealScenario() {
|
|
6
|
-
// Read the real Apple report file
|
|
7
|
-
const htmlContent = fs.readFileSync('Apple_Profit_Report_2024.html', 'utf8');
|
|
8
|
-
|
|
9
|
-
// Generate report with server base URL (like in your real case)
|
|
10
|
-
const outputPath = path.resolve('.', 'real_scenario_test.html');
|
|
11
|
-
const serverBaseUrl = 'http://localhost:55453/reports';
|
|
12
|
-
|
|
13
|
-
console.log('Testing real scenario with server base URL...');
|
|
14
|
-
const result = await generateReport(htmlContent, outputPath, serverBaseUrl);
|
|
15
|
-
|
|
16
|
-
// Read the generated report
|
|
17
|
-
const generatedContent = fs.readFileSync(outputPath, 'utf8');
|
|
18
|
-
|
|
19
|
-
console.log('Generated report saved to:', result.filePath);
|
|
20
|
-
console.log('\nChecking results...');
|
|
21
|
-
|
|
22
|
-
// Check if the report contains HTTP links
|
|
23
|
-
if (generatedContent.includes(serverBaseUrl)) {
|
|
24
|
-
console.log('✅ SUCCESS: Images converted to HTTP links');
|
|
25
|
-
} else if (generatedContent.includes('profit_chart.png')) {
|
|
26
|
-
console.log('ℹ️ INFO: Images kept original paths (file not found case)');
|
|
27
|
-
} else {
|
|
28
|
-
console.log('⚠️ UNKNOWN: Image handling result unclear');
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Check if chart processing worked
|
|
32
|
-
if (generatedContent.includes('data-chart-script')) {
|
|
33
|
-
console.log('✅ SUCCESS: Charts processed correctly');
|
|
34
|
-
} else {
|
|
35
|
-
console.log('❌ FAILED: Charts not processed');
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
console.log('\nGenerated HTML preview (first 800 chars):');
|
|
39
|
-
console.log('===========================================');
|
|
40
|
-
console.log(generatedContent.substring(0, 800) + (generatedContent.length > 800 ? '...' : ''));
|
|
41
|
-
|
|
42
|
-
console.log('\n✅ Real scenario test completed!');
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
testRealScenario().catch(console.error);
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { generateReport } from './dist/utils/reportGenerator.js';
|
|
2
|
-
import fs from 'fs-extra';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
|
|
5
|
-
async function testWithExistingImage() {
|
|
6
|
-
// Create a test image file
|
|
7
|
-
const testImagePath = 'test_image.png';
|
|
8
|
-
try {
|
|
9
|
-
// Try to copy an existing image or create a simple one
|
|
10
|
-
if (fs.existsSync('apple_logo_chart.png')) {
|
|
11
|
-
fs.copyFileSync('apple_logo_chart.png', testImagePath);
|
|
12
|
-
console.log('✅ Copied existing image for test');
|
|
13
|
-
} else {
|
|
14
|
-
// Create a simple test image (1x1 pixel PNG)
|
|
15
|
-
const testImageData = Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==', 'base64');
|
|
16
|
-
fs.writeFileSync(testImagePath, testImageData);
|
|
17
|
-
console.log('✅ Created simple test image');
|
|
18
|
-
}
|
|
19
|
-
} catch (error) {
|
|
20
|
-
console.log('⚠️ Could not create test image:', error.message);
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// Create HTML with existing image
|
|
25
|
-
const htmlContent = `
|
|
26
|
-
<!DOCTYPE html>
|
|
27
|
-
<html>
|
|
28
|
-
<head>
|
|
29
|
-
<title>Test with existing image</title>
|
|
30
|
-
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
31
|
-
</head>
|
|
32
|
-
<body>
|
|
33
|
-
<h1>Test Report with Existing Image</h1>
|
|
34
|
-
<img src="${testImagePath}" alt="Test Image" width="100" height="100">
|
|
35
|
-
<p>This image should be converted to base64 or HTTP link.</p>
|
|
36
|
-
</body>
|
|
37
|
-
</html>`;
|
|
38
|
-
|
|
39
|
-
// Test 1: Without serverBaseUrl (should convert to base64)
|
|
40
|
-
console.log('\n--- Test 1: Convert to base64 ---');
|
|
41
|
-
const outputPath1 = path.resolve('.', 'test_base64.html');
|
|
42
|
-
const result1 = await generateReport(htmlContent, outputPath1);
|
|
43
|
-
|
|
44
|
-
const generatedContent1 = fs.readFileSync(outputPath1, 'utf8');
|
|
45
|
-
if (generatedContent1.includes('data:image')) {
|
|
46
|
-
console.log('✅ SUCCESS: Image converted to base64');
|
|
47
|
-
} else {
|
|
48
|
-
console.log('❌ FAILED: Image not converted to base64');
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Test 2: With serverBaseUrl (should create HTTP link)
|
|
52
|
-
console.log('\n--- Test 2: Convert to HTTP link ---');
|
|
53
|
-
const outputPath2 = path.resolve('.', 'test_http_link.html');
|
|
54
|
-
const serverBaseUrl = 'http://localhost:3000/reports';
|
|
55
|
-
const result2 = await generateReport(htmlContent, outputPath2, serverBaseUrl);
|
|
56
|
-
|
|
57
|
-
const generatedContent2 = fs.readFileSync(outputPath2, 'utf8');
|
|
58
|
-
if (generatedContent2.includes(serverBaseUrl)) {
|
|
59
|
-
console.log('✅ SUCCESS: Image converted to HTTP link');
|
|
60
|
-
} else if (generatedContent2.includes('data:image')) {
|
|
61
|
-
console.log('ℹ️ INFO: Image converted to base64 (fallback)');
|
|
62
|
-
} else {
|
|
63
|
-
console.log('❌ FAILED: Image not processed correctly');
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Clean up test image
|
|
67
|
-
try {
|
|
68
|
-
fs.unlinkSync(testImagePath);
|
|
69
|
-
console.log('✅ Cleaned up test image');
|
|
70
|
-
} catch (error) {
|
|
71
|
-
console.log('⚠️ Could not clean up test image:', error.message);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
console.log('\n✅ All tests completed!');
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
testWithExistingImage().catch(console.error);
|