-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathstate_file.hpp
More file actions
120 lines (97 loc) · 5.15 KB
/
Copy pathstate_file.hpp
File metadata and controls
120 lines (97 loc) · 5.15 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
#pragma once
#include <optional>
// 跨会话进程状态(once-only 提示标记等),持久化到 ~/.acecode/state.json。
// 跟 config.json 区分:config.json 是用户编辑面,state.json 是 ACECode 自己
// 写的运行时状态(同一个数据目录下,通过 paths::resolve_data_dir(RunMode)
// 得到)。
//
// 设计取舍见 openspec/changes/add-legacy-terminal-fallback/design.md
// Decision 4。对外只暴露按用途划分的 typed helper,避免调用方直接耦合
// state.json 的整体 schema。
#include <cstdint>
#include <map>
#include <string>
#include <vector>
namespace acecode {
// 读 state.json 中 key 对应的 bool。文件不存在 / 损坏 / key 缺失 / 类型不符
// 都返回 false。永不抛异常。
bool read_state_flag(const std::string& key);
// Checked variant for callers that must report persistence failure (for
// example, an HTTP endpoint). The read-modify-write sequence is serialized
// with all other state_file operations in this process.
bool try_write_state_flag(const std::string& key, bool value);
struct StateFlagClaimResult {
bool claimed = false;
bool persisted = false;
};
// Atomically across threads and processes changes a missing/false flag to true.
// Exactly one concurrent caller observes claimed=true. State writers share the
// same interprocess lock so a later read-modify-write cannot erase the claim.
// A failed durable write never grants the claim.
StateFlagClaimResult try_claim_state_flag(const std::string& key);
// 测试专用:覆盖 state.json 的解析路径。传空串清除覆盖,回到从
// resolve_data_dir(get_run_mode()) 计算的默认。生产代码不应调用。
void set_state_file_path_for_test(const std::string& path);
// 写 state.json:把 key 设为 value,保留其它已有 key。
// 文件损坏(非合法 JSON)时整体覆盖并写一条 LOG_WARN。
// 写失败(权限 / 只读盘等)只 LOG_WARN,不阻断调用方。
//
// 用法:write_state_flag("legacy_terminal_hint_shown", true);
void write_state_flag(const std::string& key, bool value);
// 联网搜索 region 缓存(参见 add-web-search-tool 的 RegionDetector)。
// state.json 中的存储格式:
// { "web_search": { "region_detected": "global"|"cn",
// "region_detected_at_ms": <epoch ms> } }
struct WebSearchRegionCache {
std::string region; // "global" / "cn"
long long detected_at_ms = 0;
};
// 读取缓存的 region。文件不存在 / 字段缺失 / region 不是 global|cn → nullopt。
// detected_at_ms 即使为 0 / 缺失也接受(只表示来源未知,region 仍可信)。
std::optional<WebSearchRegionCache> read_web_search_region_cache();
// 写缓存的 region。原子写,保留其他 key。region 不在 {global, cn} 时静默不写。
void write_web_search_region_cache(const WebSearchRegionCache& cache);
// 删除 web_search 缓存(/websearch refresh 用)。其它 key 保留。
void clear_web_search_region_cache();
// Successful Provider model probes are cached by an opaque SHA-256 connection
// fingerprint. The state file stores only the fingerprint and probe output;
// provider URLs, API keys, and request headers never reach this helper.
struct ModelProbeCacheEntry {
std::vector<std::string> models;
std::map<std::string, int> context_windows;
std::int64_t probed_at_ms = 0;
};
// Missing/malformed entries return nullopt. The fingerprint must be exactly a
// 64-character hexadecimal SHA-256 digest.
std::optional<ModelProbeCacheEntry> read_model_probe_cache(
const std::string& connection_fingerprint);
// Atomically upserts one cache entry while preserving unrelated state and
// other connection fingerprints. Returns false for an invalid fingerprint or
// durable write failure.
bool write_model_probe_cache(
const std::string& connection_fingerprint,
const ModelProbeCacheEntry& entry);
// desktop multi-workspace: 上次活跃 workspace 的 cwd_hash。
// 读: 文件不存在 / 字段缺失 / 类型不符 → 空字符串。永不抛异常。
// 写: 原子写,保留其他 key;失败只 LOG_WARN 不阻断。
std::string read_last_active_workspace_hash();
void write_last_active_workspace_hash(const std::string& hash);
// desktop home page: 首页新建会话选择器上次选中的 workspace cwd_hash。
// 空字符串是有效值,表示"不使用工作区"。
std::string read_last_home_workspace_hash();
void write_last_home_workspace_hash(const std::string& hash);
// TUI slash-command adaptive ordering. The persisted shape is:
// { "tui_slash_command_usage": { "help": 3, "model": 7 } }
// Reads are tolerant: missing/malformed containers and invalid individual
// entries are ignored. Only aggregate command names/counts are stored.
std::map<std::string, std::uint64_t> read_tui_slash_command_usage();
struct SlashCommandUsageWriteResult {
// Updated count for the current process even when persistence failed.
std::uint64_t count = 0;
bool persisted = false;
};
// Atomically increment one command's durable count while preserving unrelated
// state.json keys. Counts saturate at uint64_t max rather than overflowing.
SlashCommandUsageWriteResult record_tui_slash_command_use(
const std::string& command_name);
} // namespace acecode