-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathproxy_command.cpp
More file actions
131 lines (115 loc) · 4.55 KB
/
Copy pathproxy_command.cpp
File metadata and controls
131 lines (115 loc) · 4.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
// /proxy 命令实现。所有运行时操作都委托给 network::proxy_resolver();
// 文案构造抽到 format_proxy_display() 以便单测覆盖。
#include "commands/proxy_command.hpp"
#include "network/proxy_resolver.hpp"
#include <mutex>
#include <sstream>
#include <string>
namespace acecode {
namespace {
std::string trim(const std::string& s) {
size_t start = 0;
while (start < s.size() && std::isspace(static_cast<unsigned char>(s[start]))) ++start;
size_t end = s.size();
while (end > start && std::isspace(static_cast<unsigned char>(s[end - 1]))) --end;
return s.substr(start, end - start);
}
void emit(CommandContext& ctx, const std::string& text) {
{
std::lock_guard<std::mutex> lk(ctx.state.mu);
ctx.state.conversation.push_back({"system", text, false});
ctx.state.chat_follow_tail = true;
}
if (ctx.post_event) ctx.post_event();
}
ProxyDisplaySnapshot snapshot_for_display(const AppConfig& cfg) {
ProxyDisplaySnapshot snap;
// 用一个代表性的 https url 让 resolver 决定该走哪一档代理 —— 启动横幅 +
// /proxy 命令显示的就是"对 LLM API 的代理"语义,所以选 https。
auto resolved = network::proxy_resolver().effective("https://example.com");
snap.effective_url = resolved.url;
snap.source = resolved.source;
snap.mode = cfg.network.proxy_mode;
auto fb = network::proxy_resolver().fallback_info_snapshot();
snap.reachable = !fb.active;
if (fb.active) {
snap.reachable_reason = fb.reason;
snap.original_proxy_url = fb.original_url;
snap.original_proxy_source = fb.original_source;
}
return snap;
}
void cmd_proxy(CommandContext& ctx, const std::string& args) {
std::string sub = trim(args);
if (sub == "refresh") {
network::proxy_resolver().refresh();
emit(ctx, "Proxy detection refreshed.\n" +
format_proxy_display(snapshot_for_display(ctx.config)));
return;
}
if (sub == "off") {
network::proxy_resolver().set_session_override_off();
emit(ctx, "Proxy temporarily disabled (session-only).\n" +
format_proxy_display(snapshot_for_display(ctx.config)));
return;
}
if (sub == "reset") {
network::proxy_resolver().reset_session_override();
emit(ctx, "Proxy session override cleared.\n" +
format_proxy_display(snapshot_for_display(ctx.config)));
return;
}
if (sub.rfind("set", 0) == 0) {
// /proxy set <url>
std::string rest = trim(sub.size() > 3 ? sub.substr(3) : "");
if (rest.empty()) {
emit(ctx, "Usage: /proxy set <url>");
return;
}
// normalize 之前先脱敏:用户输入直接带凭据时,日志里不要原样保留。
std::string normalized = network::normalize_proxy_url(rest);
if (normalized.empty()) {
emit(ctx, "Invalid proxy URL: " + network::redact_credentials(rest));
return;
}
network::proxy_resolver().set_session_override_url(normalized);
emit(ctx, "Proxy temporarily set to " +
network::redact_credentials(normalized) +
" (session-only).\n" +
format_proxy_display(snapshot_for_display(ctx.config)));
return;
}
if (!sub.empty() && sub != "show") {
emit(ctx, "Unknown subcommand. Usage: /proxy [refresh|off|set <url>|reset]");
return;
}
// 默认:无参 / "show" → 显示当前状态
emit(ctx, format_proxy_display(snapshot_for_display(ctx.config)));
}
} // anonymous namespace
std::string format_proxy_display(const ProxyDisplaySnapshot& snap) {
std::ostringstream oss;
if (snap.effective_url.empty()) {
oss << "Effective proxy : direct";
} else {
oss << "Effective proxy : " << network::redact_credentials(snap.effective_url);
}
oss << "\nSource : " << snap.source
<< "\nMode (config) : " << snap.mode
<< "\nReachable : "
<< (snap.reachable ? std::string("yes")
: "no (" + snap.reachable_reason + ")");
if (!snap.reachable && !snap.original_proxy_url.empty()) {
oss << "\nOriginal proxy : " << snap.original_proxy_url
<< " (" << snap.original_proxy_source << ")";
}
return oss.str();
}
void register_proxy_command(CommandRegistry& registry) {
registry.register_command({
"proxy",
"Show or temporarily switch the HTTP proxy used for LLM/API requests",
cmd_proxy,
});
}
} // namespace acecode