Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 79 additions & 9 deletions cli/src/test/kotlin/io/askimo/core/config/AppConfigTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -181,20 +181,79 @@ class AppConfigTest {
fun `updateChatField should handle all fields`() {
var config = ChatConfig()

// Test top-level fields
config = updateChatFieldHelper(config, "maxTokens", 10000)
assertEquals(10000, config.maxTokens)
}

@Test
fun `updateMemoryField should handle mode - swaps to full preset`() {
var config = MemoryConfig()

config = updateMemoryFieldHelper(config, "mode", MemoryMode.COMPACT)
assertEquals(MemoryMode.COMPACT, config.mode)
assertEquals(0.25, config.summarizationThreshold, 0.001)
assertEquals(3, config.protectedRecentTurns)
assertEquals(0.30, config.memoryBudgetFraction, 0.001)

config = updateMemoryFieldHelper(config, "mode", "DETAIL")
assertEquals(MemoryMode.DETAIL, config.mode)
assertEquals(0.60, config.summarizationThreshold, 0.001)
assertEquals(10, config.protectedRecentTurns)
assertEquals(0.50, config.memoryBudgetFraction, 0.001)
}

config = updateChatFieldHelper(config, "summarizationThreshold", 0.8)
assertEquals(0.8, config.summarizationThreshold, 0.001)
@Test
fun `updateMemoryField should handle all numeric fields`() {
var config = MemoryConfig()

config = updateChatFieldHelper(config, "enableAsyncSummarization", false)
assertFalse(config.enableAsyncSummarization)
config = updateMemoryFieldHelper(config, "summarizationThreshold", 0.5)
assertEquals(0.5, config.summarizationThreshold, 0.001)

// Verify all fields are correct after multiple updates
assertEquals(10000, config.maxTokens)
assertEquals(0.8, config.summarizationThreshold, 0.001)
assertFalse(config.enableAsyncSummarization)
config = updateMemoryFieldHelper(config, "protectedRecentTurns", 8)
assertEquals(8, config.protectedRecentTurns)

config = updateMemoryFieldHelper(config, "summarizationPruneFraction", 0.7)
assertEquals(0.7, config.summarizationPruneFraction, 0.001)

config = updateMemoryFieldHelper(config, "maxKeyFacts", 40)
assertEquals(40, config.maxKeyFacts)

config = updateMemoryFieldHelper(config, "maxMainTopics", 20)
assertEquals(20, config.maxMainTopics)

config = updateMemoryFieldHelper(config, "maxSummaryLength", 3000)
assertEquals(3000, config.maxSummaryLength)

config = updateMemoryFieldHelper(config, "memoryBudgetFraction", 0.45)
assertEquals(0.45, config.memoryBudgetFraction, 0.001)
}

@Test
fun `MemoryConfig preset values should be correct`() {
val compact = MemoryConfig.COMPACT
assertEquals(MemoryMode.COMPACT, compact.mode)
assertEquals(0.25, compact.summarizationThreshold, 0.001)
assertEquals(3, compact.protectedRecentTurns)
assertEquals(0.30, compact.memoryBudgetFraction, 0.001)

val balanced = MemoryConfig.BALANCED
assertEquals(MemoryMode.BALANCED, balanced.mode)
assertEquals(0.40, balanced.summarizationThreshold, 0.001)
assertEquals(6, balanced.protectedRecentTurns)
assertEquals(0.40, balanced.memoryBudgetFraction, 0.001)

val detail = MemoryConfig.DETAIL
assertEquals(MemoryMode.DETAIL, detail.mode)
assertEquals(0.60, detail.summarizationThreshold, 0.001)
assertEquals(10, detail.protectedRecentTurns)
assertEquals(0.50, detail.memoryBudgetFraction, 0.001)
}

@Test
fun `MemoryConfig preset factory should return correct preset`() {
assertEquals(MemoryConfig.preset(MemoryMode.COMPACT), MemoryConfig.COMPACT)
assertEquals(MemoryConfig.preset(MemoryMode.BALANCED), MemoryConfig.BALANCED)
assertEquals(MemoryConfig.preset(MemoryMode.DETAIL), MemoryConfig.DETAIL)
}

@Test
Expand Down Expand Up @@ -252,6 +311,17 @@ class AppConfigTest {
return method.invoke(AppConfig, config, field, value) as ChatConfig
}

private fun updateMemoryFieldHelper(config: MemoryConfig, field: String, value: Any): MemoryConfig {
val method = AppConfig::class.java.getDeclaredMethod(
"updateMemoryField",
MemoryConfig::class.java,
String::class.java,
Any::class.java,
)
method.isAccessible = true
return method.invoke(AppConfig, config, field, value) as MemoryConfig
}

private fun updateDeveloperFieldHelper(config: DeveloperConfig, field: String, value: Any): DeveloperConfig {
val method = AppConfig::class.java.getDeclaredMethod(
"updateDeveloperField",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import dev.langchain4j.data.message.SystemMessage
import dev.langchain4j.data.message.UserMessage
import io.askimo.core.chat.domain.SessionMemory
import io.askimo.core.chat.repository.SessionMemoryRepository
import io.askimo.core.config.AppConfig
import io.askimo.core.context.AppContext
import io.askimo.core.providers.ChatClient
import io.askimo.test.extensions.AskimoTestHome
Expand Down Expand Up @@ -542,17 +543,20 @@ class TokenAwareSummarizingMemoryTest {
// ── Helper ───────────────────────────────────────────────────────────────

private fun createMemory(
summarizationThreshold: Double = 0.4, // matches updated default
summarizationThreshold: Double = 0.4,
asyncSummarization: Boolean = true,
tokenEstimator: (ChatMessage) -> Int = TokenAwareSummarizingMemory.defaultTokenEstimator(),
summarizationTimeoutSeconds: Long = 30,
): TokenAwareSummarizingMemory = TokenAwareSummarizingMemory(
appContext = mockAppContext,
sessionId = sessionId,
sessionMemoryRepository = mockRepository,
tokenEstimator = tokenEstimator,
summarizationThreshold = summarizationThreshold,
asyncSummarization = asyncSummarization,
summarizationTimeoutSeconds = summarizationTimeoutSeconds,
)
): TokenAwareSummarizingMemory {
// Drive threshold through AppConfig — @AskimoTestHome resets config between tests
AppConfig.updateField("memory.summarizationThreshold", summarizationThreshold)
return TokenAwareSummarizingMemory(
appContext = mockAppContext,
sessionId = sessionId,
sessionMemoryRepository = mockRepository,
tokenEstimator = tokenEstimator,
asyncSummarization = asyncSummarization,
summarizationTimeoutSeconds = summarizationTimeoutSeconds,
)
}
}
14 changes: 14 additions & 0 deletions desktop-shared/src/main/resources/i18n/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1147,6 +1147,20 @@ settings.models.description=Configure global AI model behavior shared across all
settings.models.max.tool.calling.round.trips=Max Tool-Calling Round Trips
settings.models.max.tool.calling.round.trips.hint=Maximum number of tool calls the AI can make in a single response (default: 10). Higher values allow more complex agent tasks but increase latency and cost.

# Memory Settings
settings.memory.title=Memory Settings
settings.memory.description=Controls how the AI manages conversation history to stay within the model's context window.
settings.memory.mode=Memory Mode
settings.memory.mode.compact=Compact
settings.memory.mode.compact.hint=Lower token cost, less detail
settings.memory.mode.compact.description=Aggressive summarization. Lower token cost, summarizes early and often. Best for very long sessions or cost-sensitive models.
settings.memory.mode.balanced=Balanced
settings.memory.mode.balanced.hint=Good quality/cost trade-off
settings.memory.mode.balanced.description=Good quality/cost trade-off. Fires summarization at 40% of the memory budget. Suitable for most sessions.
settings.memory.mode.detail=Detail
settings.memory.mode.detail.hint=High fidelity, more tokens
settings.memory.mode.detail.description=Minimal summarization. Keeps more verbatim turns and richer summaries. Best for short sessions or when precise recall matters.

## Settings - Utility Models
settings.utility.models.title=Utility Models
settings.utility.models.uses.selected=(uses selected model)
Expand Down
14 changes: 14 additions & 0 deletions desktop-shared/src/main/resources/i18n/messages_de.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1137,6 +1137,20 @@ settings.models.description=Konfigurieren Sie das globale KI-Modellverhalten, da
settings.models.max.tool.calling.round.trips=Maximale Tool-Aufruf-Runden
settings.models.max.tool.calling.round.trips.hint=Maximale Anzahl an Tool-Aufrufen, die die KI in einer einzelnen Antwort durchführen kann (Standard: 10). Höhere Werte ermöglichen komplexere Agenten-Aufgaben, erhöhen jedoch Latenz und Kosten.

# Memory Settings
settings.memory.title=Speichereinstellungen
settings.memory.description=Steuert, wie die KI den Gesprächsverlauf verwaltet, um im Kontextfenster des Modells zu bleiben.
settings.memory.mode=Speichermodus
settings.memory.mode.compact=Kompakt
settings.memory.mode.compact.hint=Geringere Token-Kosten, weniger Details
settings.memory.mode.compact.description=Aggressives Zusammenfassen. Geringe Token-Kosten, häufiges Zusammenfassen. Ideal für sehr lange Sitzungen oder kostensensitive Modelle.
settings.memory.mode.balanced=Ausgewogen
settings.memory.mode.balanced.hint=Gutes Qualitäts-/Kostenverhältnis
settings.memory.mode.balanced.description=Gutes Qualitäts-/Kostenverhältnis. Löst die Zusammenfassung bei 40 % des Speicherbudgets aus. Geeignet für die meisten Sitzungen.
settings.memory.mode.detail=Detailliert
settings.memory.mode.detail.hint=Hohe Wiedergabetreue, mehr Tokens
settings.memory.mode.detail.description=Minimales Zusammenfassen. Behält mehr wörtliche Gesprächsrunden und reichhaltigere Zusammenfassungen bei. Ideal für kurze Sitzungen oder wenn präziser Abruf wichtig ist.

# Settings - Utility Models
settings.utility.models.title=Hilfsmodelle
settings.utility.models.uses.selected=(verwendet das ausgewählte Modell)
Expand Down
14 changes: 14 additions & 0 deletions desktop-shared/src/main/resources/i18n/messages_es.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1133,6 +1133,20 @@ settings.models.description=Configura el comportamiento global de los modelos de
settings.models.max.tool.calling.round.trips=Máximo de rondas de llamadas a herramientas
settings.models.max.tool.calling.round.trips.hint=Número máximo de llamadas a herramientas que la IA puede realizar en una sola respuesta (predeterminado: 10). Valores más altos permiten tareas de agente más complejas pero aumentan la latencia y el costo.

# Memory Settings
settings.memory.title=Configuración de memoria
settings.memory.description=Controla cómo la IA gestiona el historial de conversación para mantenerse dentro del contexto del modelo.
settings.memory.mode=Modo de memoria
settings.memory.mode.compact=Compacto
settings.memory.mode.compact.hint=Menor costo de tokens, menos detalle
settings.memory.mode.compact.description=Resumen agresivo. Menor costo de tokens, resume pronto y con frecuencia. Ideal para sesiones muy largas o modelos sensibles al costo.
settings.memory.mode.balanced=Equilibrado
settings.memory.mode.balanced.hint=Buen equilibrio calidad/costo
settings.memory.mode.balanced.description=Buen equilibrio calidad/costo. Activa el resumen al 40% del presupuesto de memoria. Adecuado para la mayoría de sesiones.
settings.memory.mode.detail=Detallado
settings.memory.mode.detail.hint=Alta fidelidad, más tokens
settings.memory.mode.detail.description=Resumen mínimo. Conserva más turnos literales y resúmenes más ricos. Ideal para sesiones cortas o cuando el recuerdo preciso es importante.

# Settings - Utility Models
settings.utility.models.title=Modelos de utilidad
settings.utility.models.uses.selected=(usa el modelo seleccionado)
Expand Down
14 changes: 14 additions & 0 deletions desktop-shared/src/main/resources/i18n/messages_fr.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1134,6 +1134,20 @@ settings.models.description=Configurez le comportement global du modèle IA part
settings.models.max.tool.calling.round.trips=Nombre maximal d'allers-retours d'appel d'outils
settings.models.max.tool.calling.round.trips.hint=Nombre maximum d'appels d'outils que l'IA peut effectuer dans une seule réponse (défaut : 10). Des valeurs plus élevées permettent des tâches d'agent plus complexes mais augmentent la latence et le coût.

# Memory Settings
settings.memory.title=Paramètres de mémoire
settings.memory.description=Contrôle la façon dont l'IA gère l'historique des conversations pour rester dans la fenêtre de contexte du modèle.
settings.memory.mode=Mode mémoire
settings.memory.mode.compact=Compact
settings.memory.mode.compact.hint=Coût en tokens réduit, moins de détails
settings.memory.mode.compact.description=Résumé agressif. Faible coût en tokens, résumé fréquent. Idéal pour les très longues sessions ou les modèles sensibles aux coûts.
settings.memory.mode.balanced=Équilibré
settings.memory.mode.balanced.hint=Bon équilibre qualité/coût
settings.memory.mode.balanced.description=Bon équilibre qualité/coût. Déclenche le résumé à 40 % du budget mémoire. Convient à la plupart des sessions.
settings.memory.mode.detail=Détaillé
settings.memory.mode.detail.hint=Haute fidélité, plus de tokens
settings.memory.mode.detail.description=Résumé minimal. Conserve plus de tours verbatim et des résumés plus riches. Idéal pour les sessions courtes ou lorsque le rappel précis est important.

# Settings - Utility Models
settings.utility.models.title=Modèles utilitaires
settings.utility.models.uses.selected=(utilise le modèle sélectionné)
Expand Down
14 changes: 14 additions & 0 deletions desktop-shared/src/main/resources/i18n/messages_ja_JP.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1135,6 +1135,20 @@ settings.models.description=すべてのプロバイダーで共有されるグ
settings.models.max.tool.calling.round.trips=最大ツール呼び出しラウンドトリップ数
settings.models.max.tool.calling.round.trips.hint=AI が 1 回の応答で実行できるツール呼び出しの最大回数です(デフォルト: 10)。値を大きくするほど複雑なエージェントタスクが可能になりますが、レイテンシとコストが増加します。

# Memory Settings
settings.memory.title=メモリ設定
settings.memory.description=AIがモデルのコンテキストウィンドウ内に収まるよう会話履歴を管理する方法を制御します。
settings.memory.mode=メモリモード
settings.memory.mode.compact=コンパクト
settings.memory.mode.compact.hint=トークンコストが低く、詳細が少ない
settings.memory.mode.compact.description=積極的な要約。トークンコストが低く、早期かつ頻繁に要約します。非常に長いセッションやコストに敏感なモデルに最適です。
settings.memory.mode.balanced=バランス
settings.memory.mode.balanced.hint=品質とコストの良好なバランス
settings.memory.mode.balanced.description=品質とコストの良好なバランス。メモリ予算の40%で要約が実行されます。ほとんどのセッションに適しています。
settings.memory.mode.detail=詳細
settings.memory.mode.detail.hint=高精度、より多くのトークン
settings.memory.mode.detail.description=最小限の要約。より多くの原文の会話と豊富な要約を保持します。短いセッションや正確な記憶が重要な場合に最適です。

# Settings - Utility Models
settings.utility.models.title=ユーティリティモデル
settings.utility.models.uses.selected=(選択されたモデルを使用)
Expand Down
14 changes: 14 additions & 0 deletions desktop-shared/src/main/resources/i18n/messages_ko_KR.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1134,6 +1134,20 @@ settings.models.description=모든 공급자에서 공유되는 전역 AI 모델
settings.models.max.tool.calling.round.trips=최대 도구 호출 라운드 트립
settings.models.max.tool.calling.round.trips.hint=AI가 단일 응답에서 수행할 수 있는 최대 도구 호출 횟수입니다 (기본값: 10). 값이 높을수록 복잡한 에이전트 작업이 가능하지만 지연 시간과 비용이 증가합니다.

# Memory Settings
settings.memory.title=메모리 설정
settings.memory.description=AI가 모델의 컨텍스트 창 안에서 대화 기록을 관리하는 방식을 제어합니다.
settings.memory.mode=메모리 모드
settings.memory.mode.compact=간결
settings.memory.mode.compact.hint=낮은 토큰 비용, 적은 상세 정보
settings.memory.mode.compact.description=적극적 요약. 토큰 비용이 낮고 자주 요약합니다. 매우 긴 세션이나 비용에 민감한 모델에 적합합니다.
settings.memory.mode.balanced=균형
settings.memory.mode.balanced.hint=품질과 비용의 적절한 균형
settings.memory.mode.balanced.description=품질과 비용의 적절한 균형. 메모리 예산의 40%에서 요약이 시작됩니다. 대부분의 세션에 적합합니다.
settings.memory.mode.detail=상세
settings.memory.mode.detail.hint=높은 정확도, 더 많은 토큰
settings.memory.mode.detail.description=최소 요약. 더 많은 원문 대화와 풍부한 요약을 유지합니다. 짧은 세션이나 정확한 기억이 중요할 때 적합합니다.

# Settings - Utility Models
settings.utility.models.title=유틸리티 모델
settings.utility.models.uses.selected=(선택된 모델 사용)
Expand Down
14 changes: 14 additions & 0 deletions desktop-shared/src/main/resources/i18n/messages_pt_BR.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1137,6 +1137,20 @@ settings.models.description=Configure o comportamento global do modelo de IA com
settings.models.max.tool.calling.round.trips=Máximo de rodadas de chamadas de ferramentas
settings.models.max.tool.calling.round.trips.hint=Número máximo de chamadas de ferramentas que a IA pode fazer em uma única resposta (padrão: 10). Valores mais altos permitem tarefas de agente mais complexas, mas aumentam a latência e o custo.

# Memory Settings
settings.memory.title=Configurações de memória
settings.memory.description=Controla como a IA gerencia o histórico de conversas para se manter dentro da janela de contexto do modelo.
settings.memory.mode=Modo de memória
settings.memory.mode.compact=Compacto
settings.memory.mode.compact.hint=Menor custo de tokens, menos detalhes
settings.memory.mode.compact.description=Resumo agressivo. Menor custo de tokens, resume cedo e com frequência. Ideal para sessões muito longas ou modelos sensíveis ao custo.
settings.memory.mode.balanced=Equilibrado
settings.memory.mode.balanced.hint=Bom equilíbrio qualidade/custo
settings.memory.mode.balanced.description=Bom equilíbrio qualidade/custo. Aciona o resumo a 40% do orçamento de memória. Adequado para a maioria das sessões.
settings.memory.mode.detail=Detalhado
settings.memory.mode.detail.hint=Alta fidelidade, mais tokens
settings.memory.mode.detail.description=Resumo mínimo. Mantém mais turnos verbatim e resumos mais ricos. Ideal para sessões curtas ou quando o recall preciso é importante.

# Settings - Utility Models
settings.utility.models.title=Modelos utilitários
settings.utility.models.uses.selected=(usa o modelo selecionado)
Expand Down
Loading