Read file text for the model. Normal mode shows plain line numbers. Raw * mode is reserved for cases where line decoration would corrupt the payload * being inspected. */
| 5652 | if (!title) return xstrdup("(no user prompt)"); |
| 5653 | size_t len = strlen(title); |
| 5654 | if (max_bytes == 0 || len <= max_bytes) return xstrdup(title); |
| 5655 | if (max_bytes < 4) max_bytes = 4; |
| 5656 | agent_buf b = {0}; |
| 5657 | agent_buf_append(&b, title, max_bytes - 3); |
| 5658 | agent_buf_puts(&b, "..."); |
| 5659 | return agent_buf_take(&b); |
| 5660 | } |
| 5661 | |
| 5662 | static char *agent_session_title_from_file(const char *path, size_t max_bytes) { |
| 5663 | FILE *fp = fopen(path, "rb"); |
| 5664 | if (!fp) return xstrdup("(unreadable session)"); |
| 5665 | ds4_kvstore_entry hdr = {0}; |
| 5666 | uint32_t text_bytes = 0; |
| 5667 | char *text = NULL; |
| 5668 | char *trailer_title = NULL; |
| 5669 | bool ok = ds4_kvstore_read_header(fp, &hdr, &text_bytes) && |
| 5670 | agent_kv_read_text(fp, text_bytes, &text, NULL, 0); |
| 5671 | if (ok && (hdr.ext_flags & DS4_KVSTORE_EXT_SESSION_TITLE)) |
| 5672 | ok = agent_kv_read_title_trailer(fp, &hdr, &trailer_title, NULL, 0); |
| 5673 | fclose(fp); |
| 5674 | char *title = ok ? |
| 5675 | (trailer_title ? |
| 5676 | agent_session_title_clip(trailer_title, max_bytes) : |
| 5677 | agent_session_title_from_text(text, text_bytes, max_bytes)) : |
| 5678 | xstrdup("(unreadable session)"); |
| 5679 | free(trailer_title); |
| 5680 | free(text); |
| 5681 | return title; |
| 5682 | } |
| 5683 | |
| 5684 | #define AGENT_HISTORY_DEFAULT_TURNS 3 |
| 5685 | #define AGENT_HISTORY_MAX_TURNS 200 |
| 5686 | #define AGENT_HISTORY_ASSISTANT_MAX_LINES 80 |
| 5687 | #define AGENT_HISTORY_ASSISTANT_MAX_BYTES 12000 |
| 5688 | |
| 5689 | typedef enum { |
| 5690 | AGENT_HISTORY_MARK_NONE, |
| 5691 | AGENT_HISTORY_MARK_USER, |
| 5692 | AGENT_HISTORY_MARK_ASSISTANT, |
| 5693 | AGENT_HISTORY_MARK_EOS, |
| 5694 | } agent_history_mark; |
| 5695 | |
| 5696 | typedef struct { |
| 5697 | const char **v; |
| 5698 | agent_history_mark *mark; |
| 5699 | int len; |
| 5700 | int cap; |
| 5701 | } agent_history_ptrs; |
| 5702 | |
| 5703 | static void agent_history_ptrs_push(agent_history_ptrs *p, const char *s, |
| 5704 | agent_history_mark mark) { |
| 5705 | if (p->len == p->cap) { |
| 5706 | p->cap = p->cap ? p->cap * 2 : 16; |
| 5707 | p->v = xrealloc(p->v, (size_t)p->cap * sizeof(p->v[0])); |
| 5708 | p->mark = xrealloc(p->mark, (size_t)p->cap * sizeof(p->mark[0])); |
| 5709 | } |
| 5710 | p->v[p->len] = s; |
| 5711 | p->mark[p->len] = mark; |
no test coverage detected