tok/mkf upd
This commit is contained in:
@@ -39,6 +39,35 @@ static int count_content_tokens(json_object *content) {
|
||||
return s ? tok_count_str(s) : 0;
|
||||
}
|
||||
|
||||
/* Count tokens for a tool-call arguments JSON string as rendered by
|
||||
* tencent/Hy3's chat_template.jinja: each key is emitted raw inside
|
||||
* <arg_key:opensource>...</arg_key:opensource> and each value is emitted
|
||||
* as a raw unescaped string (when string) or JSON (when non-string)
|
||||
* inside <arg_value:opensource>...</arg_value:opensource>. */
|
||||
static int count_tool_args_tokens(const char *ar_str, int ar_len) {
|
||||
if (!ar_str || ar_len <= 0) return 0;
|
||||
json_object *parsed = json_tokener_parse(ar_str);
|
||||
if (parsed && json_object_get_type(parsed) == json_type_object) {
|
||||
int total = 0;
|
||||
json_object_object_foreach(parsed, key, val) {
|
||||
if (key && key[0]) total += tok_count_str(key);
|
||||
if (val) {
|
||||
if (json_object_get_type(val) == json_type_string) {
|
||||
total += tok_count(json_object_get_string(val),
|
||||
json_object_get_string_len(val));
|
||||
} else {
|
||||
const char *vs = json_object_to_json_string(val);
|
||||
if (vs) total += tok_count_str(vs);
|
||||
}
|
||||
}
|
||||
}
|
||||
json_object_put(parsed);
|
||||
return total;
|
||||
}
|
||||
if (parsed) json_object_put(parsed);
|
||||
return tok_count(ar_str, ar_len);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Token counting (embedded Tencent Hy3 BPE) */
|
||||
/* ------------------------------------------------------------------ */
|
||||
@@ -47,12 +76,32 @@ int count_messages_tokens(void *req_obj) {
|
||||
if (!req) return 0;
|
||||
int total = 0;
|
||||
|
||||
bool has_tools = false;
|
||||
json_object *tools = NULL;
|
||||
if (json_object_object_get_ex(req, "tools", &tools) &&
|
||||
json_object_get_type(tools) == json_type_array &&
|
||||
json_object_array_length(tools) > 0) {
|
||||
const char *ts = json_object_to_json_string(tools);
|
||||
if (ts) total += tok_count_str(ts);
|
||||
json_object_get_type(tools) == json_type_array) {
|
||||
int tn = json_object_array_length(tools);
|
||||
if (tn > 0) {
|
||||
has_tools = true;
|
||||
for (int i = 0; i < tn; i++) {
|
||||
json_object *ti = json_object_array_get_idx(tools, i);
|
||||
if (!ti) continue;
|
||||
const char *ts = json_object_to_json_string(ti);
|
||||
if (ts) total += tok_count_str(ts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* In tencent/Hy3's chat_template.jinja, preserved_thinking defaults to
|
||||
* true when tools are present and false when tools are absent (unless
|
||||
* explicitly overridden). Since spaces/tencent/Hy3 appends the final
|
||||
* turn as a user message, historical assistant reasoning_content is
|
||||
* only included in the prompt when preserved_thinking is active. */
|
||||
bool preserved_thinking = has_tools;
|
||||
json_object *pt_obj = NULL;
|
||||
if (json_object_object_get_ex(req, "preserved_thinking", &pt_obj) &&
|
||||
json_object_get_type(pt_obj) == json_type_boolean) {
|
||||
preserved_thinking = json_object_get_boolean(pt_obj) ? true : false;
|
||||
}
|
||||
|
||||
json_object *messages = NULL;
|
||||
@@ -114,20 +163,26 @@ int count_messages_tokens(void *req_obj) {
|
||||
|
||||
total += count_content_tokens(content);
|
||||
|
||||
/* Historical tool messages in tencent/Hy3 chat_template.jinja render
|
||||
* only visible_text(message['content']); tool_call_id and name are not
|
||||
* emitted into the prompt. */
|
||||
if (strcmp(roleStr, "tool") == 0 || strcmp(roleStr, "function") == 0) {
|
||||
const char *toolID = get_str(m, "tool_call_id");
|
||||
const char *nm = get_str(m, "name");
|
||||
if (toolID[0] != 0) total += tok_count_str(toolID);
|
||||
if (nm[0] != 0) total += tok_count_str(nm);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(roleStr, "assistant") == 0) {
|
||||
json_object *rc = NULL;
|
||||
if (json_object_object_get_ex(m, "reasoning_content", &rc) &&
|
||||
json_object_get_type(rc) == json_type_string)
|
||||
total += tok_count(json_object_get_string(rc),
|
||||
json_object_get_string_len(rc));
|
||||
if (preserved_thinking) {
|
||||
json_object *rc = NULL;
|
||||
if (json_object_object_get_ex(m, "reasoning_content", &rc) &&
|
||||
json_object_get_type(rc) == json_type_string) {
|
||||
total += tok_count(json_object_get_string(rc),
|
||||
json_object_get_string_len(rc));
|
||||
} else if (json_object_object_get_ex(m, "reasoning", &rc) &&
|
||||
json_object_get_type(rc) == json_type_string) {
|
||||
total += tok_count(json_object_get_string(rc),
|
||||
json_object_get_string_len(rc));
|
||||
}
|
||||
}
|
||||
json_object *tcs = NULL;
|
||||
if (json_object_object_get_ex(m, "tool_calls", &tcs) &&
|
||||
json_object_get_type(tcs) == json_type_array) {
|
||||
@@ -145,8 +200,8 @@ int count_messages_tokens(void *req_obj) {
|
||||
json_object_get_string_len(nm));
|
||||
if (json_object_object_get_ex(fn, "arguments", &ar) &&
|
||||
json_object_get_type(ar) == json_type_string)
|
||||
total += tok_count(json_object_get_string(ar),
|
||||
json_object_get_string_len(ar));
|
||||
total += count_tool_args_tokens(json_object_get_string(ar),
|
||||
json_object_get_string_len(ar));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -160,8 +215,8 @@ int count_messages_tokens(void *req_obj) {
|
||||
json_object_get_string_len(nm));
|
||||
if (json_object_object_get_ex(fc, "arguments", &ar) &&
|
||||
json_object_get_type(ar) == json_type_string)
|
||||
total += tok_count(json_object_get_string(ar),
|
||||
json_object_get_string_len(ar));
|
||||
total += count_tool_args_tokens(json_object_get_string(ar),
|
||||
json_object_get_string_len(ar));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -175,7 +230,9 @@ int count_completion_tokens(const char *content, const char *reasoning,
|
||||
if (reasoning && reasoning[0]) total += tok_count_str(reasoning);
|
||||
for (int i = 0; i < n_tc; i++) {
|
||||
if (tc[i].name && tc[i].name[0]) total += tok_count_str(tc[i].name);
|
||||
if (tc[i].arguments && tc[i].arguments[0]) total += tok_count_str(tc[i].arguments);
|
||||
if (tc[i].arguments && tc[i].arguments[0])
|
||||
total += count_tool_args_tokens(tc[i].arguments,
|
||||
(int)strlen(tc[i].arguments));
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user