vLLM 연결 시 등록 모델 alias와 실제 모델 ID가 섞여 payload로 전달되던 경로를 보정해 RegisteredModel에서 실제 모델명을 우선 찾아 요청에 사용하도록 수정했다. OpenAI-compatible 일반 대화와 도구 호출 모두 vLLM 서버 허용 범위를 넘지 않도록 max_tokens를 자동 보정하도록 통일했다. 검증: dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\ (경고 0, 오류 0)
This commit is contained in:
@@ -1078,3 +1078,6 @@ MIT License
|
|||||||
- AX Agent 채팅창의 기본 시작 높이를 소폭 늘려, 처음 열었을 때 상하 여백과 프리셋 영역이 더 여유 있게 보이도록 조정했다.
|
- AX Agent 채팅창의 기본 시작 높이를 소폭 늘려, 처음 열었을 때 상하 여백과 프리셋 영역이 더 여유 있게 보이도록 조정했다.
|
||||||
- 업데이트: 2026-04-06 00:31 (KST)
|
- 업데이트: 2026-04-06 00:31 (KST)
|
||||||
- AX Agent 상단 중앙 탭 그룹의 버튼 padding, 최소 폭/높이와 바깥 pill 래퍼 높이를 한 단계 더 줄였다. 이제 탭 바깥 테두리 안쪽 여백이 더 살아 있어, 레퍼런스처럼 답답하지 않은 세그먼트 탭 비율로 보인다.
|
- AX Agent 상단 중앙 탭 그룹의 버튼 padding, 최소 폭/높이와 바깥 pill 래퍼 높이를 한 단계 더 줄였다. 이제 탭 바깥 테두리 안쪽 여백이 더 살아 있어, 레퍼런스처럼 답답하지 않은 세그먼트 탭 비율로 보인다.
|
||||||
|
- 업데이트: 2026-04-06 00:38 (KST)
|
||||||
|
- vLLM 연결 시 등록 모델 alias/실제 모델 ID가 섞여 전달되던 경로를 보정했다. 내부 서비스(Ollama/vLLM)는 현재 선택값이 alias여도 등록 모델의 실제 모델명을 다시 찾아 요청 payload에 넣도록 정리했다.
|
||||||
|
- vLLM OpenAI-compatible 요청의 `max_tokens`는 서버 허용 범위를 넘지 않도록 자동 보정했다. 일반 대화와 도구 호출 모두 같은 상한 계산을 써 `invalid max_tokens` 오류가 덜 나도록 맞췄다.
|
||||||
|
|||||||
@@ -4835,3 +4835,6 @@ ow + toggle ?쒓컖 ?몄뼱濡??ㅼ떆 ?뺣젹?덈떎.
|
|||||||
- 업데이트: 2026-04-06 00:31 (KST)
|
- 업데이트: 2026-04-06 00:31 (KST)
|
||||||
- [ChatWindow.xaml](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml) 의 상단 `채팅 / Cowork / 코드` 탭 그룹에서 각 버튼의 margin, padding, 최소 폭/높이와 바깥 래퍼의 padding, 최소 높이를 한 단계 더 줄였다.
|
- [ChatWindow.xaml](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml) 의 상단 `채팅 / Cowork / 코드` 탭 그룹에서 각 버튼의 margin, padding, 최소 폭/높이와 바깥 래퍼의 padding, 최소 높이를 한 단계 더 줄였다.
|
||||||
- 결과적으로 탭 그룹이 바깥 테두리를 거의 꽉 채우지 않고, pill 바깥선 안쪽에 숨 쉴 여백이 남는 레퍼런스형 비율로 정리됐다.
|
- 결과적으로 탭 그룹이 바깥 테두리를 거의 꽉 채우지 않고, pill 바깥선 안쪽에 숨 쉴 여백이 남는 레퍼런스형 비율로 정리됐다.
|
||||||
|
- 업데이트: 2026-04-06 00:38 (KST)
|
||||||
|
- [LlmService.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Services/LlmService.cs) 에서 내부 서비스(Ollama/vLLM) 모델 해석 경로를 보강했다. 현재 선택값이 alias 또는 등록 모델 키여도 `RegisteredModel`에서 실제 모델명을 다시 찾아 payload의 `model` 값으로 보내도록 정리했다.
|
||||||
|
- 같은 파일에 vLLM용 `max_tokens` 상한 보정 helper를 추가하고, [LlmService.ToolUse.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Services/LlmService.ToolUse.cs) 의 일반 도구 호출 / OpenAI-compatible tool body 생성에도 같은 값을 쓰게 맞췄다. 이로써 `Model Not Exist`, `invalid max_tokens` 계열 오류를 줄이는 방향으로 정리했다.
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ public partial class LlmService
|
|||||||
return new
|
return new
|
||||||
{
|
{
|
||||||
model = activeModel,
|
model = activeModel,
|
||||||
max_tokens = Math.Max(llm.MaxContextTokens, 4096),
|
max_tokens = ResolveOpenAiCompatibleMaxTokens(),
|
||||||
temperature = llm.Temperature,
|
temperature = llm.Temperature,
|
||||||
system = systemPrompt,
|
system = systemPrompt,
|
||||||
messages = msgs,
|
messages = msgs,
|
||||||
@@ -237,7 +237,7 @@ public partial class LlmService
|
|||||||
return new
|
return new
|
||||||
{
|
{
|
||||||
model = activeModel,
|
model = activeModel,
|
||||||
max_tokens = Math.Max(llm.MaxContextTokens, 4096),
|
max_tokens = ResolveOpenAiCompatibleMaxTokens(),
|
||||||
temperature = llm.Temperature,
|
temperature = llm.Temperature,
|
||||||
messages = msgs,
|
messages = msgs,
|
||||||
tools = toolDefs,
|
tools = toolDefs,
|
||||||
@@ -661,7 +661,7 @@ public partial class LlmService
|
|||||||
["tools"] = toolDefs,
|
["tools"] = toolDefs,
|
||||||
["stream"] = false,
|
["stream"] = false,
|
||||||
["temperature"] = ResolveTemperature(),
|
["temperature"] = ResolveTemperature(),
|
||||||
["max_tokens"] = llm.MaxContextTokens,
|
["max_tokens"] = ResolveOpenAiCompatibleMaxTokens(),
|
||||||
};
|
};
|
||||||
var effort = ResolveReasoningEffort();
|
var effort = ResolveReasoningEffort();
|
||||||
if (!string.IsNullOrWhiteSpace(effort))
|
if (!string.IsNullOrWhiteSpace(effort))
|
||||||
|
|||||||
@@ -249,10 +249,32 @@ public partial class LlmService : IDisposable
|
|||||||
var llm = _settings.Settings.Llm;
|
var llm = _settings.Settings.Llm;
|
||||||
var service = NormalizeServiceName(llm.Service);
|
var service = NormalizeServiceName(llm.Service);
|
||||||
if (service is "ollama" or "vllm" && !string.IsNullOrEmpty(llm.Model))
|
if (service is "ollama" or "vllm" && !string.IsNullOrEmpty(llm.Model))
|
||||||
|
{
|
||||||
|
var registered = FindRegisteredModel(llm, service, llm.Model);
|
||||||
|
if (registered != null)
|
||||||
|
{
|
||||||
|
var registeredModelName = CryptoService.DecryptIfEnabled(registered.EncryptedModelName, llm.EncryptionEnabled);
|
||||||
|
if (!string.IsNullOrWhiteSpace(registeredModelName))
|
||||||
|
return registeredModelName;
|
||||||
|
}
|
||||||
|
|
||||||
return CryptoService.DecryptIfEnabled(llm.Model, llm.EncryptionEnabled);
|
return CryptoService.DecryptIfEnabled(llm.Model, llm.EncryptionEnabled);
|
||||||
|
}
|
||||||
return llm.Model;
|
return llm.Model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int ResolveOpenAiCompatibleMaxTokens()
|
||||||
|
{
|
||||||
|
var llm = _settings.Settings.Llm;
|
||||||
|
var requested = Math.Clamp(llm.MaxContextTokens, 1, 1_000_000);
|
||||||
|
var service = NormalizeServiceName(llm.Service);
|
||||||
|
|
||||||
|
if (service == "vllm")
|
||||||
|
return Math.Min(requested, 8192);
|
||||||
|
|
||||||
|
return requested;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 현재 활성 모델에 매칭되는 RegisteredModel을 찾아 엔드포인트/API키를 반환합니다.
|
/// 현재 활성 모델에 매칭되는 RegisteredModel을 찾아 엔드포인트/API키를 반환합니다.
|
||||||
/// RegisteredModel에 전용 서버 정보가 있으면 그것을 사용하고, 없으면 기본 설정을 사용합니다.
|
/// RegisteredModel에 전용 서버 정보가 있으면 그것을 사용하고, 없으면 기본 설정을 사용합니다.
|
||||||
@@ -648,7 +670,7 @@ public partial class LlmService : IDisposable
|
|||||||
["messages"] = msgs,
|
["messages"] = msgs,
|
||||||
["stream"] = stream,
|
["stream"] = stream,
|
||||||
["temperature"] = ResolveTemperature(),
|
["temperature"] = ResolveTemperature(),
|
||||||
["max_tokens"] = llm.MaxContextTokens
|
["max_tokens"] = ResolveOpenAiCompatibleMaxTokens()
|
||||||
};
|
};
|
||||||
var effort = ResolveReasoningEffort();
|
var effort = ResolveReasoningEffort();
|
||||||
if (!string.IsNullOrWhiteSpace(effort))
|
if (!string.IsNullOrWhiteSpace(effort))
|
||||||
|
|||||||
Reference in New Issue
Block a user