Forge
csharpdeeb25a2
1using System.Text.Json.Serialization;
2using CascadeIDE.Services;
3
4namespace CascadeIDE.Models;
5
6/// <summary>Контур AI в <c>[ai]</c> (<c>settings.toml</c>). ADR 0083: <c>mode</c> и вложенные таблицы.</summary>
7public sealed class AiSettings
8{
9 /// <summary>Один из: <c>local</c>, <c>acp</c>, <c>mcp_only</c>, <c>cloud</c>.</summary>
10 public string Mode { get; set; } = "local";
11
12 public AiLocalSettings Local { get; set; } = new();
13
14 public AiAcpSettings Acp { get; set; } = new();
15
16 public AiMcpOnlySettings McpOnly { get; set; } = new();
17
18 public AiCloudSettings Cloud { get; set; } = new();
19
20 public AiChatSettings Chat { get; set; } = new();
21
22 /// <summary>Ключ провайдера для существующего кода чата (Ollama, Anthropic, …).</summary>
23 public string ResolveEffectiveProviderUiKey()
24 {
25 return NormalizeMode(Mode) switch
26 {
27 "local" => "Ollama",
28 "acp" => "CursorACP",
29 "mcp_only" => "Ollama",
30 "cloud" => NormalizeCloudProvider(Cloud.ActiveProvider) switch
31 {
32 "anthropic" => "Anthropic",
33 "openai" => "OpenAI",
34 "deepseek" => "DeepSeek",
35 _ => "Anthropic"
36 },
37 _ => "Ollama"
38 };
39 }
40
41 public static string NormalizeMode(string? mode)
42 {
43 var m = (mode ?? "local").Trim().ToLowerInvariant();
44 return m is "local" or "acp" or "mcp_only" or "cloud" ? m : "local";
45 }
46
47 public static string NormalizeCloudProvider(string? p)
48 {
49 var x = (p ?? "anthropic").Trim().ToLowerInvariant();
50 return x is "anthropic" or "openai" or "deepseek" ? x : "anthropic";
51 }
52}
53
54/// <summary>TOML: <c>[ai.local]</c> и <c>[ai.local.ollama]</c>.</summary>
55public sealed class AiLocalSettings
56{
57 /// <summary>Например <c>ollama</c>; должен совпадать с активной подтаблицей.</summary>
58 public string Backend { get; set; } = "ollama";
59
60 public AiLocalOllamaSettings Ollama { get; set; } = new();
61}
62
63/// <summary>TOML: <c>[ai.local.ollama]</c>.</summary>
64public sealed class AiLocalOllamaSettings
65{
66 public string Model { get; set; } = "qwen2.5-coder:7b";
67}
68
69/// <summary>TOML: <c>[ai.acp]</c>.</summary>
70public sealed class AiAcpSettings
71{
72 public string CursorAcpPath { get; set; } = "";
73
74 /// <summary>TOML: <c>cursor_acp_path_env</c> — <c>PATH</c> или имя переменной с путём (ADR 0149).</summary>
75 public string CursorAcpPathEnv { get; set; } = "";
76
77 public string CursorAcpModelId { get; set; } = "";
78
79 public string ResolveCursorAcpPath() =>
80 SettingsEnvResolver.ResolveLaunchPath(CursorAcpPath, CursorAcpPathEnv);
81}
82
83/// <summary>TOML: <c>[ai.mcp_only]</c> — зарезервировано под флаги режима.</summary>
84public sealed class AiMcpOnlySettings
85{
86}
87
88/// <summary>TOML: <c>[ai.cloud]</c> и <c>[ai.cloud.*]</c>.</summary>
89public sealed class AiCloudSettings
90{
91 public string ActiveProvider { get; set; } = "anthropic";
92
93 [JsonPropertyName("anthropic")]
94 public AiCloudAnthropicSettings Anthropic { get; set; } = new();
95
96 [JsonPropertyName("openai")]
97 public AiCloudOpenAiSettings OpenAi { get; set; } = new();
98
99 [JsonPropertyName("deepseek")]
100 public AiCloudDeepSeekSettings DeepSeek { get; set; } = new();
101}
102
103public sealed class AiCloudAnthropicSettings
104{
105 public string Model { get; set; } = "claude-sonnet-4-20250514";
106}
107
108public sealed class AiCloudOpenAiSettings
109{
110 public string BaseUrl { get; set; } = "https://api.openai.com";
111
112 public string Model { get; set; } = "gpt-4o";
113}
114
115public sealed class AiCloudDeepSeekSettings
116{
117 public string BaseUrl { get; set; } = "https://api.deepseek.com";
118
119 public string Model { get; set; } = "deepseek-chat";
120}
121
122/// <summary>TOML: <c>[ai.chat]</c>.</summary>
123public sealed class AiChatSettings
124{
125 /// <summary><c>mfd</c> | <c>window</c>.</summary>
126 public string SettingsPresentation { get; set; } = "mfd";
127
128 public bool ShowThinkingInHistory { get; set; } = true;
129}
130
View only · write via MCP/CIDE