Submit one user turn if the worker is idle. Busy submissions are rejected so * the UI can keep the typed text editable instead of silently queueing it. */
| 8161 | ds4_tokens_free(&t); |
| 8162 | return id; |
| 8163 | } |
| 8164 | |
| 8165 | /* Pick a recent verbatim tail for the compacted transcript. Prefer a user |
| 8166 | * boundary inside the budget so the rebuilt context starts at a natural turn. */ |
| 8167 | static int agent_compact_tail_start(agent_worker *w, int bottom, int sys_len) { |
| 8168 | int ctx = agent_worker_effective_ctx_size(w); |
| 8169 | int tail_budget = ctx / AGENT_COMPACT_TAIL_DIVISOR; |
| 8170 | if (tail_budget > AGENT_COMPACT_TAIL_CAP_TOKENS) |
| 8171 | tail_budget = AGENT_COMPACT_TAIL_CAP_TOKENS; |
| 8172 | if (tail_budget < 1) tail_budget = 1; |
| 8173 | |
| 8174 | int target = bottom - tail_budget; |
| 8175 | if (target < sys_len) target = sys_len; |
| 8176 | |
| 8177 | int user_id = agent_special_token_id(w->engine, |
| 8178 | ds4_engine_is_glm_dsa(w->engine) ? "<|user|>" : "<|User|>"); |
| 8179 | if (user_id < 0) return target; |
| 8180 | |
| 8181 | for (int i = target; i < bottom; i++) { |
| 8182 | if (w->transcript.v[i] == user_id) return i; |
| 8183 | } |
| 8184 | return target; |
| 8185 | } |
| 8186 | |
| 8187 | static void agent_tokens_append_range(ds4_tokens *dst, const ds4_tokens *src, |
no test coverage detected