-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathlocal_session_client.cpp
More file actions
153 lines (134 loc) · 5.55 KB
/
Copy pathlocal_session_client.cpp
File metadata and controls
153 lines (134 loc) · 5.55 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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include "local_session_client.hpp"
#include "ask_user_question_prompter.hpp"
#include "session_storage.hpp"
#include "../utils/logger.hpp"
namespace acecode {
std::string LocalSessionClient::create_session(const SessionOptions& opts) {
return registry_.create(opts);
}
bool LocalSessionClient::resume_session(const std::string& id, const SessionOptions& opts) {
return registry_.resume(id, opts);
}
std::vector<SessionInfo> LocalSessionClient::list_sessions() {
// v1 简化: 只返回内存活跃的。磁盘历史由 HTTP /api/sessions 单独的
// SessionStorage::list_sessions 路径合并(后续 Section 9)。
return registry_.list_active();
}
void LocalSessionClient::destroy_session(const std::string& id) {
registry_.destroy(id);
}
LocalSessionClient::SubscriptionId
LocalSessionClient::subscribe(const std::string& session_id,
EventListener on_event,
std::uint64_t since_seq) {
auto entry = registry_.acquire(session_id);
if (!entry || !entry->loop) return 0;
return entry->loop->events().subscribe(std::move(on_event), since_seq);
}
void LocalSessionClient::unsubscribe(const std::string& session_id, SubscriptionId sub) {
auto entry = registry_.acquire(session_id);
if (!entry || !entry->loop) return;
entry->loop->events().unsubscribe(sub);
}
bool LocalSessionClient::send_input(const std::string& session_id, const std::string& text) {
return send_input(session_id, text, std::string{});
}
bool LocalSessionClient::send_input(const std::string& session_id,
const std::string& text,
const std::string& display_text) {
UserInput input;
input.text = text;
input.display_text = display_text;
return send_input(session_id, input);
}
bool LocalSessionClient::send_input(const std::string& session_id, const UserInput& input) {
auto entry = registry_.acquire(session_id);
if (!entry || !entry->loop) {
LOG_WARN("[client] send_input on unknown session " + session_id);
return false;
}
// Ordinary submissions lazily refresh only before enqueue. Steering and
// interruption deliberately remain unhooked because they target the
// provider already captured by the active turn.
if (auto reload = registry_.reload_model_profile(session_id, false)) {
if (!reload->ok) {
LOG_WARN("[client] model profile reload failed; using current provider");
entry->loop->emit_system_message(
"Warning: model profile reload failed; continuing with the current provider.");
} else if (!reload->warning.empty()) {
entry->loop->emit_system_message("Warning: " + reload->warning);
}
}
registry_.maybe_start_auto_title(session_id, input);
entry->loop->submit(input);
return true;
}
TurnSteerResult LocalSessionClient::steer_input(
const std::string& session_id,
const std::string& expected_turn_id,
const UserInput& input) {
auto entry = registry_.acquire(session_id);
if (!entry || !entry->loop) {
LOG_WARN("[client] steer_input on unknown session " + session_id);
return {
TurnSteerStatus::UnknownSession,
{},
"unknown session",
};
}
return entry->loop->steer_input(expected_turn_id, input);
}
TurnSteerResult LocalSessionClient::interrupt_turn(
const std::string& session_id,
const std::string& expected_turn_id,
const UserInput& input) {
auto entry = registry_.acquire(session_id);
if (!entry || !entry->loop) {
LOG_WARN("[client] interrupt_turn on unknown session " + session_id);
return {
TurnSteerStatus::UnknownSession,
{},
"unknown session",
};
}
return entry->loop->interrupt_turn(expected_turn_id, input);
}
BuiltinCommandResult LocalSessionClient::execute_builtin_command(
const std::string& session_id,
const BuiltinCommandRequest& request) {
return registry_.execute_builtin_command(session_id, request);
}
void LocalSessionClient::respond_permission(const std::string& session_id,
const PermissionDecision& decision) {
auto entry = registry_.acquire(session_id);
if (!entry || !entry->prompter) {
LOG_WARN("[client] respond_permission on unknown session " + session_id);
return;
}
entry->prompter->notify_decision(decision.request_id, decision.choice);
}
QuestionResponseStatus LocalSessionClient::respond_question(
const std::string& session_id,
const std::string& request_id,
const AskUserQuestionResponse& response) {
auto entry = registry_.acquire(session_id);
if (!entry || !entry->ask_prompter) {
LOG_WARN("[client] respond_question on unknown session " + session_id);
return QuestionResponseStatus::UnknownSession;
}
return entry->ask_prompter->notify_response(request_id, response)
? QuestionResponseStatus::Accepted
: QuestionResponseStatus::Closed;
}
std::optional<std::vector<PendingQuestionRequestSnapshot>>
LocalSessionClient::snapshot_pending_questions(const std::string& session_id) {
auto entry = registry_.acquire(session_id);
if (!entry || !entry->ask_prompter) return std::nullopt;
return entry->ask_prompter->snapshot_pending_question_requests();
}
void LocalSessionClient::abort(const std::string& session_id) {
auto entry = registry_.acquire(session_id);
if (!entry || !entry->loop) return;
entry->loop->abort();
}
} // namespace acecode