diff --git a/kura/types/conversation.py b/kura/types/conversation.py index e3cb25f..8c0181e 100644 --- a/kura/types/conversation.py +++ b/kura/types/conversation.py @@ -24,7 +24,9 @@ def from_claude_conversation_dump(cls, file_path: str) -> list["Conversation"]: created_at=conversation["created_at"], messages=[ Message( - created_at=message["created_at"], + created_at=datetime.fromisoformat( + message["created_at"].replace("Z", "+00:00") + ), role="user" if message["sender"] == "human" else "assistant", @@ -36,7 +38,15 @@ def from_claude_conversation_dump(cls, file_path: str) -> list["Conversation"]: ] ), ) - for message in conversation["chat_messages"] + for message in sorted( + conversation["chat_messages"], + key=lambda x: ( + datetime.fromisoformat( + x["created_at"].replace("Z", "+00:00") + ), + 0 if x["sender"] == "human" else 1, + ), + ) ], ) for conversation in json.load(f) diff --git a/ui/bun.lockb b/ui/bun.lockb index c66b3c9..029987e 100755 Binary files a/ui/bun.lockb and b/ui/bun.lockb differ diff --git a/ui/src/components/ChatDialog.tsx b/ui/src/components/ChatDialog.tsx index 4bb81af..752df48 100644 --- a/ui/src/components/ChatDialog.tsx +++ b/ui/src/components/ChatDialog.tsx @@ -1,5 +1,5 @@ import { Conversation } from "@/types/conversation"; -import React from "react"; + import { Dialog, DialogContent, @@ -8,6 +8,7 @@ import { DialogTitle, DialogTrigger, } from "./ui/dialog"; +import { Markdown } from "./markdown"; type Props = { chatId: string; @@ -36,13 +37,13 @@ const ChatDialog = ({ chatId, conversation }: Props) => { }`} >
{m.content}
+
+ {children}
+
+
+ {children}
+
+ );
+ }
+}
diff --git a/ui/src/components/markdown.tsx b/ui/src/components/markdown.tsx
new file mode 100644
index 0000000..ff3996f
--- /dev/null
+++ b/ui/src/components/markdown.tsx
@@ -0,0 +1,107 @@
+import { memo } from "react";
+import ReactMarkdown, { type Components } from "react-markdown";
+import remarkGfm from "remark-gfm";
+import { CodeBlock } from "./code-block";
+
+const components: Partial