PromtGarageMac / Sources /PromptGarageCore /Import /GeminiJSONLParser.swift
smlflg's picture
Initial public upload from Projekte/PromtGarageMac
4977db2 verified
Raw History Blame Contribute Delete
2.39 kB
import Foundation
struct GeminiJSONLParser: ImportParser {
func parse(sourceURL: URL, dedupIndex: DedupIndex) throws -> ImportParseResult {
let files = try ImportFiles.immediateFiles(
at: sourceURL,
expected: "eine Gemini-.jsonl-Datei oder einen Ordner mit .jsonl-Dateien",
directFileMatches: { $0.pathExtension.lowercased() == "jsonl" },
directoryFileMatches: { $0.pathExtension.lowercased() == "jsonl" }
)
var accumulator = ImportAccumulator(
minimumLength: 20,
maximumLength: 10_000,
dedupIndex: dedupIndex
)
for fileURL in files {
let notebook = fileURL.deletingPathExtension().lastPathComponent
for line in try ImportFiles.lines(from: fileURL) {
let root: Any
do {
root = try ImportJSON.object(fromLine: line)
} catch {
accumulator.skipMalformed()
continue
}
guard let object = root as? [String: Any] else {
accumulator.skipMalformed()
continue
}
guard object["role"] as? String == "user" else { continue }
let text: String
if object["content"] == nil {
// Python's obj.get("content", "") treats a missing value
// as an empty prompt, which is scanned and skipped_short.
text = ""
} else if let content = object["content"] as? String {
text = content
} else {
accumulator.skipMalformed()
continue
}
accumulator.accept(
text,
sourcePrefix: "gemini-raw",
tags: "gemini,\(notebook.lowercased())",
promptedAt: firstTimestamp(in: object)
)
}
}
return accumulator.result()
}
private func firstTimestamp(in object: [String: Any]) -> String? {
for key in ["timestamp", "date", "created_at", "create_time"] {
if let timestamp = ImportTimestamp.normalize(object[key]) {
return timestamp
}
}
return nil
}
}