@adminforth/agent 2.9.1 → 3.0.0
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.
- package/README.md +4 -0
- package/dist/application/runTurnUseCase.d.ts +2 -1
- package/dist/application/runTurnUseCase.js +3 -3
- package/dist/custom/ChatFooter.vue +91 -104
- package/dist/custom/ChatHeader.vue +63 -62
- package/dist/custom/ChatSurface.vue +11 -18
- package/dist/custom/EditActionButtons.vue +12 -8
- package/dist/custom/SessionsHistory.vue +90 -28
- package/dist/custom/SteerQueue.vue +15 -9
- package/dist/custom/composables/agentStore/constants.ts +1 -1
- package/dist/custom/composables/agentStore/useAgentChat.ts +4 -3
- package/dist/custom/composables/agentStore/useAgentPlaceholder.ts +1 -0
- package/dist/custom/composables/agentStore/useAgentSessions.ts +23 -2
- package/dist/custom/composables/useAgentStore.ts +8 -29
- package/dist/custom/conversation_area/ConversationArea.vue +48 -16
- package/dist/custom/conversation_area/MessageRenderer.vue +18 -13
- package/dist/custom/conversation_area/ProcessingTimeline.vue +83 -123
- package/dist/custom/conversation_area/ReasoningRenderer.vue +13 -16
- package/dist/custom/conversation_area/SystemMessageRenderer.vue +4 -4
- package/dist/custom/conversation_area/TextRenderer.vue +67 -28
- package/dist/custom/conversation_area/ToolApprovalRenderer.vue +89 -56
- package/dist/custom/conversation_area/ToolRenderer.vue +44 -82
- package/dist/custom/incremark_code_renderers/IncremarkShikiCodeBlock.vue +22 -61
- package/dist/custom/speech_recognition_frontend/AudioLines.vue +1 -2
- package/dist/custom/speech_recognition_frontend/MicrophoneButon.vue +36 -32
- package/dist/custom/types.ts +16 -8
- package/dist/domain/agentEvents.d.ts +3 -2
- package/dist/tools/approvalFormatter.d.ts +19 -5
- package/dist/tools/approvalFormatter.js +88 -40
- package/dist/transport/http/context.d.ts +2 -1
- package/dist/transport/http/sessionEndpoints.js +34 -0
- package/package.json +3 -3
- package/dist/custom/SteerDebugPanel.vue +0 -45
- package/dist/custom/conversation_area/ToolsGroup.vue +0 -59
|
@@ -1,58 +1,69 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<template v-if="
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
<template v-if="timelineParts.length > 0 || inProgress">
|
|
3
|
+
<button
|
|
4
|
+
type="button"
|
|
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'"
|
|
6
8
|
@click="isExpanded = !isExpanded"
|
|
7
9
|
>
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
bg-[linear-gradient(-65deg,currentColor,_rgb(120,120,120)_50%,currentColor)]
|
|
13
|
-
dark:bg-[linear-gradient(-65deg,currentColor,_rgb(250,250,250,0.8)_70%,currentColor)]
|
|
14
|
-
`
|
|
15
|
-
: '']"
|
|
16
|
-
>
|
|
17
|
-
{{ inProgress ? $t('Thinking') : $t('Thoughts') }}
|
|
18
|
-
</p>
|
|
19
|
-
<ThreeDotsAnimation v-if="inProgress" />
|
|
20
|
-
<span v-if="thinkingDuration > 0">({{ (thinkingDuration/1000).toFixed(2) }} s)</span>
|
|
21
|
-
<IconAngleDownOutline
|
|
22
|
-
v-if="ToolOrReasoningParts.length > 0"
|
|
23
|
-
:class="isExpanded ? 'rotate-180' : 'rotate-0'"
|
|
24
|
-
class="transition-transform duration-200"
|
|
10
|
+
<IconChevronRight
|
|
11
|
+
v-if="timelineParts.length > 0"
|
|
12
|
+
class="w-3.5 h-3.5 transition-transform duration-200"
|
|
13
|
+
:class="isExpanded ? 'rotate-90' : 'rotate-0'"
|
|
25
14
|
/>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
15
|
+
<template v-if="inProgress">
|
|
16
|
+
<span
|
|
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
|
+
>
|
|
21
|
+
{{ $t('Thinking') }}
|
|
22
|
+
</span>
|
|
23
|
+
<ThreeDotsAnimation />
|
|
24
|
+
</template>
|
|
25
|
+
<template v-else>
|
|
26
|
+
<span>{{ thinkingSeconds ? $t('Thought for {seconds}s', { seconds: thinkingSeconds }) : $t('Thoughts') }}</span>
|
|
27
|
+
<span v-if="toolCallsCount">
|
|
28
|
+
· {{ toolCallsCount === 1 ? $t('1 tool') : $t('{count} tools', { count: toolCallsCount }) }}
|
|
29
|
+
</span>
|
|
30
|
+
</template>
|
|
31
|
+
</button>
|
|
32
|
+
<transition name="expand">
|
|
33
|
+
<!-- the box is inset from the message edge, so its own scrollbar never sits on top of the conversation scrollbar -->
|
|
34
|
+
<div
|
|
35
|
+
v-if="timelineParts.length > 0"
|
|
33
36
|
v-show="isExpanded"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
marginRight: '1rem',
|
|
37
|
-
}"
|
|
38
|
-
:scrollBarAutoHide="false"
|
|
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
|
-
<
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
40
|
+
<CustomAutoScrollContainer
|
|
41
|
+
ref="scrollContainerRef"
|
|
42
|
+
class="max-h-48 sm:max-h-96 overflow-y-auto"
|
|
43
|
+
:enabled="isResponseInProgress"
|
|
44
|
+
behavior="smooth"
|
|
45
|
+
:threshold="5"
|
|
46
|
+
:scrollBarAutoHide="false"
|
|
47
|
+
>
|
|
48
|
+
<!-- wider right padding keeps the row chevrons clear of the box's scrollbar -->
|
|
49
|
+
<ul class="flex flex-col gap-1 pl-2.5 pr-5 py-2">
|
|
50
|
+
<template v-for="(part, index) in timelineParts" :key="index">
|
|
51
|
+
<ReasoningRenderer v-if="part.type === 'reasoning'" :state="part.state" :text="part.text" />
|
|
52
|
+
<ToolRenderer v-else-if="part.type === 'data-tool-call'" :data="formatToolCallPart(part)" />
|
|
53
|
+
<li
|
|
54
|
+
v-else-if="part.type === 'data-rendering'"
|
|
55
|
+
class="flex items-center gap-2 py-0.5 text-[0.8125rem] text-lightTableText dark:text-darkTableText"
|
|
56
|
+
>
|
|
57
|
+
<span class="flex items-center justify-center w-4 h-4 shrink-0">
|
|
58
|
+
<span class="w-2 h-2 rounded-full bg-current animate-pulse" />
|
|
59
|
+
</span>
|
|
60
|
+
{{ part.data?.label ?? 'Rendering...' }}
|
|
50
61
|
<ThreeDotsAnimation />
|
|
51
|
-
</
|
|
52
|
-
</
|
|
53
|
-
</
|
|
54
|
-
</
|
|
55
|
-
</
|
|
62
|
+
</li>
|
|
63
|
+
</template>
|
|
64
|
+
</ul>
|
|
65
|
+
</CustomAutoScrollContainer>
|
|
66
|
+
</div>
|
|
56
67
|
</transition>
|
|
57
68
|
</template>
|
|
58
69
|
</template>
|
|
@@ -60,14 +71,13 @@
|
|
|
60
71
|
|
|
61
72
|
|
|
62
73
|
<script setup lang="ts">
|
|
63
|
-
import type { IFormattedToolCallPart, IMessage, IPart
|
|
74
|
+
import type { IFormattedToolCallPart, IMessage, IPart } from '../types';
|
|
64
75
|
import { ref, computed, watch, onUnmounted, onMounted, defineAsyncComponent } from 'vue';
|
|
76
|
+
import { IconChevronRight } from '@iconify-prerendered/vue-lucide';
|
|
65
77
|
import ReasoningRenderer from './ReasoningRenderer.vue';
|
|
66
|
-
import
|
|
78
|
+
import ToolRenderer from './ToolRenderer.vue';
|
|
67
79
|
import ThreeDotsAnimation from './ThreeDotsAnimation.vue';
|
|
68
80
|
import { useAgentStore } from '../composables/useAgentStore';
|
|
69
|
-
import { getMessageParts } from '../utils';
|
|
70
|
-
import ToolsGroup from './ToolsGroup.vue';
|
|
71
81
|
|
|
72
82
|
const CustomAutoScrollContainer = defineAsyncComponent(() => import('../CustomAutoScrollContainer.vue'));
|
|
73
83
|
|
|
@@ -83,17 +93,23 @@
|
|
|
83
93
|
const innerScrollContainerRef = ref<HTMLElement | null>(null);
|
|
84
94
|
const isExpanded = ref(true);
|
|
85
95
|
let isUserScrolled = false;
|
|
86
|
-
|
|
96
|
+
// One step per reasoning block and per tool call (its 'start' part; the matching 'end'
|
|
97
|
+
// part is merged in by formatToolCallPart), plus a rendering step while it is running.
|
|
98
|
+
const timelineParts = computed(() => {
|
|
87
99
|
return props.message.parts.filter((part: IPart) => {
|
|
88
|
-
return part.type === '
|
|
89
|
-
|| part.type === '
|
|
100
|
+
return part.type === 'reasoning'
|
|
101
|
+
|| (part.type === 'data-tool-call' && part.data?.phase === 'start')
|
|
90
102
|
|| isActiveRenderingPart(part);
|
|
91
103
|
});
|
|
92
104
|
});
|
|
105
|
+
const toolCallsCount = computed(() => timelineParts.value.filter(part => part.type === 'data-tool-call').length);
|
|
106
|
+
const thinkingSeconds = computed(() => (
|
|
107
|
+
thinkingDuration.value > 0 ? Math.max(1, Math.round(thinkingDuration.value / 1000)) : 0
|
|
108
|
+
));
|
|
93
109
|
const isResponseInProgress = computed(() =>{
|
|
94
|
-
return props.isLastMessageInChat && agentStore.isResponseInProgress;
|
|
110
|
+
return props.isLastMessageInChat && agentStore.isResponseInProgress;
|
|
95
111
|
});
|
|
96
|
-
|
|
112
|
+
|
|
97
113
|
const showFakeThinkingMessage = computed(() => {
|
|
98
114
|
if (props.message.parts.length === 0 && props.isLastMessageInChat) return true;
|
|
99
115
|
return false;
|
|
@@ -141,37 +157,28 @@
|
|
|
141
157
|
}
|
|
142
158
|
});
|
|
143
159
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
const finishedPart = currentMessage.parts.find(candidate => {
|
|
160
|
+
function formatToolCallPart(part: IPart): IFormattedToolCallPart {
|
|
161
|
+
const data = part.data!;
|
|
162
|
+
const finishedPart = props.message.parts.find(candidate => {
|
|
150
163
|
return candidate.type === 'data-tool-call'
|
|
151
|
-
&& candidate.data?.toolCallId ===
|
|
164
|
+
&& candidate.data?.toolCallId === data.toolCallId
|
|
152
165
|
&& candidate.data?.phase === 'end';
|
|
153
166
|
});
|
|
154
167
|
|
|
155
168
|
return {
|
|
156
169
|
type: 'data-tool-call',
|
|
157
170
|
toolInfo: {
|
|
158
|
-
toolCallId:
|
|
159
|
-
toolName:
|
|
171
|
+
toolCallId: data.toolCallId,
|
|
172
|
+
toolName: data.toolName,
|
|
160
173
|
phase: finishedPart ? 'end' : 'start',
|
|
161
174
|
durationMs: finishedPart?.data?.durationMs,
|
|
162
|
-
input:
|
|
175
|
+
input: data.input,
|
|
163
176
|
output: finishedPart?.data?.output,
|
|
164
|
-
toolInfo:
|
|
177
|
+
toolInfo: data.toolInfo,
|
|
165
178
|
error: finishedPart?.data?.error,
|
|
166
179
|
}
|
|
167
180
|
};
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const getVisibleTimelineParts = (message: IMessage) => {
|
|
171
|
-
return getMessageParts(message).filter(part => {
|
|
172
|
-
return part.type === 'reasoning' || (part.type === 'data-tool-call' && part.data?.phase === 'start');
|
|
173
|
-
});
|
|
174
|
-
};
|
|
181
|
+
}
|
|
175
182
|
|
|
176
183
|
function isActiveRenderingPart(part: IPart) {
|
|
177
184
|
return part.type === 'data-rendering'
|
|
@@ -181,55 +188,8 @@
|
|
|
181
188
|
});
|
|
182
189
|
}
|
|
183
190
|
|
|
184
|
-
const groupToolCallParts = (message: IMessage, currentPart: IPart): IToolGroup[] => {
|
|
185
|
-
if (currentPart.type !== 'data-tool-call') {
|
|
186
|
-
return [];
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
const visibleParts = getVisibleTimelineParts(message);
|
|
190
|
-
const currentPartIndex = visibleParts.findIndex(part => part === currentPart);
|
|
191
|
-
|
|
192
|
-
if (currentPartIndex === -1) {
|
|
193
|
-
return [];
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
if (currentPartIndex > 0 && visibleParts[currentPartIndex - 1]?.type === 'data-tool-call') {
|
|
197
|
-
return [];
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
const groupedParts: IToolGroup[] = [];
|
|
201
|
-
|
|
202
|
-
for (let index = currentPartIndex; index < visibleParts.length; index += 1) {
|
|
203
|
-
const part = visibleParts[index];
|
|
204
|
-
|
|
205
|
-
if (part.type === 'reasoning') {
|
|
206
|
-
break;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
const formattedPart = formatToolCallPart(part, message);
|
|
210
|
-
|
|
211
|
-
if (!formattedPart) {
|
|
212
|
-
continue;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
const lastGroup = groupedParts[groupedParts.length - 1];
|
|
216
|
-
|
|
217
|
-
if (lastGroup?.title === formattedPart.toolInfo.toolName) {
|
|
218
|
-
lastGroup.groupedTools.push(formattedPart);
|
|
219
|
-
continue;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
groupedParts.push({
|
|
223
|
-
title: formattedPart.toolInfo.toolName,
|
|
224
|
-
groupedTools: [formattedPart],
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
return groupedParts;
|
|
229
|
-
};
|
|
230
|
-
|
|
231
191
|
function handleScroll() {
|
|
232
|
-
if (isUserScrolled) {
|
|
192
|
+
if (isUserScrolled) {
|
|
233
193
|
scrollContainerRef.value?.handleScroll();
|
|
234
194
|
}
|
|
235
195
|
}
|
|
@@ -1,36 +1,33 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<li class="
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
</div>
|
|
7
|
-
</span>
|
|
8
|
-
<h3
|
|
9
|
-
class=" flex items-center mb-1 text-sm ml-3 gap-1 cursor-pointer select-none hover:opacity-80 text-listTableHeadingText dark:text-darkListTableHeadingText"
|
|
2
|
+
<li class="overflow-hidden">
|
|
3
|
+
<button
|
|
4
|
+
type="button"
|
|
5
|
+
class="flex items-center gap-2 w-full py-0.5 text-left text-[0.8125rem] leading-5 select-none"
|
|
10
6
|
@click="isExpanded = !isExpanded"
|
|
11
7
|
>
|
|
12
|
-
<
|
|
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>
|
|
13
10
|
<ThreeDotsAnimation v-if="isStreaming"/>
|
|
14
|
-
<
|
|
11
|
+
<IconChevronDown
|
|
15
12
|
:class="isExpanded ? 'rotate-180' : 'rotate-0'"
|
|
16
|
-
class="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"
|
|
17
14
|
/>
|
|
18
|
-
</
|
|
15
|
+
</button>
|
|
19
16
|
<transition name="expand">
|
|
20
17
|
<IncremarkContent
|
|
21
|
-
v-if="isExpanded"
|
|
18
|
+
v-if="isExpanded"
|
|
22
19
|
v-show="isExpanded"
|
|
23
|
-
class="
|
|
20
|
+
class="ml-6 mb-1 text-sm text-lightInputIconColor dark:text-darkInputIconColor"
|
|
24
21
|
:content="reasoningText"
|
|
25
22
|
/>
|
|
26
|
-
</transition>
|
|
23
|
+
</transition>
|
|
27
24
|
</li>
|
|
28
25
|
</template>
|
|
29
26
|
|
|
30
27
|
|
|
31
28
|
|
|
32
29
|
<script setup lang="ts">
|
|
33
|
-
import {
|
|
30
|
+
import { IconBrain, IconChevronDown } from '@iconify-prerendered/vue-lucide';
|
|
34
31
|
import type { IPart } from '../types';
|
|
35
32
|
import { ref, computed, watch, defineAsyncComponent } from 'vue';
|
|
36
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
|
-
<
|
|
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
|
-
<
|
|
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 {
|
|
20
|
+
import { IconPhone, IconPhoneOff } from '@iconify-prerendered/vue-lucide';
|
|
21
21
|
|
|
22
|
-
const TEXT_CLASSES = '
|
|
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,12 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
-
class="flex items-center justify-center
|
|
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
|
|
7
|
-
props.role === 'user'
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
hasVegaLite && 'w-full',
|
|
7
|
+
props.role === 'user'
|
|
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
|
+
: 'self-start max-w-full px-4',
|
|
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` : ''
|
|
10
12
|
]"
|
|
11
13
|
>
|
|
12
14
|
<IncremarkContent
|
|
@@ -18,13 +20,10 @@
|
|
|
18
20
|
:components="incremarkComponents"
|
|
19
21
|
:incremark-options="incremarkOptions"
|
|
20
22
|
/>
|
|
21
|
-
<!-- <p v-else class="text-red-500 py-2">
|
|
22
|
-
{{ $t('No content to render') }}
|
|
23
|
-
</p> -->
|
|
24
23
|
<template v-if="props.editMode">
|
|
25
24
|
<textarea
|
|
26
25
|
v-model="agentStore.userMessageInput"
|
|
27
|
-
class="w-full min-h-24 resize-y bg-transparent text-sm text-
|
|
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"
|
|
28
27
|
@keydown.esc.prevent="agentStore.cancelEditMessage"
|
|
29
28
|
/>
|
|
30
29
|
<EditActionButtons
|
|
@@ -154,31 +153,55 @@
|
|
|
154
153
|
</script>
|
|
155
154
|
|
|
156
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
|
+
|
|
157
193
|
.incremark a.incremark-link,
|
|
158
194
|
.incremark a.incremark-link:visited {
|
|
195
|
+
@apply text-lightPrimary dark:text-darkPrimary;
|
|
159
196
|
display: inline-block;
|
|
160
197
|
text-decoration: underline;
|
|
161
198
|
text-underline-offset: 4px;
|
|
162
|
-
text-decoration-style:dotted;
|
|
163
|
-
color: rgb(0, 0, 0);
|
|
164
|
-
transition: color 0.2s ease;
|
|
199
|
+
text-decoration-style: dotted;
|
|
165
200
|
word-break: break-all;
|
|
166
201
|
}
|
|
167
202
|
|
|
168
203
|
.incremark a.incremark-link:hover {
|
|
169
|
-
|
|
170
|
-
text-decoration: underline;
|
|
171
|
-
text-underline-offset: 4px;
|
|
172
|
-
text-decoration-style:dotted;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
html[data-theme="dark"] .incremark a.incremark-link,
|
|
176
|
-
html[data-theme="dark"] .incremark a.incremark-link:visited {
|
|
177
|
-
color: rgb(220, 220, 220);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
html[data-theme="dark"] .incremark a.incremark-link:hover {
|
|
181
|
-
color: rgb(147, 147, 255);
|
|
204
|
+
text-decoration-style: solid;
|
|
182
205
|
}
|
|
183
206
|
|
|
184
207
|
a.incremark-link::after {
|
|
@@ -197,11 +220,27 @@ a.incremark-link::after {
|
|
|
197
220
|
word-break: break-word;
|
|
198
221
|
}
|
|
199
222
|
|
|
200
|
-
.incremark
|
|
223
|
+
// scoped under .incremark: the incremark theme is imported lazily and would win an equal selector
|
|
224
|
+
.incremark .incremark-list {
|
|
201
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;
|
|
202
240
|
}
|
|
203
241
|
|
|
204
|
-
|
|
205
|
-
|
|
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;
|
|
206
245
|
}
|
|
207
246
|
</style>
|