Save the current live KV under the rendered transcript identity. The caller * decides the policy: fixed sysprompt path or SHA-named session path. */
| 3871 | } else { |
| 3872 | agent_trace(sr->renderer->worker, "dsml done calls=%d", |
| 3873 | sr->parser->calls.len); |
| 3874 | agent_tool_viz_finish(sr, NULL); |
| 3875 | sr->dsml_active = false; |
| 3876 | } |
| 3877 | } else if (sr->dsml_ignored) { |
| 3878 | agent_stream_finish_ignored_dsml( |
| 3879 | sr, "tool calling is not allowed inside <think></think>"); |
| 3880 | } else { |
| 3881 | agent_tool_viz_finish(sr, sr->tool_preflight_error ? |
| 3882 | "[tool call stopped: edit old selector failed]\n" : |
| 3883 | "[tool call interrupted]\n"); |
| 3884 | sr->dsml_active = false; |
| 3885 | } |
| 3886 | } |
| 3887 | if (sr->dsml_in_think && !sr->dsml_in_think_reported) { |
| 3888 | agent_stream_finish_ignored_dsml( |
| 3889 | sr, "tool calling is not allowed inside <think></think>"); |
| 3890 | } |
| 3891 | } |
| 3892 | } |
| 3893 | |
| 3894 | /* ============================================================================ |
| 3895 | * Worker Progress And Generic Buffers |
| 3896 | * ============================================================================ |
| 3897 | */ |
| 3898 | |
| 3899 | static void worker_progress_cb(void *ud, const char *event, int current, int total) { |
| 3900 | agent_worker *w = ud; |
| 3901 | if (!w || !event) return; |
| 3902 | (void)total; |
| 3903 | worker_apply_pending_power(w); |
| 3904 | pthread_mutex_lock(&w->mu); |
| 3905 | int done = 0; |
| 3906 | int progress_total = w->status.prefill_total; |
| 3907 | if (!strcmp(event, "prefill_work")) { |
| 3908 | /* GLM reports intra-chunk work relative to the suffix being synced. |
| 3909 | * It is display progress only: checkpoint progress still arrives as |
| 3910 | * absolute prefill_chunk positions after each completed chunk. */ |
| 3911 | done = current; |
| 3912 | } else if (!strcmp(event, "prefill_chunk") || |
| 3913 | !strcmp(event, "prefill_display")) { |
| 3914 | if (w->progress_direct) { |
| 3915 | pthread_mutex_unlock(&w->mu); |
| 3916 | return; |
| 3917 | } |
| 3918 | done = current - w->progress_base; |
| 3919 | } else { |
| 3920 | pthread_mutex_unlock(&w->mu); |
| 3921 | return; |
| 3922 | } |
| 3923 | if (progress_total < 0) progress_total = 0; |
| 3924 | if (done < 0) done = 0; |
| 3925 | if (done > progress_total) done = progress_total; |
| 3926 | w->status.prefill_total = progress_total; |
| 3927 | w->status.prefill_done = done; |
| 3928 | double elapsed = now_sec() - w->progress_started_at; |
| 3929 | w->status.prefill_tps = |
| 3930 | done > 0 && elapsed > 0.0 ? (double)done / elapsed : 0.0; |
no test coverage detected