MCPcopy Create free account
hub / github.com/Luce-Org/lucebox-hub / normalize_chat_messages

Function normalize_chat_messages

server/src/server/http_server.cpp:728–818  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

726 {"current_entries", tms.current_entries},
727 {"current_bytes", tms.current_bytes},
728 }},
729 // The C++ daemon is linked in-process; if /props is responding,
730 // the daemon is alive by construction.
731 {"daemon", {{"alive", true}}},
732 {"api", {{"endpoints", kApiEndpoints}}},
733 // Capability flags surfaced for clients that don't want to crack
734 // open `reasoning` / `speculative` / etc. — matches the Python
735 // server's _capabilities() helper.
736 {"capabilities", {
737 {"reasoning_supported", reasoning_supported},
738 {"speculative_supported", speculative_supported},
739 {"tools_supported", tools_supported},
740 }},
741 };
742 return body;
743}
744
745// Normalize Anthropic's `system` field (top-level on /v1/messages and
746// /v1/messages/count_tokens) into a leading `{role:"system", content:...}`
747// entry on `messages`. Accepts either a flat string or an array of typed
748// blocks (`[{type:"text", text:"..."}]`), and strips any
749// `x-anthropic-billing-header:`-prefixed block injected by Claude Code so
750// it never reaches the model or the token counter.
751//
752// Side-effect: prepends a system message to `messages` when the body has
753// a non-empty `system` field after billing-header filtering. No-op
754// otherwise. Both endpoints call this with identical semantics — having
755// one helper guarantees token counting and generation can't drift.
756static void normalize_anthropic_system(const json & body, json & messages) {
757 if (!body.contains("system")) return;
758 // Delegate strip to the pure fn; insert as system message.
759 std::string text = dflash::common::normalize_system_for_cache(body["system"]);
760 if (!text.empty()) {
761 json sys_msg = {{"role", "system"}, {"content", text}};
762 messages.insert(messages.begin(), sys_msg);
763 }
764}
765
766json parse_responses_arguments(const json & item) {
767 if (!item.contains("arguments")) return json::object();
768 const auto & arguments = item["arguments"];
769 if (arguments.is_object()) return arguments;
770 if (arguments.is_string()) {
771 try {
772 return json::parse(arguments.get<std::string>());
773 } catch (const std::exception &) {
774 return json::object();
775 }
776 }
777 return json::object();
778}
779
780std::string render_tool_call_xml(const std::string & name, const json & arguments) {
781 std::string out = "<function=" + name + ">\n";
782 if (arguments.is_object()) {
783 for (const auto & [key, value] : arguments.items()) {
784 out += "<parameter=" + key + ">\n";
785 out += value.is_string() ? value.get<std::string>() : value.dump();

Callers 3

route_requestMethod · 0.85
worker_loopMethod · 0.85

Calls 5

render_tool_call_xmlFunction · 0.85
emptyMethod · 0.45
lookupMethod · 0.45
sizeMethod · 0.45