재구성 AX Agent 설정과 채팅 UI를 Claude형 구조로
Some checks failed
Release Gate / gate (push) Has been cancelled
Some checks failed
Release Gate / gate (push) Has been cancelled
This commit is contained in:
@@ -388,6 +388,24 @@ public static class AgentHookRunner
|
||||
}
|
||||
}
|
||||
|
||||
if (ctxProp.ValueKind == JsonValueKind.Object)
|
||||
{
|
||||
// 구조화된 컨텍스트 오브젝트도 허용합니다.
|
||||
// 우선순위: message > content > text
|
||||
foreach (var key in new[] { "message", "content", "text" })
|
||||
{
|
||||
if (!ctxProp.TryGetProperty(key, out var value) || value.ValueKind != JsonValueKind.String)
|
||||
continue;
|
||||
|
||||
var text = value.GetString()?.Trim();
|
||||
if (!string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
additionalContext = text;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,17 +39,26 @@ public static class ContextCondenser
|
||||
/// 2단계: 이전 대화 LLM 요약 (토큰이 여전히 높으면)
|
||||
/// </summary>
|
||||
public static async Task<bool> CondenseIfNeededAsync(
|
||||
List<ChatMessage> messages, LlmService llm, int maxOutputTokens, CancellationToken ct = default)
|
||||
List<ChatMessage> messages,
|
||||
LlmService llm,
|
||||
int maxOutputTokens,
|
||||
bool proactiveEnabled = true,
|
||||
int triggerPercent = 80,
|
||||
bool force = false,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
if (messages.Count < 6) return false;
|
||||
if (!force && !proactiveEnabled) return false;
|
||||
|
||||
// 현재 모델의 입력 토큰 한도
|
||||
var settings = llm.GetCurrentModelInfo();
|
||||
var inputLimit = GetModelInputLimit(settings.service, settings.model);
|
||||
var threshold = (int)(inputLimit * 0.65); // 65%에서 압축 시작
|
||||
var effectiveMax = maxOutputTokens > 0 ? Math.Min(inputLimit, maxOutputTokens) : inputLimit;
|
||||
var percent = Math.Clamp(triggerPercent, 50, 95);
|
||||
var threshold = (int)(effectiveMax * (percent / 100.0)); // 설정 임계치에서 압축 시작
|
||||
|
||||
var currentTokens = TokenEstimator.EstimateMessages(messages);
|
||||
if (currentTokens < threshold) return false;
|
||||
if (!force && currentTokens < threshold) return false;
|
||||
|
||||
bool didCompress = false;
|
||||
|
||||
@@ -58,7 +67,7 @@ public static class ContextCondenser
|
||||
|
||||
// 1단계 후 다시 추정
|
||||
currentTokens = TokenEstimator.EstimateMessages(messages);
|
||||
if (currentTokens < threshold) return didCompress;
|
||||
if (!force && currentTokens < threshold) return didCompress;
|
||||
|
||||
// ── 2단계: 이전 대화 LLM 요약 ──
|
||||
didCompress |= await SummarizeOldMessagesAsync(messages, llm, ct);
|
||||
|
||||
@@ -55,6 +55,9 @@ public class HttpTool : IAgentTool
|
||||
|
||||
public async Task<ToolResult> ExecuteAsync(JsonElement args, AgentContext context, CancellationToken ct = default)
|
||||
{
|
||||
if (AxCopilot.Services.OperationModePolicy.IsInternal(context.OperationMode))
|
||||
return ToolResult.Fail("사내모드에서는 HTTP 도구 실행이 차단됩니다. operationMode=external에서만 사용할 수 있습니다.");
|
||||
|
||||
var method = args.GetProperty("method").GetString()?.ToUpperInvariant() ?? "GET";
|
||||
var url = args.GetProperty("url").GetString() ?? "";
|
||||
var body = args.TryGetProperty("body", out var b) ? b.GetString() ?? "" : "";
|
||||
|
||||
@@ -38,6 +38,9 @@ public class OpenExternalTool : IAgentTool
|
||||
if (rawPath.StartsWith("http://", StringComparison.OrdinalIgnoreCase) ||
|
||||
rawPath.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (AxCopilot.Services.OperationModePolicy.IsInternal(context.OperationMode))
|
||||
return Task.FromResult(ToolResult.Fail("사내모드에서는 외부 URL 열기가 차단됩니다. operationMode=external에서만 사용할 수 있습니다."));
|
||||
|
||||
Process.Start(new ProcessStartInfo(rawPath) { UseShellExecute = true });
|
||||
return Task.FromResult(ToolResult.Ok($"URL 열기: {rawPath}"));
|
||||
}
|
||||
|
||||
@@ -124,12 +124,12 @@ public static class PermissionModeCatalog
|
||||
var normalized = NormalizeGlobalMode(mode);
|
||||
return normalized switch
|
||||
{
|
||||
Default => "소극 활용",
|
||||
AcceptEdits => "적극 활용",
|
||||
Plan => "계획 중심",
|
||||
BypassPermissions => "완전 자동",
|
||||
Default => "권한 요청",
|
||||
AcceptEdits => "편집 자동 승인",
|
||||
Plan => "계획 모드",
|
||||
BypassPermissions => "권한 건너뛰기",
|
||||
DontAsk => "질문 없이 진행",
|
||||
Deny => "활용하지 않음",
|
||||
Deny => "읽기 전용",
|
||||
_ => normalized,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -14,32 +14,32 @@ internal static class PermissionModePresentationCatalog
|
||||
new PermissionModePresentation(
|
||||
PermissionModeCatalog.Deny,
|
||||
"\uE711",
|
||||
"활용하지 않음",
|
||||
"읽기 전용",
|
||||
"파일 읽기만 허용하고 생성/수정/삭제는 차단합니다.",
|
||||
"#107C10"),
|
||||
new PermissionModePresentation(
|
||||
PermissionModeCatalog.Default,
|
||||
"\uE8D7",
|
||||
"소극 활용",
|
||||
"변경 전 확인하고, 필요한 경우에만 파일 접근을 진행합니다.",
|
||||
"권한 요청",
|
||||
"변경하기 전에 항상 확인합니다.",
|
||||
"#2563EB"),
|
||||
new PermissionModePresentation(
|
||||
PermissionModeCatalog.AcceptEdits,
|
||||
"\uE73E",
|
||||
"적극 활용",
|
||||
"파일 편집 도구를 자동 승인하고 명령 실행은 계속 확인합니다.",
|
||||
"편집 자동 승인",
|
||||
"모든 파일 편집을 자동 승인합니다.",
|
||||
"#107C10"),
|
||||
new PermissionModePresentation(
|
||||
PermissionModeCatalog.Plan,
|
||||
"\uE7C3",
|
||||
"계획 중심",
|
||||
"쓰기 전 계획과 승인 흐름을 우선합니다.",
|
||||
"계획 모드",
|
||||
"변경하기 전에 계획을 먼저 만듭니다.",
|
||||
"#4338CA"),
|
||||
new PermissionModePresentation(
|
||||
PermissionModeCatalog.BypassPermissions,
|
||||
"\uE814",
|
||||
"완전 자동",
|
||||
"권한 확인을 대부분 생략합니다. 민감한 작업은 주의하세요.",
|
||||
"권한 건너뛰기",
|
||||
"모든 권한을 허용합니다.",
|
||||
"#B45309"),
|
||||
new PermissionModePresentation(
|
||||
PermissionModeCatalog.DontAsk,
|
||||
|
||||
Reference in New Issue
Block a user