LlamaLib  v2.0.2
Cross-platform library for local LLMs
Loading...
Searching...
No Matches
completion_processor.cpp
1#include "completion_processor.h"
2
3bool ResponseConcatenator::process_chunk(const std::string& chunk_data) {
4 if (chunk_data.empty()) {
5 return true;
6 }
7
8 std::string cleaned_chunk = chunk_data;
9
10 // Handle SSE format
11 // Remove "data: " prefix if present
12 const std::string prefix = "data: ";
13 if (cleaned_chunk.rfind(prefix, 0) == 0) {
14 cleaned_chunk.erase(0, prefix.length());
15 }
16
17 // Remove trailing newlines/carriage returns
18 while (!cleaned_chunk.empty() &&
19 (cleaned_chunk.back() == '\n' || cleaned_chunk.back() == '\r')) {
20 cleaned_chunk.pop_back();
21 }
22
23 // Check for SSE termination signal
24 if (cleaned_chunk == "[DONE]") {
25 is_complete_ = true;
26 return false;
27 }
28
29 if (cleaned_chunk.empty()) {
30 return true;
31 }
32
33 try {
34 json chunk_json = json::parse(cleaned_chunk);
35
36 // Handle error responses
37 if (chunk_json.contains("error")) {
38 error_ = chunk_json["error"];
39 has_error_ = true;
40 return false;
41 }
42
43 // Accumulate content
44 if (chunk_json.contains("content")) {
45 std::string content = chunk_json["content"].get<std::string>();
46 concatenated_content_ += content;
47 }
48
49 // Accumulate tokens
50 if (chunk_json.contains("tokens")) {
51 for (const auto& tok : chunk_json["tokens"]) {
52 concatenated_tokens_.push_back(tok.get<int>());
53 }
54 }
55
56 // Store the last chunk for metadata (model, id, etc.)
57 last_chunk_ = chunk_json;
58
59 // Invoke callback if set
60 if (callback_) {
61 if (callWithJSON_) callback_(build_concatenated_json().dump().c_str());
62 else callback_(concatenated_content_.c_str());
63 }
64
65 chunk_count_++;
66
67 } catch (const json::exception& e) {
68 error_ = json{{"message", std::string("JSON parse error: ") + e.what()}};
69 has_error_ = true;
70 return false;
71 }
72
73 return true;
74}
75
77 json result = last_chunk_.empty() ? json::object() : last_chunk_;
78 result["content"] = concatenated_content_;
79 result["tokens"] = concatenated_tokens_;
80 return result;
81}
82
84 if (has_error_) {
85 return json{{"error", error_}}.dump();
86 }
87 return build_concatenated_json().dump();
88}
89
91 concatenated_content_.clear();
92 concatenated_tokens_.clear();
93 last_chunk_ = json::object();
94 error_ = json::object();
95 has_error_ = false;
96 is_complete_ = false;
97 chunk_count_ = 0;
98}
99
100void ResponseConcatenator::accumulate_result(const json& item) {
101 if (item.contains("content")) {
102 concatenated_content_ += item["content"].get<std::string>();
103 }
104 if (item.contains("tokens")) {
105 for (const auto& tok : item["tokens"]) {
106 concatenated_tokens_.push_back(tok.get<int>());
107 }
108 }
109 last_chunk_ = item;
110}
bool process_chunk(const std::string &chunk_data)
Process a single chunk and accumulate its content/tokens.
void reset()
Reset the concatenator state.
json build_concatenated_json() const
Build the final concatenated JSON result.
std::string get_result_json() const
Get the complete result as JSON string.