Tab completion for /switch. Suggestions are sorted by recent use and accept * either an empty prefix or any unambiguous hex prefix. */
| 5108 | agent_history_mark mark = AGENT_HISTORY_MARK_NONE; |
| 5109 | size_t mark_len = 0; |
| 5110 | const char *m = agent_history_next_marker(p, end, &mark, &mark_len); |
| 5111 | if (!m) break; |
| 5112 | agent_history_ptrs_push(&marks, m, mark); |
| 5113 | const char *content = m + mark_len; |
| 5114 | agent_history_mark next_mark = AGENT_HISTORY_MARK_NONE; |
| 5115 | size_t next_len = 0; |
| 5116 | const char *next = agent_history_next_marker(content, end, |
| 5117 | &next_mark, &next_len); |
| 5118 | const char *content_end = next ? next : end; |
| 5119 | if (mark == AGENT_HISTORY_MARK_USER) { |
| 5120 | agent_history_ptrs_push(&all_users, m, mark); |
| 5121 | if (!agent_history_is_tool_user(content, content_end)) |
| 5122 | agent_history_ptrs_push(&users, m, mark); |
| 5123 | } |
| 5124 | p = content_end; |
| 5125 | } |
| 5126 | |
| 5127 | const char *start = end; |
| 5128 | if (tool_only) *tool_only = false; |
| 5129 | if (users.len > 0) { |
| 5130 | int idx = users.len - user_turns; |
| 5131 | if (idx < 0) idx = 0; |
| 5132 | start = users.v[idx]; |
| 5133 | } else if (all_users.len > 0) { |
| 5134 | int idx = all_users.len - user_turns; |
| 5135 | if (idx < 0) idx = 0; |
| 5136 | start = all_users.v[idx]; |
| 5137 | if (tool_only) *tool_only = true; |
| 5138 | |
| 5139 | /* Tool result messages are stored as user-role turns after the |
| 5140 | * assistant DSML stanza that produced them. Include that preceding |
| 5141 | * assistant marker when it is still in the retained tail, otherwise |
| 5142 | * replay shows the result but hides the call that caused it. */ |
| 5143 | for (int i = marks.len - 1; i >= 0; i--) { |
| 5144 | if (marks.v[i] >= start) continue; |
| 5145 | if (marks.mark[i] == AGENT_HISTORY_MARK_USER) break; |
| 5146 | if (marks.mark[i] == AGENT_HISTORY_MARK_ASSISTANT) { |
| 5147 | start = marks.v[i]; |
| 5148 | break; |
| 5149 | } |
| 5150 | } |
| 5151 | } |
| 5152 | agent_history_ptrs_free(&marks); |
| 5153 | agent_history_ptrs_free(&users); |
| 5154 | agent_history_ptrs_free(&all_users); |
| 5155 | return start; |
| 5156 | } |
| 5157 | |
| 5158 | static bool agent_history_latest_compaction_summary(const char *text, |
| 5159 | size_t len, |
| 5160 | const char **sum_start, |
| 5161 | const char **sum_end) { |
| 5162 | static const char start_mark[] = |
| 5163 | "[ds4-agent compacted earlier conversation. Durable task-state summary follows.]"; |
| 5164 | static const char end_mark[] = |
| 5165 | "[End compacted summary. Recent conversation continues verbatim below.]"; |
| 5166 | const char *end = text + len; |
| 5167 | const char *scan = text; |
nothing calls this directly
no test coverage detected