Tokenizer implemented
This commit is contained in:
@@ -30,6 +30,7 @@ typedef struct {
|
||||
int tc_state_n;
|
||||
int tc_state_cap;
|
||||
bool any_toolcall;
|
||||
int include_usage;
|
||||
char *final_content; /* non-streaming accumulation */
|
||||
char *final_reasoning;
|
||||
tool_call_t *final_tc;
|
||||
@@ -132,6 +133,31 @@ static void emit_chunk(sse_ctx_t *ctx, const char *role, const char *content,
|
||||
json_object_put(root);
|
||||
}
|
||||
|
||||
static void emit_usage_chunk(sse_ctx_t *ctx, int prompt_tokens, int completion_tokens) {
|
||||
json_object *root = json_object_new_object();
|
||||
json_object_object_add(root, "id", json_object_new_string(ctx->completion_id));
|
||||
json_object_object_add(root, "object", json_object_new_string("chat.completion.chunk"));
|
||||
json_object_object_add(root, "created", json_object_new_int64(ctx->created));
|
||||
json_object_object_add(root, "model", json_object_new_string(ctx->model));
|
||||
json_object *choices = json_object_new_array();
|
||||
json_object_object_add(root, "choices", choices);
|
||||
json_object *usage = json_object_new_object();
|
||||
json_object_object_add(usage, "prompt_tokens", json_object_new_int(prompt_tokens));
|
||||
json_object_object_add(usage, "completion_tokens", json_object_new_int(completion_tokens));
|
||||
json_object_object_add(usage, "total_tokens",
|
||||
json_object_new_int(prompt_tokens + completion_tokens));
|
||||
json_object_object_add(root, "usage", usage);
|
||||
const char *j = json_object_to_json_string(root);
|
||||
if (j) {
|
||||
size_t need = strlen(j) + 32;
|
||||
char *buf = (char *)malloc(need);
|
||||
int bl = snprintf(buf, need, "data: %s\n\n", j);
|
||||
write_all(ctx->client_fd, buf, (size_t)bl);
|
||||
free(buf);
|
||||
}
|
||||
json_object_put(root);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* SSE line processing */
|
||||
/* ------------------------------------------------------------------ */
|
||||
@@ -396,6 +422,18 @@ static void handle_chat(int fd, http_req_t *req, const config_t *cfg) {
|
||||
}
|
||||
|
||||
char *payload = build_gradio_payload(jreq, model);
|
||||
|
||||
int prompt_tokens = count_messages_tokens(jreq);
|
||||
bool include_usage = false;
|
||||
json_object *so = NULL;
|
||||
if (json_object_object_get_ex(jreq, "stream_options", &so) &&
|
||||
json_object_get_type(so) == json_type_object) {
|
||||
json_object *iu = NULL;
|
||||
if (json_object_object_get_ex(so, "include_usage", &iu) &&
|
||||
json_object_get_type(iu) == json_type_boolean)
|
||||
include_usage = json_object_get_boolean(iu);
|
||||
}
|
||||
|
||||
json_object_put(jreq);
|
||||
if (!payload) {
|
||||
send_simple(fd, 400, "Bad Request", "Invalid request: missing messages");
|
||||
@@ -457,6 +495,7 @@ static void handle_chat(int fd, http_req_t *req, const config_t *cfg) {
|
||||
ctx.client_fd = fd;
|
||||
ctx.streaming = stream;
|
||||
ctx.model = model;
|
||||
ctx.include_usage = include_usage;
|
||||
ctx.created = (long)time(NULL);
|
||||
char uuid[37];
|
||||
generate_uuid(uuid);
|
||||
@@ -479,12 +518,19 @@ static void handle_chat(int fd, http_req_t *req, const config_t *cfg) {
|
||||
|
||||
if (stream) {
|
||||
emit_chunk(&ctx, NULL, NULL, NULL, NULL, ctx.any_toolcall ? "tool_calls" : "stop");
|
||||
if (ctx.include_usage) {
|
||||
int completion_tokens = tok_count_str(ctx.emitted_content.buf);
|
||||
completion_tokens += tok_count_str(ctx.emitted_reasoning.buf);
|
||||
for (int i = 0; i < ctx.tc_state_n; i++)
|
||||
completion_tokens += tok_count_str(ctx.tc_state[i].prev_args);
|
||||
emit_usage_chunk(&ctx, prompt_tokens, completion_tokens);
|
||||
}
|
||||
const char *done = "data: [DONE]\n\n";
|
||||
write_all(fd, done, strlen(done));
|
||||
} else {
|
||||
char *resp = build_completion_response(ctx.completion_id, ctx.created, ctx.model,
|
||||
ctx.final_content, ctx.final_reasoning,
|
||||
ctx.final_tc, ctx.final_n_tc);
|
||||
ctx.final_tc, ctx.final_n_tc, prompt_tokens);
|
||||
if (resp) {
|
||||
send_json(fd, resp);
|
||||
free(resp);
|
||||
|
||||
Reference in New Issue
Block a user