@adminforth/agent 2.10.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,7 +15,7 @@
15
15
  <div
16
16
  v-for="item in agentStore.steerQueue"
17
17
  :key="item.id"
18
- class="flex items-center gap-2 rounded-lg border border-gray-200 bg-gray-50 px-3 py-1.5 shadow-sm dark:border-gray-600 dark:bg-gray-800"
18
+ class="flex items-center gap-2 rounded-lg border border-lightCardBorder bg-lightCardBackground py-1.5 pl-3 pr-1.5 shadow-popover dark:border-darkCardBorder dark:bg-darkCardBackground dark:shadow-darkPopover"
19
19
  >
20
20
  <span
21
21
  class="flex-1 min-w-0 truncate text-sm text-lightInputText dark:text-darkInputText"
@@ -23,12 +23,13 @@
23
23
  >
24
24
  {{ item.text }}
25
25
  </span>
26
- <span class="shrink-0 text-xs text-gray-400 dark:text-gray-500">
26
+ <span class="shrink-0 text-xs text-lightInputPlaceholderText dark:text-darkInputPlaceholderText">
27
27
  {{ $t('queued') }}
28
28
  </span>
29
- <button
29
+ <Button
30
+ variant="secondary"
31
+ size="sm"
30
32
  type="button"
31
- class="shrink-0 rounded-md px-2 py-1 text-xs font-medium text-lightPrimary transition-colors hover:bg-lightPrimary/10 disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:bg-transparent dark:text-darkPrimary dark:hover:bg-darkPrimary/10 dark:disabled:hover:bg-transparent"
32
33
  :disabled="agentStore.isFinalResponseStreaming"
33
34
  :title="agentStore.isFinalResponseStreaming
34
35
  ? $t('The final response is streaming; this message will be sent after it finishes')
@@ -36,21 +37,26 @@
36
37
  @click="agentStore.steerQueuedMessage(item.id)"
37
38
  >
38
39
  {{ $t('Steer') }}
39
- </button>
40
- <button
40
+ </Button>
41
+ <Button
42
+ variant="ghost"
43
+ size="sm"
44
+ iconOnly
41
45
  type="button"
42
- class="shrink-0 flex h-6 w-6 items-center justify-center rounded-md text-lg leading-none text-gray-400 transition-colors hover:bg-gray-200 hover:text-gray-600 dark:hover:bg-gray-700 dark:hover:text-gray-300"
43
46
  :title="$t('Remove from queue')"
47
+ :aria-label="$t('Remove from queue')"
44
48
  @click="agentStore.removeQueuedMessage(item.id)"
45
49
  >
46
- &times;
47
- </button>
50
+ <IconX />
51
+ </Button>
48
52
  </div>
49
53
  </TransitionGroup>
50
54
  </div>
51
55
  </template>
52
56
 
53
57
  <script setup lang="ts">
58
+ import { IconX } from '@iconify-prerendered/vue-lucide';
59
+ import { Button } from '@/afcl';
54
60
  import { useAgentStore } from './composables/useAgentStore';
55
61
 
56
62
  const agentStore = useAgentStore();
