File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1717
1818 </div >
1919 <AutoScrollContainer
20- enabled
20+ : enabled = " ! showScrollToBottomButton "
2121 class="flex flex-col overflow-y-auto border-t border-gray-200 dark:border-gray-700 "
2222 ref="scrollContainer"
23+ :threshold =" 10 "
2324 behavior="smooth"
2425 >
2526
5758 v-if =" props.messages.length === 0"
5859 class =" flex-1 flex flex-col items-center justify-center text-gray-400 tracking-widest text-xl font-medium"
5960 >
60- <p >Start the conversation</p >
61- <p class =" tracking-normal text-base text" >Give any input to begin</p >
61+ <p >{{ $t(' Start the conversation') }} </p >
62+ <p class =" tracking-normal text-base text" >{{ $t(' Give any input to begin') }} </p >
6263 </div >
6364 </AutoScrollContainer >
6465</template >
@@ -151,20 +152,16 @@ const groupToolCallParts = (message: IMessage) => {
151152 if (! part ?.toolInfo ) {
152153 continue ;
153154 }
154- console .log (' part' , part );
155155 if (part .toolInfo .toolName === currentToolName ) {
156- console .log (' grouping part with tool name' , currentToolName );
157156 groupedParts [groupedParts .length - 1 ].groupedTools .push (part );
158157 continue ;
159158 }
160159 currentToolName = part .toolInfo .toolName ;
161- console .log (' starting new group with tool name' , currentToolName );
162160 groupedParts .push ({
163161 title: currentToolName ,
164162 groupedTools: [part ]
165163 });
166164 }
167- console .log (' groupedParts' , groupedParts );
168165 return groupedParts ;
169166}
170167
Original file line number Diff line number Diff line change 11<template >
22 <div
3- class =" max-w-[80%] flex px-4 py-2 m-2 rounded-xl border border-gray-200 dark:border-gray-700"
3+ class =" max-w-[80%] flex px-4 m-2 rounded-xl border border-gray-200 dark:border-gray-700"
44 @click =" handleMarkdownLinkClick"
55 :class =" props.role === 'user' ? 'bg-lightListTableHeading dark:bg-darkListTableHeading self-end'
66 : isTypeReasoning || isTypeToolCall ? 'bg-transparent border-none self-start'
Original file line number Diff line number Diff line change 66 "
77 >
88 <h3 :class =" h3Style" >{{ $t('Chat history') }}</h3 >
9- <Button @click =" agentStore .createPreSession ()" :disabled =" agentStore .isResponseInProgress " class="w-[360px] mx-4 my-2 mb-4 rounded-3xl text-gray-800 dark:text-gray-200 ">
9+ <Button @click =" agentStore .createPreSession (); agentStore . setSessionHistoryOpen ( false ) " :disabled =" agentStore .isResponseInProgress " class="w-[360px] mx-4 my-2 mb-4 rounded-3xl text-gray-800 dark:text-gray-200 ">
1010 <IconPlusOutline class="w-5 h-5" />
1111 {{ $t('New chat') }}
1212 </Button >
1313 <div class =" w-full border-b border-gray-200 dark:border-gray-700" />
1414 <div class =" absolute w-full h-full flex flex-col items-center justify-center bg-gray-100/50 dark:bg-gray-700/50 z-10" v-if =" agentStore.isResponseInProgress" >
1515 <Spinner class="w-8 h-8" v-if =" agentStore .isResponseInProgress " />
16- <p class =" mt-2 text-gray-800 dark:text-gray-200" >generation in progress...</p >
16+ <p class =" mt-2 text-gray-800 dark:text-gray-200" >{{ $t('Generation in progress...') }} </p >
1717 </div >
1818 <div v-for =" group in groupedSessions" :key =" group.dayKey" class =" w-full py-2" >
1919 <div class =" px-4 pb-2 text-xs font-semibold uppercase tracking-[0.2em] text-gray-500 dark:text-gray-400" >
3838 v-if =" !groupedSessions || groupedSessions.length === 0"
3939 class =" w-full h-full flex items-center justify-center text-gray-800 dark:text-gray-200"
4040 >
41- There is no previous chat sessions
41+ {{ $t(' There are no previous chat sessions') }}
4242 </p >
4343 </div >
4444</template >
Original file line number Diff line number Diff line change 11<template >
2- <div v-if =" props.data?.toolInfo" class =" inline-flex m-2 max-w-[80%] flex-col gap-3 rounded-xl p-2 text-lightListTableHeadingText dark:text-darkListTableHeadingText" >
2+ <div
3+ class =" inline-flex m-2 max-w-[80%] flex-col gap-3 rounded-xl p-2 cursor-pointer text-lightListTableHeadingText dark:text-darkListTableHeadingText hover:opacity-75"
4+ @click =" isInputOutputExpanded = !isInputOutputExpanded"
5+ >
36 <div class =" flex items-center gap-3" >
47 <div class =" flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-white/70 dark:bg-blue-700/20" >
58 <Spinner v-if =" isRunning " class="h-4 w-4" />
1821 <IconAngleDownOutline
1922 v-if =" hasToolSections "
2023 :class =" isInputOutputExpanded ? ' rotate-180' : ' rotate-0' "
21- class="cursor-pointer transition-transform duration-200 hover:scale-105 hover:opacity-75 "
22- @click =" isInputOutputExpanded = ! isInputOutputExpanded "
24+ class="cursor-pointer transition-transform duration-200 hover:scale-105 "
2325 />
2426 </div >
2527 <transition name =" expand" >
Original file line number Diff line number Diff line change 11<template >
22 <template v-for =" group in props .toolGroup " :key =" group .title " >
3- <div v-if =" group.groupedTools.length > 1" class =" mb-4 flex flex-col" >
4- <div class =" flex items-center gap-2 p-2 m-2 cursor-pointer hover:opacity-75 break-all font-mono text-sm leading-5" @click =" toggleGroup(group.title)" >
5- - {{ group.title }} {{ 'x' + group.groupedTools.length }}
3+ <div v-if =" group.groupedTools.length > 1" class =" flex flex-col" >
4+ <div class =" flex items-center gap-2 p-2 m-2 cursor-pointer hover:opacity-75 break-all font-mono text-sm leading-5 text-lightListTableHeadingText dark:text-darkListTableHeadingText" @click =" toggleGroup(group.title)" >
5+ <IconMinusOutline class="w-6 h-6 p-1"/>
6+ {{ group.title }} {{ 'x' + group.groupedTools.length }}
67 <IconAngleDownOutline
78 class="transition-transform duration-200 hover:scale-105 hover:opacity-75 "
89 :class =" expandedGroups .includes (group .title ) ? ' rotate-180' : ' rotate-0' "
910 />
1011 </div >
1112 <transition name =" expand" >
1213 <div v-show =" expandedGroups.includes(group.title)" class =" flex flex-col" >
13- <ToolRenderer v-for =" part in group .groupedTools " :key =" part .text + part .type " :data =" part " />
14+ <ToolRenderer v-for =" part in group .groupedTools " :key =" part .text + part .type " :data =" part " class="ml-8" />
1415 </div >
1516 </transition >
1617 </div >
@@ -24,7 +25,7 @@ import { Tool } from 'langchain';
2425import ToolRenderer from ' ./ToolRenderer.vue' ;
2526import type { IPart } from ' ./types' ;
2627import { ref } from ' vue' ;
27- import { IconAngleDownOutline } from ' @iconify-prerendered/vue-flowbite' ;
28+ import { IconAngleDownOutline , IconMinusOutline } from ' @iconify-prerendered/vue-flowbite' ;
2829
2930const props = defineProps <{
3031 toolGroup: {
Original file line number Diff line number Diff line change @@ -120,6 +120,10 @@ export const useAgentStore = defineStore('agent', () => {
120120 } ) ;
121121 const blockCloseOfChat = ref ( false ) ;
122122
123+ function sortSessionsListByTimestamp ( sessionsList : ISessionsListItem [ ] ) {
124+ return [ ...sessionsList ] . sort ( ( a : ISessionsListItem , b : ISessionsListItem ) => b . timestamp . localeCompare ( a . timestamp ) ) ;
125+ }
126+
123127 async function sendMessage ( ) {
124128 const message = trimmedUserMessage . value ;
125129 if ( ! message || isResponseInProgress . value ) {
@@ -128,6 +132,11 @@ export const useAgentStore = defineStore('agent', () => {
128132 if ( ! currentSession . value || currentSession . value . sessionId === 'pre-session' ) {
129133 await createNewSession ( message ) ;
130134 }
135+ currentSession . value . timestamp = new Date ( ) . toISOString ( ) ;
136+ sessionList . value = sortSessionsListByTimestamp ( sessionList . value . map ( ( s : ISessionsListItem ) => s . sessionId === currentSession . value ?. sessionId ? {
137+ ...s ,
138+ timestamp : currentSession . value ?. timestamp || s . timestamp ,
139+ } : s ) ) ;
131140 lastMessage . value = message ;
132141 currentChat . value ?. sendMessage ( {
133142 text : message ,
Original file line number Diff line number Diff line change @@ -87,6 +87,13 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
8787 return { ok : true } ;
8888 }
8989
90+ private async updateSessionDate ( sessionId : string ) {
91+ await this . adminforth . resource ( this . options . sessionResource . resourceId ) . update ( sessionId , {
92+ [ this . options . sessionResource . createdAtField ] : new Date ( ) . toISOString ( ) ,
93+ } ) ;
94+ return { ok : true } ;
95+ }
96+
9097 private async getSessionTurns ( sessionId : string ) {
9198 const turns = await this . adminforth . resource ( this . options . turnResource . resourceId ) . list (
9299 [ Filters . EQ ( this . options . turnResource . sessionIdField , sessionId ) ] ,
@@ -150,6 +157,7 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
150157 const userTimeZone = ( body . timeZone as string | undefined ) ?? 'UTC' ;
151158 const sessionId = body . sessionId || adminUser ?. pk || adminUser ?. username || 'default' ;
152159 const turnId = await this . createNewTurn ( sessionId , prompt ) ;
160+ await this . updateSessionDate ( sessionId ) ;
153161 let fullResponse = "" ;
154162 let isStreamClosed = false ;
155163 const sequenceDebugCollector = createSequenceDebugCollector ( ) ;
You can’t perform that action at this time.
0 commit comments