70 lines
1.9 KiB
Python
70 lines
1.9 KiB
Python
from pathlib import Path
|
|
from datetime import datetime
|
|
import re
|
|
import yaml
|
|
|
|
def slug(text):
|
|
text = re.sub(r"[^\w\s-]", "", text.lower(), flags=re.UNICODE)
|
|
return re.sub(r"[\s_-]+", "-", text).strip("-") or "chat"
|
|
|
|
def chat_path(directory, title):
|
|
directory.mkdir(parents=True, exist_ok=True)
|
|
path = directory / f"{datetime.now():%Y-%m-%d}-{slug(title)}.md"
|
|
number = 2
|
|
|
|
while path.exists():
|
|
path = directory / f"{datetime.now():%Y-%m-%d}-{slug(title)}-{number}.md"
|
|
number += 1
|
|
|
|
return path
|
|
|
|
def save(path, title, messages, model):
|
|
meta = {
|
|
"title": title,
|
|
"created": datetime.now().astimezone().isoformat(),
|
|
"model": model,
|
|
}
|
|
|
|
out = [
|
|
"---",
|
|
yaml.safe_dump(meta, allow_unicode=True, sort_keys=False).strip(),
|
|
"---",
|
|
"",
|
|
]
|
|
|
|
for message in messages:
|
|
role = "You" if message["role"] == "user" else "AI"
|
|
out += [f"## {role}", "", message["content"].rstrip(), ""]
|
|
|
|
path.write_text("\n".join(out), encoding="utf-8")
|
|
|
|
def load(path):
|
|
text = path.read_text(encoding="utf-8")
|
|
title = path.stem
|
|
|
|
if text.startswith("---"):
|
|
_, meta, body = text.split("---", 2)
|
|
title = (yaml.safe_load(meta) or {}).get("title", title)
|
|
text = body
|
|
|
|
messages = []
|
|
role = None
|
|
buffer = []
|
|
|
|
for line in text.splitlines():
|
|
if line == "## You":
|
|
if role:
|
|
messages.append({"role": role, "content": "\n".join(buffer).strip()})
|
|
role, buffer = "user", []
|
|
elif line == "## AI":
|
|
if role:
|
|
messages.append({"role": role, "content": "\n".join(buffer).strip()})
|
|
role, buffer = "assistant", []
|
|
elif role:
|
|
buffer.append(line)
|
|
|
|
if role:
|
|
messages.append({"role": role, "content": "\n".join(buffer).strip()})
|
|
|
|
return title, [m for m in messages if m["content"]]
|