chatgpt-to-markdown 1.5.2 → 1.5.4
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 +2 -0
- package/cli.js +4 -9
- package/index.js +11 -4
- package/index.test.js +134 -0
- package/package.json +1 -1
package/README.md
CHANGED
@@ -97,6 +97,8 @@ git push --follow-tags
|
|
97
97
|
|
98
98
|
## Release notes
|
99
99
|
|
100
|
+
- 1.5.4: 02 Nov 2024. Skip `user_editable_context` to avoid polluting Markdown with custom instructions
|
101
|
+
- 1.5.3: 05 Aug 2024. Show text from multimodal prompts
|
100
102
|
- 1.5.2: 05 Aug 2024. Show tether_browsing_display summary
|
101
103
|
- 1.5.1: 22 Mar 2024. Handle unicode filenames
|
102
104
|
- 1.5.0: 28 Nov 2023. Handle `tether_browsing_display`, `tether_quote` and `system_error`
|
package/cli.js
CHANGED
@@ -10,15 +10,10 @@ async function run() {
|
|
10
10
|
process.exit(1);
|
11
11
|
}
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
await chatgptToMarkdown(json, sourceDir);
|
18
|
-
} catch (err) {
|
19
|
-
console.error("Error:", err.message);
|
20
|
-
process.exit(1);
|
21
|
-
}
|
13
|
+
const data = await fs.readFile(filePath, "utf8");
|
14
|
+
const json = JSON.parse(data);
|
15
|
+
const sourceDir = path.dirname(filePath);
|
16
|
+
await chatgptToMarkdown(json, sourceDir);
|
22
17
|
}
|
23
18
|
|
24
19
|
run();
|
package/index.js
CHANGED
@@ -34,7 +34,7 @@ function wrapHtmlTagsInBackticks(text) {
|
|
34
34
|
function indent(str) {
|
35
35
|
return str
|
36
36
|
.split("\n")
|
37
|
-
.map((v) => ` ${v}\n`)
|
37
|
+
.map((v) => (v.trim() ? ` ${v}\n` : ""))
|
38
38
|
.join("");
|
39
39
|
}
|
40
40
|
|
@@ -96,9 +96,11 @@ async function chatgptToMarkdown(json, sourceDir, { dateFormat } = { dateFormat:
|
|
96
96
|
case "multimodal_text":
|
97
97
|
body = content.parts
|
98
98
|
.map((part) =>
|
99
|
-
part
|
100
|
-
?
|
101
|
-
:
|
99
|
+
typeof part == "string"
|
100
|
+
? `${part}\n\n`
|
101
|
+
: part.content_type === "image_asset_pointer"
|
102
|
+
? `Image (${part.width}x${part.height}): ${part?.metadata?.dalle?.prompt ?? ""}\n\n`
|
103
|
+
: `${part.content_type}\n\n`,
|
102
104
|
)
|
103
105
|
.join("");
|
104
106
|
break;
|
@@ -111,6 +113,11 @@ async function chatgptToMarkdown(json, sourceDir, { dateFormat } = { dateFormat:
|
|
111
113
|
case "system_error":
|
112
114
|
body = `${content.name}\n\n${content.text}\n\n`;
|
113
115
|
break;
|
116
|
+
case "user_editable_context":
|
117
|
+
// We don't want to pollute all Markdown with custom instuctions
|
118
|
+
// in content.user_instructions. So skip it
|
119
|
+
body = "";
|
120
|
+
break;
|
114
121
|
default:
|
115
122
|
body = content;
|
116
123
|
break;
|
package/index.test.js
CHANGED
@@ -226,4 +226,138 @@ describe("chatgptToMarkdown", () => {
|
|
226
226
|
const fileContent = await fs.readFile(path.join(tempDir, "Test Conversation.md"), "utf8");
|
227
227
|
expect(fileContent).toContain('```javascript\nconsole.log("Hello, world!");\n```\n');
|
228
228
|
});
|
229
|
+
|
230
|
+
it("should skip user_editable_context content", async () => {
|
231
|
+
const json = [
|
232
|
+
{
|
233
|
+
title: "Test Conversation",
|
234
|
+
create_time: 1630454400,
|
235
|
+
update_time: 1630458000,
|
236
|
+
mapping: {
|
237
|
+
0: {
|
238
|
+
message: {
|
239
|
+
author: { role: "user" },
|
240
|
+
content: {
|
241
|
+
content_type: "user_editable_context",
|
242
|
+
user_profile: "test profile",
|
243
|
+
user_instructions: "test instructions",
|
244
|
+
},
|
245
|
+
},
|
246
|
+
},
|
247
|
+
},
|
248
|
+
},
|
249
|
+
];
|
250
|
+
await chatgptToMarkdown(json, tempDir);
|
251
|
+
const fileContent = await fs.readFile(path.join(tempDir, "Test Conversation.md"), "utf8");
|
252
|
+
expect(fileContent).not.toContain("test profile");
|
253
|
+
expect(fileContent).not.toContain("test instructions");
|
254
|
+
});
|
255
|
+
|
256
|
+
it("should handle system_error content", async () => {
|
257
|
+
const json = [
|
258
|
+
{
|
259
|
+
title: "Test Conversation",
|
260
|
+
create_time: 1630454400,
|
261
|
+
update_time: 1630458000,
|
262
|
+
mapping: {
|
263
|
+
0: {
|
264
|
+
message: {
|
265
|
+
author: { role: "system" },
|
266
|
+
content: {
|
267
|
+
content_type: "system_error",
|
268
|
+
name: "Error Name",
|
269
|
+
text: "Error details",
|
270
|
+
},
|
271
|
+
},
|
272
|
+
},
|
273
|
+
},
|
274
|
+
},
|
275
|
+
];
|
276
|
+
|
277
|
+
await chatgptToMarkdown(json, tempDir);
|
278
|
+
const fileContent = await fs.readFile(path.join(tempDir, "Test Conversation.md"), "utf8");
|
279
|
+
expect(fileContent).toContain("Error Name\n\nError details\n\n");
|
280
|
+
});
|
281
|
+
|
282
|
+
it("should handle execution_output content", async () => {
|
283
|
+
const json = [
|
284
|
+
{
|
285
|
+
title: "Test Conversation",
|
286
|
+
create_time: 1630454400,
|
287
|
+
update_time: 1630458000,
|
288
|
+
mapping: {
|
289
|
+
0: {
|
290
|
+
message: {
|
291
|
+
author: { role: "assistant" },
|
292
|
+
content: {
|
293
|
+
content_type: "execution_output",
|
294
|
+
text: "Program output",
|
295
|
+
},
|
296
|
+
},
|
297
|
+
},
|
298
|
+
},
|
299
|
+
},
|
300
|
+
];
|
301
|
+
|
302
|
+
await chatgptToMarkdown(json, tempDir);
|
303
|
+
const fileContent = await fs.readFile(path.join(tempDir, "Test Conversation.md"), "utf8");
|
304
|
+
expect(fileContent).toContain("```\nProgram output\n```");
|
305
|
+
});
|
306
|
+
|
307
|
+
it("should handle code content with unknown language", async () => {
|
308
|
+
const json = [
|
309
|
+
{
|
310
|
+
title: "Test Conversation",
|
311
|
+
create_time: 1630454400,
|
312
|
+
update_time: 1630458000,
|
313
|
+
mapping: {
|
314
|
+
0: {
|
315
|
+
message: {
|
316
|
+
author: { role: "assistant" },
|
317
|
+
content: {
|
318
|
+
content_type: "code",
|
319
|
+
language: "unknown",
|
320
|
+
text: "some code",
|
321
|
+
},
|
322
|
+
},
|
323
|
+
},
|
324
|
+
},
|
325
|
+
},
|
326
|
+
];
|
327
|
+
|
328
|
+
await chatgptToMarkdown(json, tempDir);
|
329
|
+
const fileContent = await fs.readFile(path.join(tempDir, "Test Conversation.md"), "utf8");
|
330
|
+
expect(fileContent).toContain("```\nsome code\n```");
|
331
|
+
});
|
332
|
+
|
333
|
+
it("should handle tether_browsing_display with summary", async () => {
|
334
|
+
const json = [
|
335
|
+
{
|
336
|
+
title: "Test Conversation",
|
337
|
+
create_time: 1630454400,
|
338
|
+
update_time: 1630458000,
|
339
|
+
mapping: {
|
340
|
+
0: {
|
341
|
+
message: {
|
342
|
+
author: { role: "tool" },
|
343
|
+
content: {
|
344
|
+
content_type: "tether_browsing_display",
|
345
|
+
summary: "Page Summary",
|
346
|
+
result: "Search Result",
|
347
|
+
},
|
348
|
+
},
|
349
|
+
},
|
350
|
+
},
|
351
|
+
},
|
352
|
+
];
|
353
|
+
|
354
|
+
await chatgptToMarkdown(json, tempDir);
|
355
|
+
const fileContent = await fs.readFile(path.join(tempDir, "Test Conversation.md"), "utf8");
|
356
|
+
expect(fileContent).toContain("```\nPage Summary\nSearch Result\n```");
|
357
|
+
});
|
358
|
+
|
359
|
+
it("should throw TypeError for invalid arguments", async () => {
|
360
|
+
await expect(chatgptToMarkdown("not an array", tempDir)).rejects.toThrow(TypeError);
|
361
|
+
await expect(chatgptToMarkdown([], 123)).rejects.toThrow(TypeError);
|
362
|
+
});
|
229
363
|
});
|