-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathsession_attention.cpp
More file actions
92 lines (81 loc) · 3.28 KB
/
Copy pathsession_attention.cpp
File metadata and controls
92 lines (81 loc) · 3.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include "session_attention.hpp"
#include <algorithm>
namespace acecode {
const char* to_string(SessionAttentionState state) {
switch (state) {
case SessionAttentionState::Read: return "read";
case SessionAttentionState::Unread: return "unread";
case SessionAttentionState::InProgress: return "in_progress";
}
return "read";
}
std::optional<SessionAttentionState> parse_session_attention_state(const std::string& value) {
if (value == "read") return SessionAttentionState::Read;
if (value == "unread") return SessionAttentionState::Unread;
if (value == "in_progress") return SessionAttentionState::InProgress;
return std::nullopt;
}
SessionAttentionState session_attention_state_for(const SessionAttentionRecord& record) {
if (record.busy) return SessionAttentionState::InProgress;
return record.update_cursor > record.read_cursor
? SessionAttentionState::Unread
: SessionAttentionState::Read;
}
bool session_event_has_user_visible_output(SessionEventKind kind,
const nlohmann::json& payload) {
switch (kind) {
case SessionEventKind::Token:
case SessionEventKind::Reasoning:
case SessionEventKind::ToolStart:
case SessionEventKind::ToolUpdate:
case SessionEventKind::ToolEnd:
case SessionEventKind::PermissionRequest:
case SessionEventKind::QuestionRequest:
case SessionEventKind::Error:
return true;
case SessionEventKind::Message: {
const auto role = payload.value("role", std::string{});
return role != "user";
}
case SessionEventKind::TranscriptReplace:
return true;
case SessionEventKind::Usage:
case SessionEventKind::AgentProgress:
case SessionEventKind::ModelStepStart:
case SessionEventKind::ModelStepFinish:
case SessionEventKind::TurnDiff:
case SessionEventKind::PermissionClosed:
case SessionEventKind::QuestionClosed:
case SessionEventKind::SessionUpdated:
case SessionEventKind::BusyChanged:
case SessionEventKind::Done:
return false;
}
return false;
}
SessionAttentionRecord apply_session_attention_event(
SessionAttentionRecord record,
SessionEventKind kind,
const nlohmann::json& payload,
std::uint64_t cursor,
std::int64_t timestamp_ms) {
if (kind == SessionEventKind::BusyChanged && payload.is_object() && payload.contains("busy")) {
record.busy = payload.value("busy", false);
record.updated_at_ms = std::max(record.updated_at_ms, timestamp_ms);
}
if (session_event_has_user_visible_output(kind, payload)) {
record.update_cursor = std::max(record.update_cursor, cursor);
record.updated_at_ms = std::max(record.updated_at_ms, timestamp_ms);
}
return record;
}
SessionAttentionRecord mark_session_attention_read(
SessionAttentionRecord record,
std::uint64_t cursor,
std::int64_t timestamp_ms) {
const std::uint64_t effective_cursor = cursor == 0 ? record.update_cursor : cursor;
record.read_cursor = std::max(record.read_cursor, effective_cursor);
record.updated_at_ms = std::max(record.updated_at_ms, timestamp_ms);
return record;
}
} // namespace acecode