@@ -203,6 +203,26 @@ export function createAgentSessionManager({
203
203
  setCurrentChat(PRE_SESSION_ID);
204
204
  }
205
205
 
206
+ async function renameSession(sessionId: string, title: string) {
207
+ const res = await callAdminForthApi({
208
+ method: 'POST',
209
+ path: '/agent/rename-session',
210
+ body: { sessionId, title },
211
+ });
212
+ if (res.error) {
213
+ console.error('Error renaming session:', res.error);
214
+ return;
215
+ }
216
+ sessionList.value.find((s: ISessionsListItem) => s.sessionId === sessionId)!.title = res.title;
217
+ // a loaded session is cached apart from the list, and the open one is shown in the header
218
+ if (sessions.value[sessionId]) {
219
+ sessions.value[sessionId].title = res.title;
220
+ }
221
+ if (currentSession.value?.sessionId === sessionId) {
222
+ currentSession.value.title = res.title;
223
+ }
224
+ }
225
+
206
226
  async function deleteSession(sessionId: string) {
207
227
  if (sessionId === PRE_SESSION_ID) {
208
228
  deletePreSession();
@@ -370,6 +390,7 @@ export function createAgentSessionManager({
370
390
  createPreSession,
371
391
  setActiveSession,
372
392
  fetchSessionsList,
393
+ renameSession,
373
394
  deleteSession,
374
395
  addDebugMessage,
375
396
  addSystemMessage,
@@ -198,6 +198,7 @@ export const useAgentStore = defineStore('agent', () => {
198
198
  createPreSession,
199
199
  setActiveSession,
200
200
  fetchSessionsList,
201
+ renameSession,
201
202
  deleteSession,
202
203
  addDebugMessage,
203
204
  addSystemMessage,
@@ -590,6 +591,7 @@ export const useAgentStore = defineStore('agent', () => {
590
591
  sessionList,
591
592
  setActiveSession,
592
593
  fetchSessionsList,
594
+ renameSession,
593
595
  deleteSession,
594
596
  createPreSession,
595
597
  //____________________________________________
@@ -5,7 +5,7 @@
5
5
  <div
6
6
  v-if="agentStore.isSessionHistoryOpen"
7
7
  @click="agentStore.setSessionHistoryOpen(false)"
8
- class="absolute bg-black/10 backdrop-blur-md z-10 h-full w-full"
8
+ class="absolute z-10 h-full w-full bg-lightScrim dark:bg-darkScrim"
9
9
  >
10
10
  </div>
11
11
  <div class="relative flex-1 min-h-0 overflow-hidden [container-type:size]" @click="recalculateScroll()">
@@ -36,7 +36,7 @@
36
36
 
37
37
  <div
38
38
  v-for="(message, index) in props.messages" :key="index"
39
- class="flex flex-col w-full mt-2 pb-2"
39
+ class="flex flex-col w-full pt-5 first:pt-4"
40
40
  :class="message.role === 'user' ? 'self-end' : 'self-start'"
41
41
  ref="messagesRefs"
42
42
  >
@@ -50,25 +50,27 @@
50
50
  <div class="flex items-center justify-center w-11 h-11 rounded-xl bg-lightPrimary/10 text-lightPrimary dark:bg-darkPrimary/15 dark:text-darkPrimary">
51
51
  <IconSparkles class="w-6 h-6" />
52
52
  </div>
53
- <h2 class="mt-4 text-xl font-semibold text-lightNavbarText dark:text-darkNavbarText">
53
+ <h2 class="mt-4 text-lg font-semibold tracking-tight text-lightNavbarText dark:text-darkNavbarText">
54
54
  {{ $t('How can I help?') }}
55
55
  </h2>
56
- <p class="mt-1.5 max-w-xs text-sm leading-relaxed text-gray-600 dark:text-gray-400">
56
+ <p class="mt-1.5 max-w-xs text-sm leading-relaxed text-lightInputIconColor dark:text-darkInputIconColor">
57
57
  {{ $t('Ask about your data, build charts or update records.') }}
58
58
  </p>
59
59
  <div v-if="suggestions.length" class="mt-7 w-full max-w-sm flex flex-col gap-2 text-left">
60
- <p class="pl-0.5 text-xs font-medium text-gray-500 dark:text-gray-400">{{ $t('Try asking') }}</p>
60
+ <p class="pl-0.5 text-xs font-medium text-lightInputIconColor dark:text-darkInputIconColor">{{ $t('Try asking') }}</p>
61
61
  <button
62
62
  v-for="suggestion in suggestions"
63
63
  :key="suggestion"
64
64
  type="button"
65
- class="group flex items-center gap-2.5 w-full px-3 py-2.5 rounded-xl border text-sm text-left transition-colors duration-150
66
- border-gray-200 text-lightNavbarText hover:border-gray-300 hover:bg-gray-50
67
- dark:border-gray-700 dark:text-darkNavbarText dark:hover:border-gray-600 dark:hover:bg-gray-800"
65
+ class="group flex items-center gap-2.5 w-full px-3 py-2.5 rounded-lg border text-sm text-left transition-colors duration-150
66
+ border-lightCardBorder bg-lightCardBackground text-lightNavbarText hover:bg-lightCardBackgroundHover
67
+ focus:outline-none focus-visible:ring-[3px] focus-visible:ring-lightFocusRing
68
+ dark:border-darkCardBorder dark:bg-darkCardBackground dark:text-darkNavbarText dark:hover:bg-darkCardBackgroundHover
69
+ dark:focus-visible:ring-darkFocusRing"
68
70
  @click="applySuggestion(suggestion)"
69
71
  >
70
72
  <span class="flex-1 min-w-0">{{ suggestion }}</span>
71
- <IconArrowRight class="w-4 h-4 shrink-0 text-gray-400 transition-transform duration-150 group-hover:translate-x-0.5" />
73
+ <IconArrowRight class="w-4 h-4 shrink-0 text-lightInputIconColor transition-transform duration-150 group-hover:translate-x-0.5 dark:text-darkInputIconColor" />
72
74
  </button>
73
75
  </div>
74
76
  </div>
@@ -84,18 +86,17 @@
84
86
  <button
85
87
  v-if="showScrollToBottomButton"
86
88
  @click="scrollContainer.scrollToBottom();"
87
- class="absolute z-10 bottom-8 left-1/2 -translate-x-1/2
88
- bg-lightPrimary/20 dark:bg-darkPrimary/10
89
- border border-lightPrimary dark:border-darkPrimary
90
- text-lightPrimary dark:text-darkPrimary
91
- backdrop-blur-sm rounded-full
92
- w-10 h-10 flex items-center justify-center gap-0.5"
93
- :class="{ 'w-12 h-8': showAnimationInScrollToBottomButton }"
89
+ class="absolute z-10 bottom-8 left-1/2 -translate-x-1/2 flex items-center justify-center gap-0.5 w-[2.125rem] h-[2.125rem] rounded-full border
90
+ border-lightInputBorder bg-lightInputBackground text-lightInputIconColor shadow-popover hover:text-lightInputText
91
+ focus:outline-none focus-visible:ring-[3px] focus-visible:ring-lightFocusRing
92
+ dark:border-darkInputBorder dark:bg-darkInputBackground dark:text-darkInputIconColor dark:shadow-darkPopover dark:hover:text-darkInputText
93
+ dark:focus-visible:ring-darkFocusRing"
94
+ :class="{ 'w-12': showAnimationInScrollToBottomButton }"
95
+ :aria-label="$t('Scroll to the latest message')"
94
96
  >
95
- <IconArrowDownOutline
97
+ <IconArrowDown
96
98
  v-if="!showAnimationInScrollToBottomButton"
97
- class="p-2 w-10 h-10 transition-opacity duration-100 ease-in "
98
- :disabled="!showScrollToBottomButton"
99
+ class="w-4 h-4"
99
100
  />
100
101
  <ThreeDotsAnimation
101
102
  v-else
@@ -110,8 +111,7 @@
110
111
  <script setup lang="ts">
111
112
  import type { IMessage } from '../types';
112
113
  import { useTemplateRef, ref, onMounted, onUnmounted, watch, nextTick, defineAsyncComponent, computed } from 'vue';
113
- import { IconArrowDownOutline } from '@iconify-prerendered/vue-flowbite';
114
- import { IconArrowRight, IconSparkles } from '@iconify-prerendered/vue-heroicons';
114
+ import { IconArrowDown, IconArrowRight, IconSparkles } from '@iconify-prerendered/vue-lucide';
115
115
  import SessionsHistory from '../SessionsHistory.vue';
116
116
  import { useAgentStore } from '../composables/useAgentStore';
117
117
  import { useAgentTransitions } from '../composables/useAgentTransitions';
@@ -18,34 +18,38 @@
18
18
  >
19
19
  <div
20
20
  v-if="showActionsBar && showEditButton"
21
- class="absolute flex -bottom-6 p-1 mt-0.5 z-20"
21
+ class="absolute flex top-full -mt-1 p-1 z-20"
22
22
  :class="isUserMessage ? 'right-0 self-end mr-4' : 'left-0 self-start ml-4'"
23
23
  @mouseenter="showEditButtonOnHover"
24
24
  @mouseleave="hideEditButtonOnHover"
25
25
  >
26
- <button
26
+ <Button
27
27
  v-if="canCopy"
28
- type="button"
29
- :class="ACTION_BUTTON_CLASSES"
28
+ variant="ghost"
29
+ size="sm"
30
+ iconOnly
30
31
  :title="$t('Copy message')"
32
+ :aria-label="$t('Copy message')"
31
33
  @click="copyMessageToClipboard"
32
34
  >
33
- <IconFileCopyOutline class="w-4 h-4" />
34
- </button>
35
- <button
35
+ <IconCopy />
36
+ </Button>
37
+ <Button
36
38
  v-if="canEdit"
37
- type="button"
38
- :class="ACTION_BUTTON_CLASSES"
39
+ variant="ghost"
40
+ size="sm"
41
+ iconOnly
39
42
  :title="$t('Edit message')"
43
+ :aria-label="$t('Edit message')"
40
44
  @click="agentStore.startEditMessage(message)"
41
45
  >
42
- <IconPenOutline class="w-4 h-4" />
43
- </button>
46
+ <IconPencil />
47
+ </Button>
44
48
  </div>
45
49
  </Transition>
46
50
  <div
47
51
  v-if="message.role === 'user' && message.metadata?.steer && !isBeingEditedTurn"
48
- class="self-end mr-4 mb-0.5 text-xs italic text-gray-400 dark:text-gray-500"
52
+ class="self-end mr-4 mb-0.5 text-xs italic text-lightInputPlaceholderText dark:text-darkInputPlaceholderText"
49
53
  >
50
54
  {{ $t('Steering instruction') }}
51
55
  </div>
@@ -83,7 +87,8 @@
83
87
 
84
88
  <script setup lang="ts">
85
89
  import { computed, ref } from 'vue';
86
- import { IconPenOutline, IconFileCopyOutline } from '@iconify-prerendered/vue-flowbite';
90
+ import { IconCopy, IconPencil } from '@iconify-prerendered/vue-lucide';
91
+ import { Button } from '@/afcl';
87
92
  import TextRenderer from './TextRenderer.vue';
88
93
  import type { IMessage } from '../types';
89
94
  import { getMessageParts } from '../utils';
@@ -99,10 +104,6 @@
99
104
  isLastMessageInChat: boolean
100
105
  }>();
101
106
 
102
- const ACTION_BUTTON_CLASSES = `flex items-center justify-center w-7 h-7 rounded-md transition-colors duration-150
103
- text-gray-500 hover:bg-gray-100 hover:text-gray-800
104
- dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-200`;
105
-
106
107
  const agentStore = useAgentStore();
107
108
  const { alert } = useAdminforth();
108
109
  const showEditButton = ref(false);
@@ -2,21 +2,21 @@
2
2
  <template v-if="timelineParts.length > 0 || inProgress">
3
3
  <button
4
4
  type="button"
5
- class="z-20 self-start flex items-center gap-1.5 mx-4 my-1 select-none text-[0.9375rem] font-medium transition-colors duration-150
6
- text-gray-600 dark:text-gray-400"
7
- :class="timelineParts.length > 0 ? 'hover:text-gray-900 dark:hover:text-gray-200' : 'cursor-default'"
5
+ class="z-20 self-start flex items-center gap-1 mx-4 mb-2 select-none text-[13px] font-medium transition-colors duration-150
6
+ text-lightInputIconColor dark:text-darkInputIconColor"
7
+ :class="timelineParts.length > 0 ? 'hover:text-lightInputText dark:hover:text-darkInputText' : 'cursor-default'"
8
8
  @click="isExpanded = !isExpanded"
9
9
  >
10
10
  <IconChevronRight
11
11
  v-if="timelineParts.length > 0"
12
- class="w-4 h-4 transition-transform duration-200"
12
+ class="w-3.5 h-3.5 transition-transform duration-200"
13
13
  :class="isExpanded ? 'rotate-90' : 'rotate-0'"
14
14
  />
15
15
  <template v-if="inProgress">
16
16
  <span
17
- class="shine-text text-listTableHeadingText dark:text-darkListTableHeadingText
18
- bg-[linear-gradient(-65deg,currentColor,_rgb(120,120,120)_50%,currentColor)]
19
- dark:bg-[linear-gradient(-65deg,currentColor,_rgb(250,250,250,0.8)_70%,currentColor)]"
17
+ class="shine-text
18
+ bg-[linear-gradient(-65deg,currentColor,theme(colors.lightInputPlaceholderText)_50%,currentColor)]
19
+ dark:bg-[linear-gradient(-65deg,currentColor,theme(colors.darkInputText)_70%,currentColor)]"
20
20
  >
21
21
  {{ $t('Thinking') }}
22
22
  </span>
@@ -34,8 +34,8 @@
34
34
  <div
35
35
  v-if="timelineParts.length > 0"
36
36
  v-show="isExpanded"
37
- class="z-20 mx-4 mt-1 mb-3 overflow-hidden rounded-xl border
38
- border-gray-100 bg-gray-50/70 dark:border-gray-700 dark:bg-gray-800/50"
37
+ class="z-20 mx-4 mb-3 overflow-hidden rounded-lg border
38
+ border-lightCardBorder bg-lightCardBackground dark:border-darkCardBorder dark:bg-darkCardBackground"
39
39
  >
40
40
  <CustomAutoScrollContainer
41
41
  ref="scrollContainerRef"
@@ -52,7 +52,7 @@
52
52
  <ToolRenderer v-else-if="part.type === 'data-tool-call'" :data="formatToolCallPart(part)" />
53
53
  <li
54
54
  v-else-if="part.type === 'data-rendering'"
55
- class="flex items-center gap-2 py-0.5 text-[0.8125rem] text-gray-700 dark:text-gray-300"
55
+ class="flex items-center gap-2 py-0.5 text-[0.8125rem] text-lightTableText dark:text-darkTableText"
56
56
  >
57
57
  <span class="flex items-center justify-center w-4 h-4 shrink-0">
58
58
  <span class="w-2 h-2 rounded-full bg-current animate-pulse" />
@@ -73,7 +73,7 @@
73
73
  <script setup lang="ts">
74
74
  import type { IFormattedToolCallPart, IMessage, IPart } from '../types';
75
75
  import { ref, computed, watch, onUnmounted, onMounted, defineAsyncComponent } from 'vue';
76
- import { IconChevronRight } from '@iconify-prerendered/vue-heroicons';
76
+ import { IconChevronRight } from '@iconify-prerendered/vue-lucide';
77
77
  import ReasoningRenderer from './ReasoningRenderer.vue';
78
78
  import ToolRenderer from './ToolRenderer.vue';
79
79
  import ThreeDotsAnimation from './ThreeDotsAnimation.vue';
@@ -5,19 +5,19 @@
5
5
  class="flex items-center gap-2 w-full py-0.5 text-left text-[0.8125rem] leading-5 select-none"
6
6
  @click="isExpanded = !isExpanded"
7
7
  >
8
- <IconBrainOutline class="w-4 h-4 shrink-0 text-gray-500 dark:text-gray-400" />
9
- <span class="min-w-0 truncate font-medium text-gray-700 dark:text-gray-300">{{ reasoningTitle || $t('Reasoning') }}</span>
8
+ <IconBrain class="w-4 h-4 shrink-0 text-lightInputIconColor dark:text-darkInputIconColor" />
9
+ <span class="min-w-0 truncate font-medium text-lightTableText dark:text-darkTableText">{{ reasoningTitle || $t('Reasoning') }}</span>
10
10
  <ThreeDotsAnimation v-if="isStreaming"/>
11
11
  <IconChevronDown
12
12
  :class="isExpanded ? 'rotate-180' : 'rotate-0'"
13
- class="ml-auto w-3.5 h-3.5 shrink-0 text-gray-400 transition-transform duration-200"
13
+ class="ml-auto w-3.5 h-3.5 shrink-0 text-lightInputIconColor transition-transform duration-200 dark:text-darkInputIconColor"
14
14
  />
15
15
  </button>
16
16
  <transition name="expand">
17
17
  <IncremarkContent
18
18
  v-if="isExpanded"
19
19
  v-show="isExpanded"
20
- class="ml-6 mb-1 text-sm text-gray-600 dark:text-gray-400"
20
+ class="ml-6 mb-1 text-sm text-lightInputIconColor dark:text-darkInputIconColor"
21
21
  :content="reasoningText"
22
22
  />
23
23
  </transition>
@@ -27,8 +27,7 @@
27
27
 
28
28
 
29
29
  <script setup lang="ts">
30
- import { IconBrainOutline } from '@iconify-prerendered/vue-flowbite';
31
- import { IconChevronDown } from '@iconify-prerendered/vue-heroicons';
30
+ import { IconBrain, IconChevronDown } from '@iconify-prerendered/vue-lucide';
32
31
  import type { IPart } from '../types';
33
32
  import { ref, computed, watch, defineAsyncComponent } from 'vue';
34
33
  import ThreeDotsAnimation from './ThreeDotsAnimation.vue';
@@ -1,10 +1,10 @@
1
1
  <template>
2
2
  <p :class="`${TEXT_CLASSES}`" v-if="message === RESERVED_SYSTEM_MESSAGE_CONTENT.START_AUDIO_CHAT">
3
- <IconPhoneSolid class="inline-block w-4 h-4 mr-1" />
3
+ <IconPhone class="inline-block w-4 h-4 mr-1" />
4
4
  {{$t('Audio chat started')}}
5
5
  </p>
6
6
  <p :class="`${TEXT_CLASSES}`" v-else-if="message === RESERVED_SYSTEM_MESSAGE_CONTENT.END_AUDIO_CHAT">
7
- <IconPhoneHangupSolid class="inline-block w-4 h-4 mr-1" />
7
+ <IconPhoneOff class="inline-block w-4 h-4 mr-1" />
8
8
  {{$t('Audio chat ended')}}
9
9
  </p>
10
10
  <p :class="`${TEXT_CLASSES}`" v-else-if="message === RESERVED_SYSTEM_MESSAGE_CONTENT.AGENT_RESPONSE_ABORTED">
@@ -17,9 +17,9 @@
17
17
 
18
18
  <script setup lang="ts">
19
19
  import { RESERVED_SYSTEM_MESSAGE_CONTENT } from '../composables/agentStore/constants';
20
- import { IconPhoneSolid, IconPhoneHangupSolid } from '@iconify-prerendered/vue-flowbite';
20
+ import { IconPhone, IconPhoneOff } from '@iconify-prerendered/vue-lucide';
21
21
 
22
- const TEXT_CLASSES = 'text-center italic text-lightListTableHeadingText dark:text-darkListTableHeadingText flex items-center justify-center';
22
+ const TEXT_CLASSES = 'flex items-center justify-center text-center text-sm italic text-lightInputIconColor dark:text-darkInputIconColor';
23
23
 
24
24
  const props = defineProps<{
25
25
  message: string
@@ -1,13 +1,14 @@
1
1
  <template>
2
2
  <div
3
- class="flex items-center justify-center min-w-0 transition-shadow duration-150 z-20"
3
+ class="flex items-center justify-center min-w-0 text-sm transition-shadow duration-150 z-20"
4
4
  @click="handleMarkdownLinkClick"
5
5
  :class="[
6
- hasVegaLite ? 'w-full my-2' : 'my-2',
6
+ hasVegaLite && 'w-full',
7
7
  props.role === 'user'
8
- ? 'self-end max-w-[82%] mr-4 px-3.5 py-0.5 rounded-2xl rounded-br-md bg-lightPrimary/10 dark:bg-darkPrimary/20'
8
+ ? 'self-end max-w-[82%] mr-4 px-3 py-2 rounded-xl rounded-br [&_.incremark-paragraph]:leading-5 bg-lightSecondaryDarken dark:bg-darkSecondaryLighten'
9
9
  : 'self-start max-w-full px-4',
10
- props.editMode ? 'ring-2 ring-lightPrimary dark:ring-darkPrimary w-full max-w-[calc(100%-2rem)] flex-col items-stretch py-3' : ''
10
+ props.editMode ? `w-full max-w-[calc(100%-2rem)] flex-col items-stretch py-3 border bg-lightInputBackground border-lightInputFocusBorder ring-[3px] ring-lightInputFocusRing
11
+ dark:bg-darkInputBackground dark:border-darkInputFocusBorder dark:ring-darkInputFocusRing` : ''
11
12
  ]"
12
13
  >
13
14
  <IncremarkContent
@@ -19,13 +20,10 @@
19
20
  :components="incremarkComponents"
20
21
  :incremark-options="incremarkOptions"
21
22
  />
22
- <!-- <p v-else class="text-red-500 py-2">
23
- {{ $t('No content to render') }}
24
- </p> -->
25
23
  <template v-if="props.editMode">
26
24
  <textarea
27
25
  v-model="agentStore.userMessageInput"
28
- class="w-full min-h-24 resize-y bg-transparent text-sm text-gray-900 dark:text-gray-100 border-none focus:outline-none focus:ring-0 p-0"
26
+ class="w-full min-h-24 resize-y bg-transparent text-sm text-lightInputText dark:text-darkInputText border-none focus:outline-none focus:ring-0 p-0"
29
27
  @keydown.esc.prevent="agentStore.cancelEditMessage"
30
28
  />
31
29
  <EditActionButtons
@@ -155,31 +153,55 @@
155
153
  </script>
156
154
 
157
155
  <style lang="scss">
156
+ // the incremark theme ships its own fonts and palette, point them to the design tokens
157
+ .incremark {
158
+ --incremark-typography-font-family-base: theme('fontFamily.sans');
159
+ --incremark-typography-font-family-mono: theme('fontFamily.mono');
160
+ --incremark-color-text-primary: theme('colors.lightListTableText');
161
+ --incremark-color-text-secondary: theme('colors.lightInputIconColor');
162
+ --incremark-color-text-tertiary: theme('colors.lightInputPlaceholderText');
163
+ --incremark-color-border-default: theme('colors.lightCardBorder');
164
+ --incremark-color-border-strong: theme('colors.lightCardBorder');
165
+ --incremark-color-border-subtle: theme('colors.lightCardBorder');
166
+ --incremark-color-background-base: theme('colors.lightCardBackground');
167
+ --incremark-color-background-elevated: theme('colors.lightCardBackgroundHover');
168
+ --incremark-color-code-inline-background: theme('colors.lightSecondaryDarken');
169
+ --incremark-color-code-inline-text: theme('colors.lightInputText');
170
+ --incremark-color-brand-primary: theme('colors.lightPrimary');
171
+ --incremark-color-interactive-link: theme('colors.lightPrimary');
172
+ --incremark-color-interactive-link-hover: theme('colors.lightPrimary');
173
+ --incremark-color-interactive-link-visited: theme('colors.lightPrimary');
174
+ }
175
+
176
+ .dark .incremark {
177
+ --incremark-color-text-primary: theme('colors.darkListTableText');
178
+ --incremark-color-text-secondary: theme('colors.darkInputIconColor');
179
+ --incremark-color-text-tertiary: theme('colors.darkInputPlaceholderText');
180
+ --incremark-color-border-default: theme('colors.darkCardBorder');
181
+ --incremark-color-border-strong: theme('colors.darkCardBorder');
182
+ --incremark-color-border-subtle: theme('colors.darkCardBorder');
183
+ --incremark-color-background-base: theme('colors.darkCardBackground');
184
+ --incremark-color-background-elevated: theme('colors.darkCardBackgroundHover');
185
+ --incremark-color-code-inline-background: theme('colors.darkSecondaryLighten');
186
+ --incremark-color-code-inline-text: theme('colors.darkInputText');
187
+ --incremark-color-brand-primary: theme('colors.darkPrimary');
188
+ --incremark-color-interactive-link: theme('colors.darkPrimary');
189
+ --incremark-color-interactive-link-hover: theme('colors.darkPrimary');
190
+ --incremark-color-interactive-link-visited: theme('colors.darkPrimary');
191
+ }
192
+
158
193
  .incremark a.incremark-link,
159
194
  .incremark a.incremark-link:visited {
195
+ @apply text-lightPrimary dark:text-darkPrimary;
160
196
  display: inline-block;
161
197
  text-decoration: underline;
162
198
  text-underline-offset: 4px;
163
- text-decoration-style:dotted;
164
- color: rgb(0, 0, 0);
165
- transition: color 0.2s ease;
199
+ text-decoration-style: dotted;
166
200
  word-break: break-all;
167
201
  }
168
202
 
169
203
  .incremark a.incremark-link:hover {
170
- color: rgb(74, 74, 255);
171
- text-decoration: underline;
172
- text-underline-offset: 4px;
173
- text-decoration-style:dotted;
174
- }
175
-
176
- html[data-theme="dark"] .incremark a.incremark-link,
177
- html[data-theme="dark"] .incremark a.incremark-link:visited {
178
- color: rgb(220, 220, 220);
179
- }
180
-
181
- html[data-theme="dark"] .incremark a.incremark-link:hover {
182
- color: rgb(147, 147, 255);
204
+ text-decoration-style: solid;
183
205
  }
184
206
 
185
207
  a.incremark-link::after {
@@ -198,11 +220,27 @@ a.incremark-link::after {
198
220
  word-break: break-word;
199
221
  }
200
222
 
201
- .incremark-list {
223
+ // scoped under .incremark: the incremark theme is imported lazily and would win an equal selector
224
+ .incremark .incremark-list {
202
225
  list-style: disc;
226
+ margin: 0 0 8px;
227
+ padding-left: 18px;
228
+ }
229
+
230
+ .incremark .incremark-list-item {
231
+ margin: 2px 0;
232
+ }
233
+
234
+ .incremark .incremark-paragraph {
235
+ margin: 0 0 8px;
236
+ }
237
+
238
+ .incremark .incremark-list-item > .incremark-paragraph {
239
+ margin: 0;
203
240
  }
204
241
 
205
- .incremark-paragraph {
206
- margin: 8px 0;
242
+ // the gap between messages comes from the conversation, not from the last block of a message
243
+ .incremark > .incremark-block:last-child > :last-child {
244
+ margin-bottom: 0;
207
245
  }
208
246
  </style>