Responses API: convert a content-array item (input_text/output_text/text) into a * concatenated string. Strict shape check: bare string, null, or an array of * recognized text blocks. Numbers / objects / arrays-of-primitives at the top * level all reject so the client sees a 400 instead of an answer built on * silently dropped context. */
| 3021 | buf_free(&tools); |
| 3022 | } |
| 3023 | for (int i = 0; msgs && i < msgs->len; i++) { |
| 3024 | const chat_msg *m = &msgs->v[i]; |
| 3025 | if (!role_is_system(m->role)) continue; |
| 3026 | buf_puts(&out, "<|system|>"); |
| 3027 | buf_puts(&out, m->content ? m->content : ""); |
| 3028 | } |
| 3029 | |
| 3030 | bool pending_assistant = false; |
| 3031 | bool observation_open = false; |
| 3032 | for (int i = 0; msgs && i < msgs->len; i++) { |
| 3033 | const chat_msg *m = &msgs->v[i]; |
| 3034 | if (role_is_system(m->role)) { |
| 3035 | observation_open = false; |
| 3036 | continue; |
| 3037 | } else if (chat_msg_is_glm_tool_result(m)) { |
| 3038 | if (!observation_open) buf_puts(&out, "<|observation|>"); |
| 3039 | append_glm_tool_result_message(&out, m); |
| 3040 | observation_open = true; |
| 3041 | pending_assistant = true; |
| 3042 | } else if (!strcmp(m->role, "user")) { |
| 3043 | observation_open = false; |
| 3044 | buf_puts(&out, "<|user|>"); |
| 3045 | buf_puts(&out, m->content ? m->content : ""); |
| 3046 | pending_assistant = true; |
| 3047 | } else if (!strcmp(m->role, "assistant")) { |
| 3048 | observation_open = false; |
| 3049 | (void)pending_assistant; |
| 3050 | buf_puts(&out, "<|assistant|>"); |
| 3051 | append_glm_assistant_message_prefix( |
| 3052 | &out, m, think && (tool_context || i > last_user_idx)); |
| 3053 | append_trimmed_text(&out, m->content); |
| 3054 | append_tool_calls_text_for_syntax(&out, SERVER_MODEL_SYNTAX_GLM, |
| 3055 | &m->calls, tool_orders); |
| 3056 | pending_assistant = false; |
| 3057 | } |
| 3058 | } |
| 3059 | |
| 3060 | if (pending_assistant) { |
| 3061 | buf_puts(&out, "<|assistant|>"); |
| 3062 | buf_puts(&out, think ? "<think>" : "<think></think>"); |
| 3063 | } |
| 3064 | |
| 3065 | return buf_take(&out); |
| 3066 | } |
| 3067 | |
| 3068 | static char *render_chat_prompt_text_for_syntax(server_model_syntax syntax, |
| 3069 | const chat_msgs *msgs, |
| 3070 | const char *tool_schemas, |
| 3071 | const tool_schema_orders *tool_orders, |
| 3072 | ds4_think_mode think_mode) { |
| 3073 | if (syntax == SERVER_MODEL_SYNTAX_GLM) { |
| 3074 | return render_glm_chat_prompt_text(msgs, tool_schemas, |
| 3075 | tool_orders, think_mode); |
| 3076 | } |
| 3077 | return render_deepseek_chat_prompt_text(msgs, tool_schemas, |
| 3078 | tool_orders, think_mode); |
| 3079 | } |
| 3080 |
no test coverage detected