-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSkillManagementService.cs
More file actions
139 lines (124 loc) · 5 KB
/
Copy pathSkillManagementService.cs
File metadata and controls
139 lines (124 loc) · 5 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
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text.Json;
namespace TimeTask
{
public class SkillDefinition
{
public string SkillId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Scenario { get; set; }
public bool Enabled { get; set; }
}
/// <summary>
/// 思维工具开关的持久化。
/// 历史实现把用户选择写进 exe 旁的 TimeTask.exe.config:
/// 装在 Program Files 时会静默失败(无写权限),便携盘上则污染程序目录。
/// 现改为写入用户数据目录的 JSON(原子写 + .bak),旧 appSettings 值仅作一次迁移读取。
/// </summary>
public static class SkillManagementService
{
private const string EnabledSkillIdsKey = "EnabledSkillIds";
private static string StatePath => AppPaths.GetDataFile("skill_settings.json");
public static readonly string[] AllowedSkillIds = ThinkingToolAdvisor.GetAllowedSkillIds();
public static List<SkillDefinition> GetSkillDefinitions()
{
var enabled = LoadEnabledSkillIds();
var defs = ThinkingToolAdvisor.GetDefinitions();
return defs
.Select(def => new SkillDefinition
{
SkillId = def.SkillId,
Title = def.Title,
Description = def.Description,
Scenario = def.Scenario,
Enabled = enabled.Contains(def.SkillId)
})
.ToList();
}
public static HashSet<string> LoadEnabledSkillIds()
{
try
{
// 1) 新存储:用户数据目录 JSON(损坏自动回退 .bak)
var stored = JsonStore.Load(StatePath, json => JsonSerializer.Deserialize<List<string>>(json));
if (stored != null)
{
return ToEnabledSet(stored);
}
// 2) 旧存储:exe 配置里的 appSettings(只读迁移,不再写回)
string raw = ConfigurationManager.AppSettings[EnabledSkillIdsKey];
if (!string.IsNullOrWhiteSpace(raw))
{
var ids = raw.Split(new[] { ',', ';', '|', ' ' }, StringSplitOptions.RemoveEmptyEntries);
return ToEnabledSet(ids);
}
// 3) 默认:全部启用
return DefaultSet();
}
catch
{
return DefaultSet();
}
}
private static HashSet<string> ToEnabledSet(IEnumerable<string> ids)
{
var filtered = ids
.Where(x => !string.IsNullOrWhiteSpace(x))
.Select(x => x.Trim().ToLowerInvariant())
.Where(x => AllowedSkillIds.Contains(x, StringComparer.OrdinalIgnoreCase))
.ToList();
if (filtered.Count == 0)
{
return DefaultSet();
}
return new HashSet<string>(filtered, StringComparer.OrdinalIgnoreCase);
}
private static HashSet<string> DefaultSet()
{
return new HashSet<string>(AllowedSkillIds, StringComparer.OrdinalIgnoreCase);
}
public static List<LlmSkillRecommendation> FilterEnabled(List<LlmSkillRecommendation> skills)
{
if (skills == null || skills.Count == 0)
return new List<LlmSkillRecommendation>();
var enabled = LoadEnabledSkillIds();
return skills
.Where(s => s != null && !string.IsNullOrWhiteSpace(s.SkillId))
.Where(s => enabled.Contains(s.SkillId.Trim()))
.ToList();
}
public static void SaveEnabledSkillIds(IEnumerable<string> enabledIds)
{
var target = (enabledIds ?? Enumerable.Empty<string>())
.Where(x => !string.IsNullOrWhiteSpace(x))
.Select(x => x.Trim().ToLowerInvariant())
.Where(x => AllowedSkillIds.Contains(x, StringComparer.OrdinalIgnoreCase))
.Distinct(StringComparer.OrdinalIgnoreCase)
.ToList();
if (target.Count == 0)
{
target = new List<string>(AllowedSkillIds);
}
try
{
string dir = Path.GetDirectoryName(StatePath);
if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
AtomicFile.WriteAllText(StatePath, JsonSerializer.Serialize(target));
}
catch (Exception ex)
{
// 保存失败要可见:这是用户在界面上明确做的选择
VoiceRuntimeLog.Error("保存思维工具开关失败。", ex);
throw;
}
}
}
}