| 5517 | const char *dim = color ? "\x1b[90m" : ""; |
| 5518 | const char *reset = color ? "\x1b[0m" : ""; |
| 5519 | |
| 5520 | for (int i = 0; i < sessions_len; i++) { |
| 5521 | ds4_kvstore_entry *e = &sessions[i].entry; |
| 5522 | char age[32]; |
| 5523 | agent_format_age(e->last_used ? e->last_used : e->created_at, |
| 5524 | age, sizeof(age)); |
| 5525 | printf("%s%.8s%s %s>%s %s%s%s\n", |
| 5526 | sha_on, e->sha, reset, dim, reset, |
| 5527 | title_on, sessions[i].title, reset); |
| 5528 | printf(" %s> %s, %u tokens, %.2f MB%s%s\n\n", |
| 5529 | dim, age, e->tokens, |
| 5530 | (double)e->file_size / (1024.0 * 1024.0), |
| 5531 | e->payload_bytes == 0 ? ", stripped" : "", |
| 5532 | reset); |
| 5533 | } |
| 5534 | printf("%sUse /switch <id> to select a session, /del <id> to remove, " |
| 5535 | "/strip <id> to strip KV cache.%s\n", |
| 5536 | help_on, reset); |
| 5537 | agent_session_list_free(sessions, sessions_len); |
| 5538 | } |
| 5539 | |
| 5540 | typedef struct { |
| 5541 | char sha[41]; |
| 5542 | uint64_t last_used; |
| 5543 | } agent_completion_session; |
| 5544 | |
| 5545 | typedef struct { |
| 5546 | agent_completion_session *v; |
| 5547 | int len; |
| 5548 | int cap; |
| 5549 | } agent_completion_sessions; |
| 5550 | |
| 5551 | static void agent_completion_sessions_push(agent_completion_sessions *s, |
| 5552 | const char sha[41], |
| 5553 | uint64_t last_used) { |
| 5554 | if (s->len == s->cap) { |
| 5555 | s->cap = s->cap ? s->cap * 2 : 16; |
| 5556 | s->v = xrealloc(s->v, (size_t)s->cap * sizeof(s->v[0])); |
| 5557 | } |
| 5558 | memcpy(s->v[s->len].sha, sha, 41); |
| 5559 | s->v[s->len].last_used = last_used; |
| 5560 | s->len++; |
| 5561 | } |
| 5562 | |
| 5563 | static int agent_completion_session_cmp(const void *a, const void *b) { |
| 5564 | const agent_completion_session *sa = a, *sb = b; |
| 5565 | if (sa->last_used < sb->last_used) return 1; |
| 5566 | if (sa->last_used > sb->last_used) return -1; |
no test coverage detected