| 95 | } |
| 96 | |
| 97 | StreamResult LFM2::parse_stream_content(const std::string content) { |
| 98 | const std::string TOOL_START = "<|tool_call_start|>"; |
| 99 | const std::string TOOL_END = "<|tool_call_end|>"; |
| 100 | |
| 101 | StreamResult result; |
| 102 | buffer_ += content; |
| 103 | |
| 104 | while (true) { |
| 105 | if (!is_in_tool_block_) { |
| 106 | size_t tool_start_pos = buffer_.find(TOOL_START); |
| 107 | |
| 108 | if (tool_start_pos != std::string::npos) { |
| 109 | if (tool_start_pos > 0) { |
| 110 | result.content = buffer_.substr(0, tool_start_pos); |
| 111 | result.type = StreamEventType::CONTENT; |
| 112 | buffer_ = buffer_.substr(tool_start_pos); |
| 113 | return result; |
| 114 | } |
| 115 | |
| 116 | is_in_tool_block_ = true; |
| 117 | tool_name_.clear(); |
| 118 | buffer_ = buffer_.substr(TOOL_START.length()); |
| 119 | result.type = StreamEventType::WAITING; |
| 120 | return result; |
| 121 | } |
| 122 | else { |
| 123 | if (!buffer_.empty()) { |
| 124 | result.content = buffer_; |
| 125 | result.type = StreamEventType::CONTENT; |
| 126 | buffer_.clear(); |
| 127 | return result; |
| 128 | } |
| 129 | break; |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | if (is_in_tool_block_) { |
| 134 | size_t tool_end_pos = buffer_.find(TOOL_END); |
| 135 | |
| 136 | if (tool_end_pos != std::string::npos) { |
| 137 | tool_name_ += buffer_.substr(0, tool_end_pos); |
| 138 | buffer_ = buffer_.substr(tool_end_pos + TOOL_END.length()); |
| 139 | is_in_tool_block_ = false; |
| 140 | |
| 141 | std::string raw = tool_name_; |
| 142 | |
| 143 | size_t start = raw.find_first_not_of(" \t\n\r["); |
| 144 | if (start == std::string::npos) { |
| 145 | result.type = StreamEventType::CONTENT; |
| 146 | result.content = "[Error: Empty tool call]"; |
| 147 | return result; |
| 148 | } |
| 149 | raw = raw.substr(start); |
| 150 | |
| 151 | size_t pos_open = raw.find('('); |
| 152 | if (pos_open == std::string::npos) { |
| 153 | result.type = StreamEventType::CONTENT; |
| 154 | result.content = "[Error: No function bracket found]"; |
no test coverage detected