1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2025-04-10 04:36:38 +00:00

Basic support for importing ChatGPT archives

This commit is contained in:
Jeremy Ruston 2024-07-14 21:16:11 +01:00
parent e00c761088
commit d652f820b8
5 changed files with 182 additions and 1 deletions

View File

@ -0,0 +1,87 @@
/*\
title: $:/plugins/tiddlywiki/ai-tools/modules/conversations-archive-importer.js
type: application/javascript
module-type: library
Conversations archive importer
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
function ConversationsArchiveImporter() {
}
ConversationsArchiveImporter.prototype.import = function(widget,conversationsTitle) {
var logger = new $tw.utils.Logger("ai-tools");
var jsonConversations = widget.wiki.getTiddlerData(conversationsTitle,[]);
var tiddlers = [];
$tw.utils.each(jsonConversations,function(jsonConversation) {
var conversationTitle = (jsonConversation.title || "Untitled") + " (" + jsonConversation.conversation_id + ")",
conversationCreated = convertDate(jsonConversation.create_time),
conversationModified = convertDate(jsonConversation.update_time);
var conversationFields = {
title: conversationTitle,
tags: $tw.utils.stringifyList(["$:/tags/AI/Conversation"]),
created: conversationCreated,
modified: conversationModified
};
tiddlers.push(conversationFields);
var messageIndex = 1;
$tw.utils.each(jsonConversation.mapping,function(jsonMessage,messageId) {
// Skip messages where "message" is null
if(jsonMessage.message) {
var messageFields = {
title: conversationTitle + " " + (messageIndex + 1),
created: convertDate(jsonMessage.message.create_time) || conversationCreated,
modified: convertDate(jsonMessage.message.update_time) || conversationModified,
tags: $tw.utils.stringifyList([conversationTitle]),
role: jsonMessage.message.author.role,
"message-type": jsonMessage.message.content.content_type
}
switch(jsonMessage.message.content.content_type) {
case "code":
messageFields.text = jsonMessage.message.content.text;
messageFields.type = "text/plain";
break;
case "execution_output":
messageFields.text = jsonMessage.message.content.text;
messageFields.type = "text/plain";
break;
case "system_error":
messageFields.text = jsonMessage.message.content.text;
messageFields.type = "text/plain";
break;
case "text":
messageFields.text = jsonMessage.message.content.parts.join("");
messageFields.type = "text/markdown";
break;
default:
messageFields.text = JSON.stringify(jsonMessage.message,null,4);
messageFields.type = "text/plain";
break;
}
tiddlers.push(messageFields);
messageIndex += 1;
}
});
});
// Create summary tiddler
$tw.utils.each(tiddlers,function(tidder) {
});
// Create the tiddlers
widget.wiki.addTiddlers(tiddlers);
// widget.dispatchEvent({type: "tm-import-tiddlers", param: JSON.stringify(tiddlers)});
};
function convertDate(unixTimestamp) {
return $tw.utils.stringifyDate(new Date(unixTimestamp * 1000));
}
exports.ConversationsArchiveImporter = ConversationsArchiveImporter;
})();

View File

@ -0,0 +1,30 @@
/*\
title: $:/plugins/tiddlywiki/ai-tools/modules/startup.js
type: application/javascript
module-type: startup
Setup the root widget event handlers
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
// Export name and synchronous status
exports.name = "ai-tools";
exports.platforms = ["browser"];
exports.after = ["startup"];
exports.synchronous = true;
// Install the root widget event handlers
exports.startup = function() {
var ConversationsArchiveImporter = require("$:/plugins/tiddlywiki/ai-tools/modules/conversations-archive-importer.js").ConversationsArchiveImporter;
$tw.conversationsArchiveImporter = new ConversationsArchiveImporter();
$tw.rootWidget.addEventListener("tm-import-conversations",function(event) {
$tw.conversationsArchiveImporter.import(event.widget,event.param);
});
};
})();

View File

@ -2,6 +2,6 @@
"title": "$:/plugins/tiddlywiki/ai-tools",
"name": "AI Tools",
"description": "AI Tools for TiddlyWiki",
"list": "readme docs settings",
"list": "readme docs tools settings",
"stability": "STABILITY_1_EXPERIMENTAL"
}

View File

@ -0,0 +1,19 @@
title: $:/plugins/tiddlywiki/ai-tools/tools
! Import ~ChatGPT Export Archive
Any tiddlers containing ~ChatGPT exported `conversation.json` files will be shown here for import.
<$list filter="[all[tiddlers+shadows]type[application/json]sort[title]]" template="$:/plugins/tiddlywiki/ai-tools/view-templates/imported-conversations-json"/>
! Loaded Conversations
<ul>
<$list filter="[all[tiddlers+shadows]tag[$:/tags/AI/Conversation]sort[title]]">
<li>
<$link>
<$text text=<<currentTiddler>>/>
</$link>
</li>
</$list>
</ul>

View File

@ -0,0 +1,45 @@
title: $:/plugins/tiddlywiki/ai-tools/view-templates/imported-conversations-json
tags: $:/tags/ViewTemplate
list-before: $:/core/ui/ViewTemplate/body
\whitespace trim
\procedure importer()
<p>
<div>
<$link>
<$text text=`$(currentTiddler)$ appears to be a ChatGPT export containing $(numberOfConversations)$ conversations`/>
</$link>
</div>
<div>
<$button>
<$action-sendmessage $message="tm-import-conversations" $param=<<currentTiddler>>/>
{{$:/core/images/input-button}} Import
</$button>
</div>
</p>
\end importer
<%if [<currentTiddler>type[application/json]] %>
<$let json={{{ [<currentTiddler>get[text]] }}} >
<%if [<json>jsontype[]match[array]] %>
<$let
numberOfConversations={{{ [<json>jsonindexes[]count[]] }}}
json={{{ [<json>jsonextract[0]] }}}
>
<%if [<json>jsontype[]match[object]] %>
<%if
[<json>jsontype[title]match[string]]
:and[<json>jsontype[create_time]match[number]]
:and[<json>jsontype[update_time]match[number]]
:and[<json>jsontype[mapping]match[object]]
:and[<json>jsontype[id]match[string]]
%>
<<importer>>
<%endif%>
<%endif%>
</$let>
<%endif%>
</$let>
<%endif%>