Skip to content

Commit 16d6f1f

Browse files
committed
Simplify API and fix bugs
- Fix copy and paste error in boolean parsing. - We don't need the setter methods. Just use operator=(). - Remove std::string_view (it complicates things too much)
1 parent 0ead068 commit 16d6f1f

File tree

5 files changed

+161
-181
lines changed

5 files changed

+161
-181
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@ double-conversion.a: \
4040
$(AR) rcs $@ $^
4141

4242
%.o: double-conversion/%.cc
43-
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $<
43+
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $<

README.md

+37-44
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ than 3x) advantage, which we haven't figured out how to explain yet.
5555

5656
```
5757
# json.cpp
58-
88 ns 2000x object_test()
59-
304 ns 2000x deep_test()
60-
816 ns 2000x parse_test()
61-
1588 ns 2000x round_trip_test()
62-
5838 ns 2000x json_test_suite()
58+
71 ns 2000x object_test()
59+
226 ns 2000x deep_test()
60+
675 ns 2000x parse_test()
61+
1309 ns 2000x round_trip_test()
62+
10462 ns 2000x json_test_suite()
6363
6464
# nlohmann::ordered_json
6565
202 ns 2000x object_test()
@@ -79,28 +79,28 @@ Here's the code where it parses the incoming HTTP body and validates it.
7979

8080
```cpp
8181
// object<model, messages, ...>
82-
std::pair<Json::Status, Json> json = Json::parse(payload_);
83-
if (json.first != Json::success)
84-
return send_error(400, Json::StatusToString(json.first));
85-
if (!json.second.isObject())
82+
auto [status, json] = jt::Json::parse(std::string(payload_));
83+
if (status != jt::Json::success)
84+
return send_error(400, jt::Json::StatusToString(status));
85+
if (!json.isObject())
8686
return send_error(400, "JSON body must be an object");
8787

8888
// fields openai documents that we don't support yet
89-
if (!json.second["tools"].isNull())
89+
if (json.contains("tools"))
9090
return send_error(400, "OpenAI tools field not supported yet");
91-
if (!json.second["audio"].isNull())
91+
if (json.contains("audio"))
9292
return send_error(400, "OpenAI audio field not supported yet");
9393

9494
// model: string
95-
Json& model = json.second["model"];
95+
jt::Json& model = json["model"];
9696
if (!model.isString())
9797
return send_error(400, "JSON missing model string");
98-
params->model = std::move(model.getString());
98+
params->model = model.getString();
9999

100100
// messages: array<object<role:string, content:string>>
101-
if (!json.second["messages"].isArray())
101+
if (!json["messages"].isArray())
102102
return send_error(400, "JSON missing messages array");
103-
std::vector<Json>& messages = json.second["messages"].getArray();
103+
std::vector<Json>& messages = json["messages"].getArray();
104104
if (messages.empty())
105105
return send_error(400, "JSON messages array is empty");
106106
for (Json& message : messages) {
@@ -112,9 +112,8 @@ Here's the code where it parses the incoming HTTP body and validates it.
112112
return send_error(400, "message role not system user assistant");
113113
if (!message["content"].isString())
114114
return send_error(400, "message must have string content");
115-
params->messages.emplace_back(
116-
std::move(message["role"].getString()),
117-
std::move(message["content"].getString()));
115+
params->messages.emplace_back(message["role"].getString(),
116+
message["content"].getString());
118117
}
119118

120119
// ...
@@ -126,7 +125,7 @@ Here's the code where it sends a response.
126125
struct V1ChatCompletionResponse
127126
{
128127
std::string content;
129-
Json json;
128+
jt::Json json;
130129
};
131130
132131
bool
@@ -140,27 +139,24 @@ Client::v1_chat_completions()
140139
// ...
141140
142141
// setup response json
143-
response->json["id"].setString(generate_id());
144-
response->json["object"].setString("chat.completion");
145-
response->json["model"].setString(params->model);
146-
response->json["system_fingerprint"].setString(slot_->system_fingerprint_);
147-
response->json["choices"].setArray();
142+
response->json["id"] = generate_id();
143+
response->json["object"] = "chat.completion";
144+
response->json["model"] = params->model;
145+
response->json["system_fingerprint"] = slot_->system_fingerprint_;
148146
Json& choice = response->json["choices"][0];
149-
choice.setObject();
150-
choice["index"].setLong(0);
151-
choice["logprobs"].setNull();
152-
choice["finish_reason"].setNull();
147+
choice["index"] = 0;
148+
choice["logprobs"] = nullptr;
149+
choice["finish_reason"] = nullptr;
153150
154151
// initialize response
155152
if (params->stream) {
156153
char* p = append_http_response_message(obuf_.p, 200);
157154
p = stpcpy(p, "Content-Type: text/event-stream\r\n");
158155
if (!send_response_start(obuf_.p, p))
159156
return false;
160-
choice["delta"].setObject();
161-
choice["delta"]["role"].setString("assistant");
162-
choice["delta"]["content"].setString("");
163-
response->json["created"].setLong(timespec_real().tv_sec);
157+
choice["delta"]["role"] = "assistant";
158+
choice["delta"]["content"] = "";
159+
response->json["created"] = timespec_real().tv_sec;
164160
response->content = make_event(response->json);
165161
choice.getObject().erase("delta");
166162
if (!send_response_chunk(response->content))
@@ -173,29 +169,26 @@ Client::v1_chat_completions()
173169
for (;;) {
174170
// do token generation ...
175171
}
176-
choice["finish_reason"].setString(finish_reason);
172+
choice["finish_reason"] = finish_reason;
177173
178174
// finalize response
179175
cleanup_slot(this);
180176
if (params->stream) {
181-
choice["delta"].setObject();
182-
choice["delta"]["content"].setString("");
183-
response->json["created"].setLong(timespec_real().tv_sec);
177+
choice["delta"]["content"] = "";
178+
response->json["created"] = timespec_real().tv_sec;
184179
response->content = make_event(response->json);
185180
choice.getObject().erase("delta");
186181
if (!send_response_chunk(response->content))
187182
return false;
188183
return send_response_finish();
189184
} else {
190185
Json& usage = response->json["usage"];
191-
usage.setObject();
192-
usage["prompt_tokens"].setLong(prompt_tokens);
193-
usage["completion_tokens"].setLong(completion_tokens);
194-
usage["total_tokens"].setLong(completion_tokens + prompt_tokens);
195-
choice["message"].setObject();
196-
choice["message"]["role"].setString("assistant");
197-
choice["message"]["content"].setString(std::move(response->content));
198-
response->json["created"].setLong(timespec_real().tv_sec);
186+
usage["prompt_tokens"] = prompt_tokens;
187+
usage["completion_tokens"] = completion_tokens;
188+
usage["total_tokens"] = completion_tokens + prompt_tokens;
189+
choice["message"]["role"] = "assistant";
190+
choice["message"]["content"] = std::move(response->content);
191+
response->json["created"] = timespec_real().tv_sec;
199192
char* p = append_http_response_message(obuf_.p, 200);
200193
p = stpcpy(p, "Content-Type: application/json\r\n");
201194
response->content = response->json.toStringPretty();

0 commit comments

Comments
 (0)