5656 </aside >
5757
5858 <main class =" min-w-0 flex-1 overflow-y-auto" >
59- <div class =" mx-auto flex w-full max-w-5xl flex-col gap-6 px-6 py-6" >
60- <div class =" flex items-start justify-between gap-4" >
59+ <div
60+ data-testid =" deepchat-agents-sticky-header"
61+ class =" sticky top-0 z-20 border-b border-border/80 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/85"
62+ >
63+ <div class =" mx-auto flex w-full max-w-5xl items-start justify-between gap-4 px-6 py-4" >
6164 <div class =" flex items-center gap-4" >
6265 <div
6366 class =" flex h-14 w-14 shrink-0 items-center justify-center rounded-2xl border border-border/70 bg-muted/40"
99102 </Button >
100103 </div >
101104 </div >
105+ </div >
102106
107+ <div class =" mx-auto flex w-full max-w-5xl flex-col gap-6 px-6 py-6" >
103108 <section class =" grid gap-4 rounded-2xl border border-border p-5 md:grid-cols-2" >
104109 <label class =" space-y-2" >
105110 <div class =" text-sm font-medium" >{{ t('settings.deepchatAgents.name') }}</div >
550555 <div class =" text-sm font-medium" >
551556 {{ `${t('settings.deepchatAgents.compactionThreshold')} (%)` }}
552557 </div >
553- <Input v-model =" form.autoCompactionTriggerThreshold" type =" number" min =" 5" max =" 95" />
558+ <Input
559+ v-model =" form.autoCompactionTriggerThreshold"
560+ data-testid =" auto-compaction-trigger-threshold-input"
561+ type =" number"
562+ min =" 5"
563+ max =" 95"
564+ />
554565 </label >
555566 <label class =" space-y-2" >
556567 <div class =" text-sm font-medium" >
557568 {{ t('settings.deepchatAgents.compactionRetainPairs') }}
558569 </div >
559570 <Input
560571 v-model =" form.autoCompactionRetainRecentPairs"
572+ data-testid =" auto-compaction-retain-recent-pairs-input"
561573 type =" number"
562574 min =" 1"
563575 max =" 10"
@@ -661,6 +673,7 @@ type ToolGroup = {
661673 label: string
662674 tools: MCPToolDefinition []
663675}
676+ type EditableNumberValue = string | number
664677type FormState = {
665678 id: string | null
666679 protected: boolean
@@ -683,13 +696,19 @@ type FormState = {
683696 subagents: EditableSubagentSlot []
684697 disabledAgentTools: string []
685698 autoCompactionEnabled: boolean
686- autoCompactionTriggerThreshold: string
687- autoCompactionRetainRecentPairs: string
699+ autoCompactionTriggerThreshold: EditableNumberValue
700+ autoCompactionRetainRecentPairs: EditableNumberValue
688701}
689702
690703const LUCIDE_ICONS = [' bot' , ' sparkles' , ' brain' , ' code' , ' book-open' , ' pen-tool' , ' rocket' ]
691704const DRAFT_AGENT_ID = ' __draft_deepchat_agent__'
692705const CURRENT_SUBAGENT_TARGET = ' __current_agent__'
706+ const AUTO_COMPACTION_TRIGGER_THRESHOLD_DEFAULT = 80
707+ const AUTO_COMPACTION_TRIGGER_THRESHOLD_MIN = 5
708+ const AUTO_COMPACTION_TRIGGER_THRESHOLD_MAX = 95
709+ const AUTO_COMPACTION_RETAIN_RECENT_PAIRS_DEFAULT = 2
710+ const AUTO_COMPACTION_RETAIN_RECENT_PAIRS_MIN = 1
711+ const AUTO_COMPACTION_RETAIN_RECENT_PAIRS_MAX = 10
693712const GROUP_ORDER = [
694713 ' agent-filesystem' ,
695714 ' agent-core' ,
@@ -978,12 +997,35 @@ const normalizePath = (value: string | null | undefined) => {
978997 const normalized = value ?.trim ()
979998 return normalized ? normalized : null
980999}
981- const parseNum = (value : string ) => {
982- const normalized = value .trim ()
983- if (! normalized ) return undefined
984- const parsed = Number (normalized )
985- return Number .isFinite (parsed ) ? parsed : undefined
1000+ const normalizeNumericInput = (
1001+ value : EditableNumberValue | null | undefined ,
1002+ options : { fallback: number ; min: number ; max: number ; integer? : boolean }
1003+ ) => {
1004+ if (value === ' ' || value === null || value === undefined ) {
1005+ return options .fallback
1006+ }
1007+
1008+ const parsed = typeof value === ' number' ? value : Number (value .trim ())
1009+ if (! Number .isFinite (parsed )) {
1010+ return options .fallback
1011+ }
1012+
1013+ const normalized = options .integer ? Math .round (parsed ) : parsed
1014+ return Math .min (options .max , Math .max (options .min , normalized ))
9861015}
1016+ const normalizeAutoCompactionTriggerThreshold = (value : EditableNumberValue | null | undefined ) =>
1017+ normalizeNumericInput (value , {
1018+ fallback: AUTO_COMPACTION_TRIGGER_THRESHOLD_DEFAULT ,
1019+ min: AUTO_COMPACTION_TRIGGER_THRESHOLD_MIN ,
1020+ max: AUTO_COMPACTION_TRIGGER_THRESHOLD_MAX
1021+ })
1022+ const normalizeAutoCompactionRetainRecentPairs = (value : EditableNumberValue | null | undefined ) =>
1023+ normalizeNumericInput (value , {
1024+ fallback: AUTO_COMPACTION_RETAIN_RECENT_PAIRS_DEFAULT ,
1025+ min: AUTO_COMPACTION_RETAIN_RECENT_PAIRS_MIN ,
1026+ max: AUTO_COMPACTION_RETAIN_RECENT_PAIRS_MAX ,
1027+ integer: true
1028+ })
9871029const createAgentSlotId = () =>
9881030 ` slot-${Date .now ().toString (36 )}-${Math .random ().toString (36 ).slice (2 , 6 )} `
9891031const numText = (value : unknown ) =>
@@ -1042,8 +1084,12 @@ const fromAgent = (agent?: Agent | null): FormState => {
10421084 subagents: normalizeDeepChatSubagentSlots (config .subagents ),
10431085 disabledAgentTools: [... (config .disabledAgentTools ?? [])],
10441086 autoCompactionEnabled: config .autoCompactionEnabled ?? true ,
1045- autoCompactionTriggerThreshold: numText (config .autoCompactionTriggerThreshold ?? 80 ),
1046- autoCompactionRetainRecentPairs: numText (config .autoCompactionRetainRecentPairs ?? 2 )
1087+ autoCompactionTriggerThreshold: numText (
1088+ config .autoCompactionTriggerThreshold ?? AUTO_COMPACTION_TRIGGER_THRESHOLD_DEFAULT
1089+ ),
1090+ autoCompactionRetainRecentPairs: numText (
1091+ config .autoCompactionRetainRecentPairs ?? AUTO_COMPACTION_RETAIN_RECENT_PAIRS_DEFAULT
1092+ )
10471093 }
10481094}
10491095const modelText = (selection : EditableModel | undefined ) => {
@@ -1253,8 +1299,12 @@ const saveAgent = async () => {
12531299 subagents: normalizeDeepChatSubagentSlots (form .subagents ),
12541300 disabledAgentTools: [... form .disabledAgentTools ],
12551301 autoCompactionEnabled: form .autoCompactionEnabled ,
1256- autoCompactionTriggerThreshold: parseNum (form .autoCompactionTriggerThreshold ) ?? 80 ,
1257- autoCompactionRetainRecentPairs: parseNum (form .autoCompactionRetainRecentPairs ) ?? 2
1302+ autoCompactionTriggerThreshold: normalizeAutoCompactionTriggerThreshold (
1303+ form .autoCompactionTriggerThreshold
1304+ ),
1305+ autoCompactionRetainRecentPairs: normalizeAutoCompactionRetainRecentPairs (
1306+ form .autoCompactionRetainRecentPairs
1307+ )
12581308 }
12591309 }
12601310 if (form .id ) {
0 commit comments