30using ChatDecode = std::function<std::string(
const std::vector<int>&)>;
34 const char*
ws =
" \t\n\v\f\r";
35 const auto a =
s.find_first_not_of(
ws),
b =
s.find_last_not_of(
ws);
36 return a == std::string::npos ? std::string() :
s.substr(
a,
b -
a + 1);
49 if (
p.parsed && !
p.tool_calls.empty()) {
51 for (
auto&
c :
p.tool_calls) {
54 r.tool_calls.push_back(std::move(
c));
67 Json a = Json::array();
68 for (
const auto&
c :
calls)
69 a.push_back(
Json{{
"id",
c.id}, {
"type",
"function"}, {
"function",
Json{{
"name",
c.name}, {
"arguments",
c.arguments}}}});
82 if (call_id_ >= 0 &&
id == call_id_) in_call_ =
true;
83 if (in_call_)
return std::string();
84 return stream_.next(decode_(ids_),
false);
89 if (!in_call_)
return stream_.next(decode_(ids_),
true);
90 if (!
out.tool_calls.empty()) {
91 std::vector<int>
before(ids_.begin(), ids_.begin() + first_call());
92 return stream_.next(decode_(
before),
true);
94 return stream_.next(decode_(ids_),
true);
97 const std::vector<int>&
ids()
const {
return ids_; }
101 for (
size_t i = 0;
i < ids_.size(); ++
i)
102 if (ids_[
i] == call_id_)
return static_cast<std::ptrdiff_t
>(
i);
103 return static_cast<std::ptrdiff_t
>(ids_.size());
109 bool in_call_ =
false;
std::string finish(ChatReply &out)
const std::vector< int > & ids() const
ReplyBuilder(int call_id, ChatDecode decode)
std::ptrdiff_t first_call() const
const float * p[kIrDepthSourcesMax]
std::string strip_reply_ws(const std::string &s)
Json tool_calls_json(const std::vector< chat::ToolCall > &calls)
std::function< std::string(const std::vector< int > &)> ChatDecode
ChatReply reply_of(const std::vector< int > &ids, int call_id, const ChatDecode &decode)
std::string utf8_valid(const std::string &s)
ParsedReply parse_reply(const std::vector< int > &ids, int call_id, Decode decode)
std::vector< chat::ToolCall > tool_calls