|
7 | 7 | #include <QString> |
8 | 8 | #include <QUrl> |
9 | 9 |
|
10 | | -#include <memory> |
| 10 | +#include <iterator> |
| 11 | +#include <map> |
| 12 | +#include <ranges> |
11 | 13 | #include <vector> |
12 | 14 |
|
13 | | -using namespace std::literals::string_view_literals; |
| 15 | +namespace views = std::views; |
| 16 | +using json = nlohmann::ordered_json; |
14 | 17 |
|
15 | 18 |
|
16 | | -JinjaResultInfo::~JinjaResultInfo() = default; |
17 | | - |
18 | | -const JinjaFieldMap<ResultInfo> JinjaResultInfo::s_fields = { |
19 | | - { "collection", [](auto &s) { return s.collection.toStdString(); } }, |
20 | | - { "path", [](auto &s) { return s.path .toStdString(); } }, |
21 | | - { "file", [](auto &s) { return s.file .toStdString(); } }, |
22 | | - { "title", [](auto &s) { return s.title .toStdString(); } }, |
23 | | - { "author", [](auto &s) { return s.author .toStdString(); } }, |
24 | | - { "date", [](auto &s) { return s.date .toStdString(); } }, |
25 | | - { "text", [](auto &s) { return s.text .toStdString(); } }, |
26 | | - { "page", [](auto &s) { return s.page; } }, |
27 | | - { "file_uri", [](auto &s) { return s.fileUri() .toStdString(); } }, |
28 | | -}; |
29 | | - |
30 | | -JinjaPromptAttachment::~JinjaPromptAttachment() = default; |
31 | | - |
32 | | -const JinjaFieldMap<PromptAttachment> JinjaPromptAttachment::s_fields = { |
33 | | - { "url", [](auto &s) { return s.url.toString() .toStdString(); } }, |
34 | | - { "file", [](auto &s) { return s.file() .toStdString(); } }, |
35 | | - { "processed_content", [](auto &s) { return s.processedContent().toStdString(); } }, |
36 | | -}; |
37 | | - |
38 | | -std::vector<std::string> JinjaMessage::GetKeys() const |
| 19 | +json::object_t JinjaResultInfo::AsJson() const |
39 | 20 | { |
40 | | - std::vector<std::string> result; |
41 | | - auto &keys = this->keys(); |
42 | | - result.reserve(keys.size()); |
43 | | - result.assign(keys.begin(), keys.end()); |
44 | | - return result; |
| 21 | + return { |
| 22 | + { "collection", m_source->collection.toStdString() }, |
| 23 | + { "path", m_source->path .toStdString() }, |
| 24 | + { "file", m_source->file .toStdString() }, |
| 25 | + { "title", m_source->title .toStdString() }, |
| 26 | + { "author", m_source->author .toStdString() }, |
| 27 | + { "date", m_source->date .toStdString() }, |
| 28 | + { "text", m_source->text .toStdString() }, |
| 29 | + { "page", m_source->page }, |
| 30 | + { "file_uri", m_source->fileUri() .toStdString() }, |
| 31 | + }; |
45 | 32 | } |
46 | 33 |
|
47 | | -auto JinjaMessage::keys() const -> const std::unordered_set<std::string_view> & |
| 34 | +json::object_t JinjaPromptAttachment::AsJson() const |
48 | 35 | { |
49 | | - static const std::unordered_set<std::string_view> baseKeys |
50 | | - { "role", "content" }; |
51 | | - static const std::unordered_set<std::string_view> userKeys |
52 | | - { "role", "content", "sources", "prompt_attachments" }; |
53 | | - switch (m_item->type()) { |
54 | | - using enum MessageItem::Type; |
55 | | - case System: |
56 | | - case Response: |
57 | | - case ToolResponse: |
58 | | - return baseKeys; |
59 | | - case Prompt: |
60 | | - return userKeys; |
61 | | - break; |
62 | | - } |
63 | | - Q_UNREACHABLE(); |
| 36 | + return { |
| 37 | + { "url", m_attachment->url.toString() .toStdString() }, |
| 38 | + { "file", m_attachment->file() .toStdString() }, |
| 39 | + { "processed_content", m_attachment->processedContent().toStdString() }, |
| 40 | + }; |
64 | 41 | } |
65 | 42 |
|
66 | | -bool operator==(const JinjaMessage &a, const JinjaMessage &b) |
| 43 | +json::object_t JinjaMessage::AsJson() const |
67 | 44 | { |
68 | | - if (a.m_item == b.m_item) |
69 | | - return true; |
70 | | - const auto &[ia, ib] = std::tie(*a.m_item, *b.m_item); |
71 | | - auto type = ia.type(); |
72 | | - if (type != ib.type() || ia.content() != ib.content()) |
73 | | - return false; |
74 | | - |
75 | | - switch (type) { |
76 | | - using enum MessageItem::Type; |
77 | | - case System: |
78 | | - case Response: |
79 | | - case ToolResponse: |
80 | | - return true; |
81 | | - case Prompt: |
82 | | - return ia.sources() == ib.sources() && ia.promptAttachments() == ib.promptAttachments(); |
83 | | - break; |
84 | | - } |
85 | | - Q_UNREACHABLE(); |
86 | | -} |
87 | | - |
88 | | -const JinjaFieldMap<JinjaMessage> JinjaMessage::s_fields = { |
89 | | - { "role", [](auto &m) { |
90 | | - switch (m.item().type()) { |
| 45 | + json::object_t obj; |
| 46 | + { |
| 47 | + json::string_t role; |
| 48 | + switch (m_item->type()) { |
91 | 49 | using enum MessageItem::Type; |
92 | | - case System: return "system"sv; |
93 | | - case Prompt: return "user"sv; |
94 | | - case Response: return "assistant"sv; |
95 | | - case ToolResponse: return "tool"sv; |
96 | | - break; |
| 50 | + case System: role = "system"; break; |
| 51 | + case Prompt: role = "user"; break; |
| 52 | + case Response: role = "assistant"; break; |
| 53 | + case ToolResponse: role = "tool"; break; |
| 54 | + } |
| 55 | + obj.emplace_back("role", std::move(role)); |
| 56 | + } |
| 57 | + { |
| 58 | + QString content; |
| 59 | + if (m_version == 0 && m_item->type() == MessageItem::Type::Prompt) { |
| 60 | + content = m_item->bakedPrompt(); |
| 61 | + } else { |
| 62 | + content = m_item->content(); |
| 63 | + } |
| 64 | + obj.emplace_back("content", content.toStdString()); |
| 65 | + } |
| 66 | + if (m_item->type() == MessageItem::Type::Prompt) { |
| 67 | + { |
| 68 | + auto sources = m_item->sources() | views::transform([](auto &r) { |
| 69 | + return JinjaResultInfo(r).AsJson(); |
| 70 | + }); |
| 71 | + obj.emplace("sources", json::array_t(sources.begin(), sources.end())); |
| 72 | + } |
| 73 | + { |
| 74 | + auto attachments = m_item->promptAttachments() | views::transform([](auto &pa) { |
| 75 | + return JinjaPromptAttachment(pa).AsJson(); |
| 76 | + }); |
| 77 | + obj.emplace("prompt_attachments", json::array_t(attachments.begin(), attachments.end())); |
97 | 78 | } |
98 | | - Q_UNREACHABLE(); |
99 | | - } }, |
100 | | - { "content", [](auto &m) { |
101 | | - if (m.version() == 0 && m.item().type() == MessageItem::Type::Prompt) |
102 | | - return m.item().bakedPrompt().toStdString(); |
103 | | - return m.item().content().toStdString(); |
104 | | - } }, |
105 | | - { "sources", [](auto &m) { |
106 | | - auto sources = m.item().sources() | views::transform([](auto &r) { |
107 | | - return jinja2::GenericMap([map = std::make_shared<JinjaResultInfo>(r)] { return map.get(); }); |
108 | | - }); |
109 | | - return jinja2::ValuesList(sources.begin(), sources.end()); |
110 | | - } }, |
111 | | - { "prompt_attachments", [](auto &m) { |
112 | | - auto attachments = m.item().promptAttachments() | views::transform([](auto &pa) { |
113 | | - return jinja2::GenericMap([map = std::make_shared<JinjaPromptAttachment>(pa)] { return map.get(); }); |
114 | | - }); |
115 | | - return jinja2::ValuesList(attachments.begin(), attachments.end()); |
116 | | - } }, |
117 | | -}; |
| 79 | + } |
| 80 | + return obj; |
| 81 | +} |
0 commit comments