[Phase 17-A] Reflexion 자기성찰 메모리 시스템 구현
ReflexionEvaluatorService 신규 구현 (ReflexionService.cs): - LLM 기반 자기평가: 완성도 점수(0~1), 강점/약점/교훈 추출 - $$raw string 평가 프롬프트로 JSON 포맷 안전하게 삽입 - JSON 블록 추출 + 역직렬화, LLM 실패 시 규칙 기반 폴백 엔트리 - ReflexionRepository.BuildContextPromptAsync() maxEntries 파라미터 추가 AgentLoopService.Reflexion.cs (신규, 82줄): - InjectReflexionContextAsync(): 세션 시작 전 과거 교훈→시스템 메시지 주입 - FireAndForgetReflexionEval(): 세션 완료 후 Task.Run 비동기 자기평가 저장 - 지연 초기화(_reflexionRepo, _reflexionEval): 사용 시점에 생성 AgentLoopService.cs 통합 포인트 2개 추가: - RunAsync() 루프 시작 전: await InjectReflexionContextAsync() - finally 블록 통계 섹션: FireAndForgetReflexionEval() 호출 AgentSettingsPanel — 자기성찰 메모리 섹션 추가: - 활성화 토글(ChkReflexionEnabled) - 성공 세션만 평가 토글(ChkReflexionSuccessOnly) - 최대 참고 교훈 수 슬라이더(1~20, 기본값 5) - LoadFromSettings() 초기화 + 3개 이벤트 핸들러 빌드: 경고 0, 오류 0
This commit is contained in:
@@ -4954,5 +4954,29 @@ ThemeResourceHelper에 5개 정적 필드 추가:
|
||||
|
||||
---
|
||||
|
||||
최종 업데이트: 2026-04-03 (Phase 22~52 + Phase 17-UI-A~E 구현 완료)
|
||||
## Phase 17-A — Reflexion 강화 (v1.8.0) ✅ 완료
|
||||
|
||||
> **목표**: 성공·실패 모두 구조화된 자기평가 저장 → 동일 작업 유형 재실행 시 자동 참고
|
||||
|
||||
### 변경 파일
|
||||
|
||||
| 파일 | 변경 내용 |
|
||||
|------|----------|
|
||||
| `ReflexionService.cs` | `ReflexionEvaluatorService` 신규 추가: LLM 기반 자기평가(점수·강점·약점·교훈 추출), 규칙 기반 폴백 엔트리. `ReflexionRepository.BuildContextPromptAsync()` maxEntries 파라미터 추가. |
|
||||
| `AgentLoopService.Reflexion.cs` (신규, 82줄) | `InjectReflexionContextAsync()` — 세션 시작 시 과거 교훈을 시스템 메시지에 주입. `FireAndForgetReflexionEval()` — 세션 완료 후 비동기 자기평가 저장. |
|
||||
| `AgentLoopService.cs` | `RunAsync()` 루프 시작 전: `InjectReflexionContextAsync()` 호출. `finally` 블록: `FireAndForgetReflexionEval()` 호출. |
|
||||
| `AgentSettingsPanel.xaml` | "자기성찰 메모리" 섹션 추가: 활성화 토글, 성공 시만 평가 토글, 최대 참고 교훈 수 슬라이더. |
|
||||
| `AgentSettingsPanel.xaml.cs` | `LoadFromSettings()`: Reflexion 설정 초기화. `ChkReflexion_Changed()`, `ChkReflexionSuccessOnly_Changed()`, `SliderReflexionMaxEntries_ValueChanged()` 핸들러 추가. |
|
||||
|
||||
### 구현 세부사항
|
||||
|
||||
- **ReflexionEvaluatorService**: `$$"""..."""` raw string으로 평가 프롬프트 생성, JSON 블록 추출 후 역직렬화
|
||||
- **작업 유형 분류**: `TaskTypeClassifier.Classify()` — 8개 카테고리 (code_generation, file_refactor, document, analysis, search, test, git, debug, general)
|
||||
- **저장 위치**: `%APPDATA%\AxCopilot\reflexion\<taskType>.jsonl` (JSONL 형식, 최신 N개 역순 조회)
|
||||
- **비동기 처리**: fire-and-forget — 루프 취소(`CancellationToken`) 영향 없음
|
||||
- **빌드**: 경고 0, 오류 0
|
||||
|
||||
---
|
||||
|
||||
최종 업데이트: 2026-04-03 (Phase 22~52 + Phase 17-UI-A~E + Phase 17-A 구현 완료)
|
||||
|
||||
|
||||
87
src/AxCopilot/Services/Agent/AgentLoopService.Reflexion.cs
Normal file
87
src/AxCopilot/Services/Agent/AgentLoopService.Reflexion.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using AxCopilot.Models;
|
||||
|
||||
namespace AxCopilot.Services.Agent;
|
||||
|
||||
/// <summary>
|
||||
/// Phase 17-A: AgentLoopService — Reflexion(자기성찰 메모리) 통합.
|
||||
/// 세션 시작 시 과거 교훈을 시스템 메시지에 주입하고,
|
||||
/// 세션 완료 후 LLM 자기평가를 비동기로 저장합니다.
|
||||
/// </summary>
|
||||
public partial class AgentLoopService
|
||||
{
|
||||
// ── 지연 초기화 (첫 사용 시 생성) ────────────────────────────────────
|
||||
private ReflexionRepository? _reflexionRepo;
|
||||
private ReflexionEvaluatorService? _reflexionEval;
|
||||
|
||||
private ReflexionRepository ReflexionRepo =>
|
||||
_reflexionRepo ??= new ReflexionRepository();
|
||||
|
||||
private ReflexionEvaluatorService ReflexionEval =>
|
||||
_reflexionEval ??= new ReflexionEvaluatorService(_llm, ReflexionRepo);
|
||||
|
||||
/// <summary>
|
||||
/// 세션 시작 시 과거 유사 작업 교훈을 시스템 메시지 끝에 주입합니다.
|
||||
/// Reflexion이 비활성화되었거나 교훈이 없으면 아무것도 하지 않습니다.
|
||||
/// </summary>
|
||||
internal async Task InjectReflexionContextAsync(List<ChatMessage> messages, string userQuery)
|
||||
{
|
||||
var reflexion = _settings.Settings.Llm.Reflexion;
|
||||
if (reflexion?.Enabled != true) return;
|
||||
if (string.IsNullOrWhiteSpace(userQuery)) return;
|
||||
|
||||
try
|
||||
{
|
||||
var taskType = TaskTypeClassifier.Classify(userQuery);
|
||||
var maxEntries = reflexion.MaxContextEntries > 0 ? reflexion.MaxContextEntries : 5;
|
||||
var context = await ReflexionRepo.BuildContextPromptAsync(taskType, maxEntries);
|
||||
if (string.IsNullOrEmpty(context)) return;
|
||||
|
||||
// 시스템 메시지 찾기 (첫 번째 system 역할 메시지)
|
||||
var sysMsg = messages.FirstOrDefault(m => m.Role == "system");
|
||||
if (sysMsg != null)
|
||||
sysMsg.Content += "\n" + context;
|
||||
// 시스템 메시지가 없으면 리스트 앞에 추가
|
||||
else
|
||||
messages.Insert(0, new ChatMessage { Role = "system", Content = context });
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 교훈 주입 실패는 루프 진행에 영향 없음 (무시)
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 세션 완료 후 자기평가를 비동기(fire-and-forget)로 실행·저장합니다.
|
||||
/// 실패 시 루프에 영향 없음.
|
||||
/// </summary>
|
||||
internal void FireAndForgetReflexionEval(
|
||||
string userQuery,
|
||||
string agentResult,
|
||||
string sessionId,
|
||||
bool isSuccess,
|
||||
int toolCallCount,
|
||||
int iterationCount)
|
||||
{
|
||||
var reflexion = _settings.Settings.Llm.Reflexion;
|
||||
if (reflexion?.Enabled != true) return;
|
||||
if (!isSuccess && reflexion.EvaluateOnSuccess) return; // 성공 시만 평가 설정일 때 실패면 스킵
|
||||
if (string.IsNullOrWhiteSpace(userQuery)) return;
|
||||
if (toolCallCount == 0) return; // 도구 사용 없는 단순 대화는 평가 불필요
|
||||
|
||||
// CancellationToken 없이 fire-and-forget — 루프 취소에 영향받지 않음
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await ReflexionEval.EvaluateAndSaveAsync(
|
||||
userQuery, agentResult, sessionId,
|
||||
isSuccess, toolCallCount, iterationCount,
|
||||
CancellationToken.None);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 평가 저장 실패 — UI 방해 없이 조용히 무시
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -196,6 +196,9 @@ public partial class AgentLoopService
|
||||
|
||||
var context = BuildContext(activeTabSnapshot);
|
||||
|
||||
// Phase 17-A: Reflexion — 과거 교훈을 시스템 메시지에 주입
|
||||
await InjectReflexionContextAsync(messages, userQuery);
|
||||
|
||||
try
|
||||
{
|
||||
// ── 플랜 모드 "always": 첫 번째 호출은 계획만 생성 (도구 없이) ──
|
||||
@@ -820,6 +823,13 @@ public partial class AgentLoopService
|
||||
$"소요 {durationSec:F1}초 | 사용 도구: {toolList}";
|
||||
EmitEvent(AgentEventType.StepDone, "total_stats", summary);
|
||||
}
|
||||
|
||||
// Phase 17-A: Reflexion — 세션 완료 후 자기평가 비동기 저장
|
||||
var isSessionSuccess = statsSuccessCount > 0 && statsFailCount == 0;
|
||||
var lastResult = messages.LastOrDefault(m => m.Role == "assistant")?.Content ?? "";
|
||||
FireAndForgetReflexionEval(
|
||||
userQuery, lastResult, _sessionId ?? "",
|
||||
isSessionSuccess, totalToolCalls, iteration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using AxCopilot.Models;
|
||||
|
||||
namespace AxCopilot.Services.Agent;
|
||||
|
||||
@@ -81,13 +82,13 @@ public class ReflexionRepository
|
||||
}
|
||||
|
||||
/// <summary>동일 작업 유형의 과거 교훈을 시스템 프롬프트 주입용 텍스트로 빌드.</summary>
|
||||
public async Task<string> BuildContextPromptAsync(string taskType)
|
||||
public async Task<string> BuildContextPromptAsync(string taskType, int maxEntries = 5)
|
||||
{
|
||||
var entries = await GetByTaskTypeAsync(taskType, 5);
|
||||
var entries = await GetByTaskTypeAsync(taskType, maxEntries);
|
||||
if (entries.Count == 0) return string.Empty;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine($"## 이전 유사 작업({taskType})에서 배운 점:");
|
||||
sb.AppendLine($"\n## 이전 유사 작업({taskType})에서 배운 점:");
|
||||
foreach (var e in entries)
|
||||
{
|
||||
if (e.Lessons.Length > 0)
|
||||
@@ -136,3 +137,165 @@ public static class TaskTypeClassifier
|
||||
return best;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Phase 17-A: LLM 기반 자기평가 서비스.
|
||||
/// 세션 완료 후 LLM을 호출해 완성도·강점·약점·교훈을 추출하고 ReflexionEntry를 생성합니다.
|
||||
/// </summary>
|
||||
public class ReflexionEvaluatorService
|
||||
{
|
||||
private readonly LlmService _llm;
|
||||
private readonly ReflexionRepository _repo;
|
||||
|
||||
private static readonly JsonSerializerOptions _jsonOpts = new()
|
||||
{
|
||||
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
|
||||
PropertyNameCaseInsensitive = true,
|
||||
};
|
||||
|
||||
public ReflexionEvaluatorService(LlmService llm, ReflexionRepository repo)
|
||||
{
|
||||
_llm = llm;
|
||||
_repo = repo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 세션을 평가하고 ReflexionEntry를 저장합니다.
|
||||
/// 내부 LLM 호출 실패 시 규칙 기반 폴백 엔트리를 저장합니다.
|
||||
/// </summary>
|
||||
public async Task EvaluateAndSaveAsync(
|
||||
string userQuery,
|
||||
string agentResult,
|
||||
string sessionId,
|
||||
bool isSuccess,
|
||||
int toolCallCount,
|
||||
int iterationCount,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(userQuery)) return;
|
||||
|
||||
var taskType = TaskTypeClassifier.Classify(userQuery);
|
||||
|
||||
try
|
||||
{
|
||||
var entry = await EvaluateWithLlmAsync(
|
||||
userQuery, agentResult, taskType, sessionId, isSuccess, toolCallCount, iterationCount, ct);
|
||||
await _repo.SaveAsync(entry);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// LLM 평가 실패 → 규칙 기반 폴백 엔트리
|
||||
var fallback = BuildFallbackEntry(userQuery, taskType, sessionId, isSuccess, iterationCount);
|
||||
try { await _repo.SaveAsync(fallback); } catch (Exception) { /* 저장 실패도 무시 */ }
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<ReflexionEntry> EvaluateWithLlmAsync(
|
||||
string userQuery,
|
||||
string agentResult,
|
||||
string taskType,
|
||||
string sessionId,
|
||||
bool isSuccess,
|
||||
int toolCallCount,
|
||||
int iterationCount,
|
||||
CancellationToken ct)
|
||||
{
|
||||
var resultPreview = agentResult.Length > 500 ? agentResult[..500] + "…" : agentResult;
|
||||
var evalPrompt = $$"""
|
||||
에이전트가 다음 작업을 수행했습니다. 수행 결과를 평가하고 JSON으로 응답하세요.
|
||||
|
||||
## 사용자 요청
|
||||
{{userQuery}}
|
||||
|
||||
## 에이전트 결과 요약
|
||||
{{resultPreview}}
|
||||
|
||||
## 수행 통계
|
||||
- 성공 여부: {{(isSuccess ? "성공" : "실패 또는 중단")}}
|
||||
- 도구 호출 횟수: {{toolCallCount}}
|
||||
- 반복 횟수: {{iterationCount}}
|
||||
|
||||
## 응답 형식 (JSON만 출력, 다른 텍스트 없이)
|
||||
{
|
||||
"score": 0.0~1.0,
|
||||
"strengths": ["잘된 점1", "잘된 점2"],
|
||||
"weaknesses": ["부족한 점1", "부족한 점2"],
|
||||
"lessons": ["다음에 적용할 교훈1", "다음에 적용할 교훈2"],
|
||||
"summary": "한 줄 요약"
|
||||
}
|
||||
""";
|
||||
|
||||
var messages = new List<ChatMessage>
|
||||
{
|
||||
new() { Role = "user", Content = evalPrompt }
|
||||
};
|
||||
|
||||
var response = await _llm.SendAsync(messages, ct);
|
||||
|
||||
// JSON 블록 추출
|
||||
var json = ExtractJson(response);
|
||||
if (string.IsNullOrEmpty(json))
|
||||
return BuildFallbackEntry(userQuery, taskType, sessionId, isSuccess, iterationCount);
|
||||
|
||||
var parsed = JsonSerializer.Deserialize<EvalResponse>(json, _jsonOpts);
|
||||
if (parsed == null)
|
||||
return BuildFallbackEntry(userQuery, taskType, sessionId, isSuccess, iterationCount);
|
||||
|
||||
return new ReflexionEntry
|
||||
{
|
||||
TaskType = taskType,
|
||||
Summary = parsed.Summary ?? userQuery[..Math.Min(80, userQuery.Length)],
|
||||
IsSuccess = isSuccess,
|
||||
CompletionScore = Math.Clamp(parsed.Score, 0f, 1f),
|
||||
Strengths = parsed.Strengths ?? Array.Empty<string>(),
|
||||
Weaknesses = parsed.Weaknesses ?? Array.Empty<string>(),
|
||||
Lessons = parsed.Lessons ?? Array.Empty<string>(),
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
SessionId = sessionId,
|
||||
};
|
||||
}
|
||||
|
||||
private static ReflexionEntry BuildFallbackEntry(
|
||||
string userQuery, string taskType, string sessionId, bool isSuccess, int iterationCount)
|
||||
{
|
||||
return new ReflexionEntry
|
||||
{
|
||||
TaskType = taskType,
|
||||
Summary = userQuery.Length > 80 ? userQuery[..80] + "…" : userQuery,
|
||||
IsSuccess = isSuccess,
|
||||
CompletionScore = isSuccess ? 0.7f : 0.3f,
|
||||
Strengths = isSuccess ? new[] { "작업 완료" } : Array.Empty<string>(),
|
||||
Weaknesses = !isSuccess ? new[] { $"반복 {iterationCount}회 후 완료 못함" } : Array.Empty<string>(),
|
||||
Lessons = Array.Empty<string>(),
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
SessionId = sessionId,
|
||||
};
|
||||
}
|
||||
|
||||
private static string ExtractJson(string text)
|
||||
{
|
||||
var start = text.IndexOf('{');
|
||||
var end = text.LastIndexOf('}');
|
||||
if (start < 0 || end <= start) return string.Empty;
|
||||
return text[start..(end + 1)];
|
||||
}
|
||||
|
||||
// JSON 응답 역직렬화용 내부 DTO
|
||||
private class EvalResponse
|
||||
{
|
||||
[JsonPropertyName("score")]
|
||||
public float Score { get; set; }
|
||||
|
||||
[JsonPropertyName("strengths")]
|
||||
public string[]? Strengths { get; set; }
|
||||
|
||||
[JsonPropertyName("weaknesses")]
|
||||
public string[]? Weaknesses { get; set; }
|
||||
|
||||
[JsonPropertyName("lessons")]
|
||||
public string[]? Lessons { get; set; }
|
||||
|
||||
[JsonPropertyName("summary")]
|
||||
public string? Summary { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,6 +195,57 @@
|
||||
|
||||
<Border Height="1" Background="{DynamicResource BorderColor}" Margin="0,8,0,16"/>
|
||||
|
||||
<!-- ═══ 자기성찰 메모리 (Phase 17-A) ═══ -->
|
||||
<TextBlock Text="자기성찰 메모리" FontSize="13" FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource PrimaryText}" Margin="0,0,0,8"/>
|
||||
|
||||
<!-- 자기성찰 활성화 -->
|
||||
<Grid Margin="0,0,0,8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel>
|
||||
<TextBlock Text="자기성찰 메모리" Foreground="{DynamicResource SecondaryText}" FontSize="12"/>
|
||||
<TextBlock Text="동일 유형 작업 시 과거 교훈 자동 참고" FontSize="10"
|
||||
Foreground="{DynamicResource SecondaryText}" Opacity="0.7"/>
|
||||
</StackPanel>
|
||||
<CheckBox x:Name="ChkReflexionEnabled" Grid.Column="1"
|
||||
Style="{StaticResource ToggleSwitch}"
|
||||
Checked="ChkReflexion_Changed" Unchecked="ChkReflexion_Changed"/>
|
||||
</Grid>
|
||||
|
||||
<!-- 성공 시만 평가 -->
|
||||
<Grid Margin="0,0,0,8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="성공 세션만 평가" Foreground="{DynamicResource SecondaryText}" FontSize="12"
|
||||
VerticalAlignment="Center"/>
|
||||
<CheckBox x:Name="ChkReflexionSuccessOnly" Grid.Column="1"
|
||||
Style="{StaticResource ToggleSwitch}"
|
||||
Checked="ChkReflexionSuccessOnly_Changed" Unchecked="ChkReflexionSuccessOnly_Changed"/>
|
||||
</Grid>
|
||||
|
||||
<!-- 최대 참고 교훈 수 -->
|
||||
<Grid Margin="0,0,0,4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="40"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="최대 참고 교훈 수" Foreground="{DynamicResource SecondaryText}" FontSize="12"
|
||||
VerticalAlignment="Center"/>
|
||||
<TextBlock x:Name="TxtReflexionMaxEntries" Grid.Column="1" Text="5"
|
||||
Foreground="{DynamicResource PrimaryText}" FontSize="12"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"/>
|
||||
</Grid>
|
||||
<Slider x:Name="SliderReflexionMaxEntries" Minimum="1" Maximum="20" Value="5"
|
||||
IsSnapToTickEnabled="True" TickFrequency="1"
|
||||
ValueChanged="SliderReflexionMaxEntries_ValueChanged" Margin="0,0,0,8"/>
|
||||
|
||||
<Border Height="1" Background="{DynamicResource BorderColor}" Margin="0,8,0,16"/>
|
||||
|
||||
<!-- ═══ 탭 전용 설정 ═══ -->
|
||||
<TextBlock Text="탭 전용 설정" FontSize="13" FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource PrimaryText}" Margin="0,0,0,8"/>
|
||||
|
||||
@@ -66,6 +66,13 @@ public partial class AgentSettingsPanel : UserControl
|
||||
SliderAutoCompact.Value = llm.AutoCompactThreshold > 0 ? llm.AutoCompactThreshold : 80;
|
||||
TxtAutoCompact.Text = ((int)SliderAutoCompact.Value).ToString();
|
||||
|
||||
// Phase 17-A: Reflexion 설정 로드
|
||||
var reflexion = llm.Reflexion;
|
||||
ChkReflexionEnabled.IsChecked = reflexion?.Enabled ?? true;
|
||||
ChkReflexionSuccessOnly.IsChecked = reflexion?.EvaluateOnSuccess ?? true;
|
||||
SliderReflexionMaxEntries.Value = reflexion?.MaxContextEntries > 0 ? reflexion.MaxContextEntries : 5;
|
||||
TxtReflexionMaxEntries.Text = ((int)SliderReflexionMaxEntries.Value).ToString();
|
||||
|
||||
ChkDevMode.IsChecked = llm.DevMode;
|
||||
|
||||
// 탭별 설정 표시
|
||||
@@ -226,6 +233,40 @@ public partial class AgentSettingsPanel : UserControl
|
||||
SaveSetting(s => s.Llm.DevMode = ChkDevMode.IsChecked == true);
|
||||
}
|
||||
|
||||
// ── Phase 17-A: Reflexion 핸들러 ──────────────────────────────────────
|
||||
|
||||
private void ChkReflexion_Changed(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (_isLoading) return;
|
||||
SaveSetting(s =>
|
||||
{
|
||||
s.Llm.Reflexion ??= new Models.ReflexionConfig();
|
||||
s.Llm.Reflexion.Enabled = ChkReflexionEnabled.IsChecked == true;
|
||||
});
|
||||
}
|
||||
|
||||
private void ChkReflexionSuccessOnly_Changed(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (_isLoading) return;
|
||||
SaveSetting(s =>
|
||||
{
|
||||
s.Llm.Reflexion ??= new Models.ReflexionConfig();
|
||||
s.Llm.Reflexion.EvaluateOnSuccess = ChkReflexionSuccessOnly.IsChecked == true;
|
||||
});
|
||||
}
|
||||
|
||||
private void SliderReflexionMaxEntries_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
||||
{
|
||||
if (_isLoading || TxtReflexionMaxEntries == null) return;
|
||||
var val = (int)SliderReflexionMaxEntries.Value;
|
||||
TxtReflexionMaxEntries.Text = val.ToString();
|
||||
SaveSetting(s =>
|
||||
{
|
||||
s.Llm.Reflexion ??= new Models.ReflexionConfig();
|
||||
s.Llm.Reflexion.MaxContextEntries = val;
|
||||
});
|
||||
}
|
||||
|
||||
private void ToolToggle_Changed(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (_isLoading || sender is not CheckBox chk || chk.Tag is not string toolName) return;
|
||||
|
||||
Reference in New Issue
Block a user