@adminforth/agent 1.20.0 → 1.22.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/apiBasedTools.ts +7 -0
- package/build.log +12 -6
- package/custom/ChatSurface.vue +2 -2
- package/custom/CustomAutoScrollContainer.vue +127 -0
- package/custom/composables/useAgentStore.ts +8 -4
- package/custom/conversation_area/ConversationArea.vue +109 -0
- package/custom/conversation_area/MessageRenderer.vue +33 -0
- package/custom/conversation_area/ProcessingTimeline.vue +190 -0
- package/custom/conversation_area/ReasoningRenderer.vue +87 -0
- package/{dist/custom/Message.vue → custom/conversation_area/TextRenderer.vue} +14 -102
- package/custom/conversation_area/ThreeDotsAnimation.vue +35 -0
- package/custom/{ToolRenderer.vue → conversation_area/ToolRenderer.vue} +65 -13
- package/custom/conversation_area/ToolsGroup.vue +63 -0
- package/custom/package.json +2 -1
- package/custom/pnpm-lock.yaml +18 -0
- package/custom/skills/data-analytics/SKILL.md +3 -3
- package/custom/types.ts +11 -1
- package/custom/utils.ts +29 -0
- package/dist/apiBasedTools.js +6 -0
- package/dist/custom/ChatSurface.vue +2 -2
- package/dist/custom/CustomAutoScrollContainer.vue +127 -0
- package/dist/custom/composables/useAgentStore.ts +8 -4
- package/dist/custom/conversation_area/ConversationArea.vue +109 -0
- package/dist/custom/conversation_area/MessageRenderer.vue +33 -0
- package/dist/custom/conversation_area/ProcessingTimeline.vue +190 -0
- package/dist/custom/conversation_area/ReasoningRenderer.vue +87 -0
- package/{custom/Message.vue → dist/custom/conversation_area/TextRenderer.vue} +14 -102
- package/dist/custom/conversation_area/ThreeDotsAnimation.vue +35 -0
- package/dist/custom/{ToolRenderer.vue → conversation_area/ToolRenderer.vue} +65 -13
- package/dist/custom/conversation_area/ToolsGroup.vue +63 -0
- package/dist/custom/package.json +2 -1
- package/dist/custom/pnpm-lock.yaml +18 -0
- package/dist/custom/skills/data-analytics/SKILL.md +3 -3
- package/dist/custom/types.ts +11 -1
- package/dist/custom/utils.ts +29 -0
- package/package.json +1 -1
- package/custom/ConversationArea.vue +0 -198
- package/custom/ToolsGroup.vue +0 -67
- package/dist/custom/ConversationArea.vue +0 -198
- package/dist/custom/ToolsGroup.vue +0 -67
|
@@ -1,52 +1,21 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div
|
|
3
3
|
class="max-w-[80%] flex px-4 m-2 rounded-xl border border-gray-200 dark:border-gray-700"
|
|
4
4
|
@click="handleMarkdownLinkClick"
|
|
5
5
|
:class="[
|
|
6
6
|
hasVegaLite ? 'w-full' : '',
|
|
7
7
|
props.role === 'user' ? 'bg-lightListTableHeading dark:bg-darkListTableHeading self-end'
|
|
8
|
-
|
|
9
|
-
: 'bg-blue-100 dark:bg-blue-700/10 self-start'
|
|
8
|
+
: 'border-none self-start'
|
|
10
9
|
]"
|
|
11
10
|
>
|
|
12
11
|
<IncremarkContent
|
|
13
12
|
class="text-wrap break-words w-full max-w-full"
|
|
14
|
-
v-if="content
|
|
13
|
+
v-if="content"
|
|
15
14
|
:content="content"
|
|
16
15
|
:is-finished="isFinished"
|
|
17
16
|
:components="incremarkComponents"
|
|
18
17
|
:incremark-options="incremarkOptions"
|
|
19
18
|
/>
|
|
20
|
-
<!-- reasoning/thinking -->
|
|
21
|
-
<div
|
|
22
|
-
v-else-if="isTypeReasoning || isStateStreaming"
|
|
23
|
-
class="flex flex-col items-start gap-1 text-gray-500 py-2 "
|
|
24
|
-
>
|
|
25
|
-
<div class="flex items-center gap-1 hover:underline cursor-pointer text-lightListTableHeadingText hover:text-lightListTableHeadingText dark:text-darkListTableHeadingText dark:hover:text-darkListTableHeadingText" @click="isThoughtsExpanded = !isThoughtsExpanded">
|
|
26
|
-
<IconAngleDownOutline
|
|
27
|
-
v-if="content"
|
|
28
|
-
:class="isThoughtsExpanded ? 'rotate-180' : 'rotate-0'"
|
|
29
|
-
class="transition-transform duration-200"
|
|
30
|
-
/>
|
|
31
|
-
{{ isStateStreaming ? 'Thinking' : 'Thoughts' }}
|
|
32
|
-
<template v-if="isStateStreaming">
|
|
33
|
-
<span class="bounce-dot1 rounded-full w-2 h-2 bg-lightPrimary"></span>
|
|
34
|
-
<span class="bounce-dot2 rounded-full w-2 h-2 bg-lightPrimary"></span>
|
|
35
|
-
<span class="bounce-dot3 rounded-full w-2 h-2 bg-lightPrimary"></span>
|
|
36
|
-
</template>
|
|
37
|
-
</div>
|
|
38
|
-
<transition name="expand" class="max-h-36 overflow-y-auto">
|
|
39
|
-
<p v-show="isThoughtsExpanded" class="overflow-hidden">
|
|
40
|
-
{{ content }}
|
|
41
|
-
</p>
|
|
42
|
-
</transition>
|
|
43
|
-
</div>
|
|
44
|
-
<div v-else-if="isTypeToolCall && isToolCallStart">
|
|
45
|
-
{{ props.data?.toolName }} start
|
|
46
|
-
</div>
|
|
47
|
-
<div v-else-if="isTypeToolCall && isToolCallEnd">
|
|
48
|
-
{{ props.data?.toolName }} end
|
|
49
|
-
</div>
|
|
50
19
|
<p v-else class="text-red-500 py-2">
|
|
51
20
|
Error occured
|
|
52
21
|
</p>
|
|
@@ -56,12 +25,11 @@
|
|
|
56
25
|
<script setup lang="ts">
|
|
57
26
|
import { computed, defineAsyncComponent, onMounted, ref, watch } from 'vue';
|
|
58
27
|
import { useRouter } from 'vue-router';
|
|
59
|
-
import {
|
|
60
|
-
import { useAgentStore } from './composables/useAgentStore';
|
|
28
|
+
import { useAgentStore } from '../composables/useAgentStore';
|
|
61
29
|
import { useCoreStore } from '@/stores/core';
|
|
62
30
|
|
|
63
31
|
const IncremarkContent = defineAsyncComponent(() => import('@incremark/vue').then(module => module.IncremarkContent))
|
|
64
|
-
const ShikiCodeBlock = defineAsyncComponent(() => import('
|
|
32
|
+
const ShikiCodeBlock = defineAsyncComponent(() => import('../incremark_code_renderers/IncremarkShikiCodeBlock.vue'))
|
|
65
33
|
|
|
66
34
|
const agentStore = useAgentStore();
|
|
67
35
|
const coreStore = useCoreStore();
|
|
@@ -84,10 +52,8 @@
|
|
|
84
52
|
})
|
|
85
53
|
|
|
86
54
|
const props = defineProps<{
|
|
87
|
-
type: string,
|
|
88
55
|
message: string | undefined,
|
|
89
56
|
state: string | undefined,
|
|
90
|
-
data?: any
|
|
91
57
|
role: 'user' | 'assistant'
|
|
92
58
|
}>();
|
|
93
59
|
|
|
@@ -95,27 +61,23 @@
|
|
|
95
61
|
|
|
96
62
|
const content = computed(() => props.message)
|
|
97
63
|
const isFinished = computed(() => props.state === 'done')
|
|
98
|
-
const isThoughtsExpanded = ref(
|
|
99
|
-
const hasVegaLite = computed(() => props.
|
|
64
|
+
const isThoughtsExpanded = ref(true);
|
|
65
|
+
const hasVegaLite = computed(() => props.message?.includes('```vega-lite'))
|
|
100
66
|
|
|
101
|
-
const isTypeReasoning = computed(() => props.type === 'reasoning')
|
|
102
|
-
const isTypeToolCall = computed(() => props.type === 'data-tool-call')
|
|
103
|
-
const isToolCallStart = computed(() => {
|
|
104
|
-
if (props.type !== 'data-tool-call') return false;
|
|
105
|
-
return props.data?.phase === 'start';
|
|
106
|
-
})
|
|
107
|
-
const isToolCallEnd = computed(() => {
|
|
108
|
-
if (props.type !== 'data-tool-call') return false;
|
|
109
|
-
return props.data?.phase === 'end';
|
|
110
|
-
})
|
|
111
67
|
const isStateStreaming = computed(() => props.state === 'streaming')
|
|
112
68
|
|
|
69
|
+
watch(isStateStreaming, (newValue: boolean) => {
|
|
70
|
+
if (!newValue) {
|
|
71
|
+
isThoughtsExpanded.value = false;
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
|
|
113
75
|
watch(isThoughtsExpanded, (newValue: boolean) => {
|
|
114
76
|
emit('toggle-thoughts', newValue);
|
|
115
77
|
})
|
|
116
78
|
|
|
117
79
|
function handleMarkdownLinkClick(event: MouseEvent) {
|
|
118
|
-
if (
|
|
80
|
+
if (event.defaultPrevented || event.button !== 0) {
|
|
119
81
|
return;
|
|
120
82
|
}
|
|
121
83
|
if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
|
|
@@ -134,7 +96,6 @@
|
|
|
134
96
|
return;
|
|
135
97
|
}
|
|
136
98
|
event.preventDefault();
|
|
137
|
-
|
|
138
99
|
const internalRoute = resolveInternalRoute(href);
|
|
139
100
|
if (internalRoute !== null) {
|
|
140
101
|
if (agentStore.isFullScreen && !coreStore.isMobile) {
|
|
@@ -170,55 +131,6 @@
|
|
|
170
131
|
}
|
|
171
132
|
</style>
|
|
172
133
|
|
|
173
|
-
<style scoped>
|
|
174
|
-
|
|
175
|
-
.bounce-dot1 {
|
|
176
|
-
animation: bounce 1.5s infinite;
|
|
177
|
-
animation-delay: 0s;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
.bounce-dot2 {
|
|
181
|
-
animation: bounce 1.5s infinite;
|
|
182
|
-
animation-delay: 0.1s;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
.bounce-dot3 {
|
|
186
|
-
animation: bounce 1.5s infinite;
|
|
187
|
-
animation-delay: 0.2s;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
@keyframes bounce {
|
|
191
|
-
0%, 100% {
|
|
192
|
-
transform: translateY(20%);
|
|
193
|
-
opacity: 0.3;
|
|
194
|
-
animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
|
|
195
|
-
}
|
|
196
|
-
50% {
|
|
197
|
-
transform: none;
|
|
198
|
-
opacity: 1;
|
|
199
|
-
animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
.expand-enter-active,
|
|
204
|
-
.expand-leave-active {
|
|
205
|
-
transition: all 0.3s ease;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
.expand-enter-from,
|
|
209
|
-
.expand-leave-to {
|
|
210
|
-
opacity: 0;
|
|
211
|
-
max-height: 0;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
.expand-enter-to,
|
|
215
|
-
.expand-leave-from {
|
|
216
|
-
opacity: 1;
|
|
217
|
-
max-height: 144px;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
</style>
|
|
221
|
-
|
|
222
134
|
<style lang="scss">
|
|
223
135
|
.incremark a.incremark-link,
|
|
224
136
|
.incremark a.incremark-link:visited {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<span class="bounce-dot1 rounded-full w-2 h-2 bg-lightPrimary"></span>
|
|
3
|
+
<span class="bounce-dot2 rounded-full w-2 h-2 bg-lightPrimary"></span>
|
|
4
|
+
<span class="bounce-dot3 rounded-full w-2 h-2 bg-lightPrimary"></span>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<style scoped>
|
|
8
|
+
.bounce-dot1 {
|
|
9
|
+
animation: bounce 1.5s infinite;
|
|
10
|
+
animation-delay: 0s;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.bounce-dot2 {
|
|
14
|
+
animation: bounce 1.5s infinite;
|
|
15
|
+
animation-delay: 0.1s;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.bounce-dot3 {
|
|
19
|
+
animation: bounce 1.5s infinite;
|
|
20
|
+
animation-delay: 0.2s;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@keyframes bounce {
|
|
24
|
+
0%, 100% {
|
|
25
|
+
transform: translateY(20%);
|
|
26
|
+
opacity: 0.3;
|
|
27
|
+
animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
|
|
28
|
+
}
|
|
29
|
+
50% {
|
|
30
|
+
transform: none;
|
|
31
|
+
opacity: 1;
|
|
32
|
+
animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
</style>
|
|
@@ -1,19 +1,34 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
<div
|
|
3
|
+
ref="toolRendererRef"
|
|
4
|
+
class="py-1 inline-flex justify-center m-2
|
|
5
|
+
flex-col gap-3 rounded-xl px-2 text-lightListTableHeadingText
|
|
6
|
+
dark:text-darkListTableHeadingText select-none
|
|
7
|
+
"
|
|
8
|
+
:class="[
|
|
9
|
+
isInputOutputExpanded ? 'items-start border-none' : '',
|
|
10
|
+
activateShrinkedStyle ? 'border items-center' : '',
|
|
11
|
+
activateFullWidth ? 'w-full' : '',
|
|
12
|
+
]"
|
|
13
|
+
:style="{
|
|
14
|
+
maxWidth: isAnimatingShrinkFinal ? toolRendererInitialWidth + 'px' : '',
|
|
15
|
+
transition: 'max-width 0.3s ease',
|
|
16
|
+
}"
|
|
5
17
|
>
|
|
6
|
-
<div
|
|
18
|
+
<div
|
|
19
|
+
class="flex items-center gap-1 cursor-pointer"
|
|
20
|
+
@click="toggleInputOutput()"
|
|
21
|
+
>
|
|
7
22
|
<div class="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-white/70 dark:bg-blue-700/20">
|
|
8
23
|
<Spinner v-if="isRunning" class="h-4 w-4" />
|
|
9
24
|
<IconCheckOutline v-else class="h-4 w-4 text-lightPrimary dark:text-darkPrimary" />
|
|
10
25
|
</div>
|
|
11
26
|
|
|
12
27
|
<div class="min-w-0">
|
|
13
|
-
<p class="text-xs text-gray-500 dark:text-gray-400 font-bold">
|
|
28
|
+
<!-- <p class="text-xs text-gray-500 dark:text-gray-400 font-bold">
|
|
14
29
|
{{ statusLabel }}
|
|
15
30
|
<span v-if="props.data?.toolInfo?.durationMs" class="text-xs">({{ (props.data.toolInfo.durationMs / 1000).toFixed(2) }}s)</span>
|
|
16
|
-
</p>
|
|
31
|
+
</p> -->
|
|
17
32
|
<p class="break-all font-mono text-sm leading-5">
|
|
18
33
|
{{ props.data?.toolInfo?.toolName }}
|
|
19
34
|
</p>
|
|
@@ -47,12 +62,52 @@
|
|
|
47
62
|
</template>
|
|
48
63
|
|
|
49
64
|
<script setup lang="ts">
|
|
50
|
-
import { computed, ref } from 'vue';
|
|
51
|
-
import { type
|
|
65
|
+
import { computed, ref, watch, onMounted } from 'vue';
|
|
66
|
+
import { type IFormattedToolCallPart } from '../types';
|
|
52
67
|
import { Spinner } from '@/afcl';
|
|
53
68
|
import { IconAngleDownOutline, IconCheckOutline } from '@iconify-prerendered/vue-flowbite';
|
|
54
69
|
|
|
55
70
|
const isInputOutputExpanded = ref(false);
|
|
71
|
+
const activateShrinkedStyle = ref(true);
|
|
72
|
+
const isAnimatingShrinkFinal = ref(false);
|
|
73
|
+
const toolRendererInitialWidth = ref<number | null>(null);
|
|
74
|
+
const toolRendererRef = ref<HTMLElement | null>(null);
|
|
75
|
+
const activateFullWidth = ref(false);
|
|
76
|
+
const blockClicksDuringAnimation = ref(false);
|
|
77
|
+
const ANIMATION_DURATION = 300;
|
|
78
|
+
|
|
79
|
+
onMounted(() => {
|
|
80
|
+
if (toolRendererRef.value) {
|
|
81
|
+
toolRendererInitialWidth.value = toolRendererRef.value.offsetWidth;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
watch(isInputOutputExpanded, (newValue) => {
|
|
86
|
+
if (!newValue) {
|
|
87
|
+
setTimeout(() => {
|
|
88
|
+
activateFullWidth.value = false;
|
|
89
|
+
isAnimatingShrinkFinal.value = true;
|
|
90
|
+
}, ANIMATION_DURATION - 10)
|
|
91
|
+
setTimeout(() => {
|
|
92
|
+
isAnimatingShrinkFinal.value = false;
|
|
93
|
+
}, ANIMATION_DURATION);
|
|
94
|
+
setTimeout(() => {
|
|
95
|
+
activateShrinkedStyle.value = true;
|
|
96
|
+
}, ANIMATION_DURATION + 10);
|
|
97
|
+
} else {
|
|
98
|
+
activateShrinkedStyle.value = false;
|
|
99
|
+
activateFullWidth.value = true;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
function toggleInputOutput() {
|
|
104
|
+
if (blockClicksDuringAnimation.value) return;
|
|
105
|
+
isInputOutputExpanded.value = !isInputOutputExpanded.value;
|
|
106
|
+
blockClicksDuringAnimation.value = true;
|
|
107
|
+
setTimeout(() => {
|
|
108
|
+
blockClicksDuringAnimation.value = false;
|
|
109
|
+
}, ANIMATION_DURATION);
|
|
110
|
+
}
|
|
56
111
|
|
|
57
112
|
interface IToolSection {
|
|
58
113
|
label: string;
|
|
@@ -63,10 +118,7 @@
|
|
|
63
118
|
}
|
|
64
119
|
|
|
65
120
|
const props = defineProps<{
|
|
66
|
-
data:
|
|
67
|
-
type: string;
|
|
68
|
-
toolInfo: IPartData;
|
|
69
|
-
}
|
|
121
|
+
data: IFormattedToolCallPart
|
|
70
122
|
}>();
|
|
71
123
|
|
|
72
124
|
const isRunning = computed(() => props.data?.toolInfo?.phase === 'start');
|
|
@@ -115,7 +167,7 @@
|
|
|
115
167
|
|
|
116
168
|
.expand-enter-active,
|
|
117
169
|
.expand-leave-active {
|
|
118
|
-
transition: all
|
|
170
|
+
transition: all 300ms ease;
|
|
119
171
|
}
|
|
120
172
|
|
|
121
173
|
.expand-enter-from,
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
<template >
|
|
2
|
+
<template v-if="toolGroup.length > 0">
|
|
3
|
+
<span class="bg-lightNavbar absolute flex items-center justify-center w-5 h-5 bg-brand-softer rounded-full -start-[0.68rem] ring-4 ring-lightNavbar ring-default">
|
|
4
|
+
<div class="w-5 h-5 rounded-full flex items-center justify-center">
|
|
5
|
+
<IconWrenchSolid class="w-4 h-4" />
|
|
6
|
+
</div>
|
|
7
|
+
</span>
|
|
8
|
+
<h3
|
|
9
|
+
class="flex items-center mb-1 text-sm my-2 ml-3 gap-1"
|
|
10
|
+
>
|
|
11
|
+
<span class="font-semibold select-none ">Call tools</span>
|
|
12
|
+
</h3>
|
|
13
|
+
<div class="flex flex-wrap">
|
|
14
|
+
<template v-for="group in props.toolGroup" :key="group.title">
|
|
15
|
+
<ToolRenderer v-for="part in group.groupedTools" :key="part.toolInfo.toolCallId" :data="part"/>
|
|
16
|
+
</template>
|
|
17
|
+
</div>
|
|
18
|
+
</template>
|
|
19
|
+
</template>
|
|
20
|
+
|
|
21
|
+
<script setup lang="ts">
|
|
22
|
+
import ToolRenderer from './ToolRenderer.vue';
|
|
23
|
+
import type { IToolGroup } from '../types';
|
|
24
|
+
import { ref } from 'vue';
|
|
25
|
+
import { IconWrenchSolid } from '@iconify-prerendered/vue-heroicons';
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
const props = defineProps<{
|
|
29
|
+
toolGroup: IToolGroup[]
|
|
30
|
+
}>();
|
|
31
|
+
|
|
32
|
+
const expandedGroups = ref<string[]>([]);
|
|
33
|
+
|
|
34
|
+
function toggleGroup(groupTitle: string) {
|
|
35
|
+
if (expandedGroups.value.includes(groupTitle)) {
|
|
36
|
+
expandedGroups.value = expandedGroups.value.filter((title: string) => title !== groupTitle);
|
|
37
|
+
} else {
|
|
38
|
+
expandedGroups.value.push(groupTitle);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
<style scoped>
|
|
45
|
+
|
|
46
|
+
.expand-enter-active,
|
|
47
|
+
.expand-leave-active {
|
|
48
|
+
transition: all 0.3s ease;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.expand-enter-from,
|
|
52
|
+
.expand-leave-to {
|
|
53
|
+
opacity: 0;
|
|
54
|
+
max-height: 0;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.expand-enter-to,
|
|
58
|
+
.expand-leave-from {
|
|
59
|
+
opacity: 1;
|
|
60
|
+
max-height: 288px;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
</style>
|
package/custom/package.json
CHANGED
package/custom/pnpm-lock.yaml
CHANGED
|
@@ -41,6 +41,9 @@ importers:
|
|
|
41
41
|
vega-embed:
|
|
42
42
|
specifier: ^7.1.0
|
|
43
43
|
version: 7.1.0(vega-lite@6.4.2(vega@6.2.0))(vega@6.2.0)
|
|
44
|
+
vue-custom-scrollbar:
|
|
45
|
+
specifier: ^2.0.2
|
|
46
|
+
version: 2.0.2(vue@3.5.32)
|
|
44
47
|
|
|
45
48
|
packages:
|
|
46
49
|
|
|
@@ -653,6 +656,9 @@ packages:
|
|
|
653
656
|
parse-entities@4.0.2:
|
|
654
657
|
resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==}
|
|
655
658
|
|
|
659
|
+
perfect-scrollbar@1.5.6:
|
|
660
|
+
resolution: {integrity: sha512-rixgxw3SxyJbCaSpo1n35A/fwI1r2rdwMKOTCg/AcG+xOEyZcE8UHVjpZMFCVImzsFoCZeJTT+M/rdEIQYO2nw==}
|
|
661
|
+
|
|
656
662
|
picocolors@1.1.1:
|
|
657
663
|
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
|
658
664
|
|
|
@@ -873,6 +879,11 @@ packages:
|
|
|
873
879
|
vfile@6.0.3:
|
|
874
880
|
resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
|
|
875
881
|
|
|
882
|
+
vue-custom-scrollbar@2.0.2:
|
|
883
|
+
resolution: {integrity: sha512-eRyxGb7UFLLH8P0B8FDux2uPrzNBH0X6IN+A/RB5sfmLq1ym7shbCPVKua1pC7LPqPB7dc86evFXyWO/svrfKA==}
|
|
884
|
+
peerDependencies:
|
|
885
|
+
vue: ^3.3.0
|
|
886
|
+
|
|
876
887
|
vue@3.5.32:
|
|
877
888
|
resolution: {integrity: sha512-vM4z4Q9tTafVfMAK7IVzmxg34rSzTFMyIe0UUEijUCkn9+23lj0WRfA83dg7eQZIUlgOSGrkViIaCfqSAUXsMw==}
|
|
878
889
|
peerDependencies:
|
|
@@ -1755,6 +1766,8 @@ snapshots:
|
|
|
1755
1766
|
is-decimal: 2.0.1
|
|
1756
1767
|
is-hexadecimal: 2.0.1
|
|
1757
1768
|
|
|
1769
|
+
perfect-scrollbar@1.5.6: {}
|
|
1770
|
+
|
|
1758
1771
|
picocolors@1.1.1: {}
|
|
1759
1772
|
|
|
1760
1773
|
postcss@8.5.10:
|
|
@@ -2129,6 +2142,11 @@ snapshots:
|
|
|
2129
2142
|
'@types/unist': 3.0.3
|
|
2130
2143
|
vfile-message: 4.0.3
|
|
2131
2144
|
|
|
2145
|
+
vue-custom-scrollbar@2.0.2(vue@3.5.32):
|
|
2146
|
+
dependencies:
|
|
2147
|
+
perfect-scrollbar: 1.5.6
|
|
2148
|
+
vue: 3.5.32
|
|
2149
|
+
|
|
2132
2150
|
vue@3.5.32:
|
|
2133
2151
|
dependencies:
|
|
2134
2152
|
'@vue/compiler-dom': 3.5.32
|
|
@@ -12,10 +12,10 @@ Use `get_resource_data` to fetch data for this skill. This is the main tool for
|
|
|
12
12
|
|
|
13
13
|
When the user asks for analytics, reports, trends, comparisons, or distributions:
|
|
14
14
|
|
|
15
|
-
- Fetch the
|
|
16
|
-
-
|
|
15
|
+
- Fetch the requested data using `aggregate` tool. This tool is capable of performing fast server-side aggregations on filtered data, groupings by date including grouping by day/week/month etc.
|
|
16
|
+
- if it is not possible to get the required aggregates using `aggregate`, fetch the underlying rows with `get_resource_data`. This is much heavier since returns original rows with all fields, but allows you to perform complex calculations, comparisons, and custom groupings in-memory. Always prefer `aggregate` when possible.
|
|
17
|
+
- Prefer narrow requests: use filters, sorting, pagination, and date ranges whenever possible.
|
|
17
18
|
- If the request is ambiguous, clarify the resource, metric, grouping, or date range before fetching data.
|
|
18
|
-
- Compute aggregates from the returned rows yourself: sums, counts, averages, min/max, grouped totals, ratios, and trend deltas.
|
|
19
19
|
- Return a short written summary with the key finding and most important numbers.
|
|
20
20
|
- If a chart would help, produce a Vega-Lite spec.
|
|
21
21
|
|
package/custom/types.ts
CHANGED
|
@@ -7,12 +7,22 @@ export interface IPartData {
|
|
|
7
7
|
durationMs?: number;
|
|
8
8
|
}
|
|
9
9
|
export interface IPart {
|
|
10
|
-
type:
|
|
10
|
+
type: 'reasoning' | 'data-tool-call' | 'text';
|
|
11
11
|
text?: string;
|
|
12
12
|
state?: 'started' | 'thinking' | 'processing' | 'streaming' | 'done';
|
|
13
13
|
data?: IPartData;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
export interface IFormattedToolCallPart {
|
|
17
|
+
type: 'data-tool-call';
|
|
18
|
+
toolInfo: IPartData;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface IToolGroup {
|
|
22
|
+
title: string;
|
|
23
|
+
groupedTools: IFormattedToolCallPart[];
|
|
24
|
+
}
|
|
25
|
+
|
|
16
26
|
export interface IMessage {
|
|
17
27
|
id: string;
|
|
18
28
|
role: 'user' | 'assistant';
|
package/custom/utils.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { IMessage, IPart } from "./types";
|
|
2
|
+
|
|
1
3
|
export function remToPx(rem: number): number {
|
|
2
4
|
const rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize);
|
|
3
5
|
return rem * rootFontSize;
|
|
@@ -7,3 +9,30 @@ export function pxToRem(px: number): number {
|
|
|
7
9
|
const rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize);
|
|
8
10
|
return px / rootFontSize;
|
|
9
11
|
}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
export function getMessageParts(message: IMessage): IPart[] {
|
|
15
|
+
return message.parts?.length
|
|
16
|
+
? message.parts
|
|
17
|
+
: [{ text: '', type: 'reasoning', state: 'streaming' }];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function addNewLineBeforeTitles(text: string): string {
|
|
21
|
+
return text.replace(/(\*\*[^*]+\*\*)/g, '\n\n$1');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function extractTitleAndTextFromReasoning(reasoningText: string): { title: string | null; body: string } {
|
|
25
|
+
const match = reasoningText.match(/^\*\*(.*?)\*\*(.*)$/s);
|
|
26
|
+
|
|
27
|
+
if (!match) {
|
|
28
|
+
return {
|
|
29
|
+
title: null,
|
|
30
|
+
body: addNewLineBeforeTitles(reasoningText)
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
title: match[1].trim(),
|
|
36
|
+
body: addNewLineBeforeTitles(match[2].trim())
|
|
37
|
+
};
|
|
38
|
+
}
|
package/dist/apiBasedTools.js
CHANGED
|
@@ -25,6 +25,9 @@ const TOOL_OVERRIDES = {
|
|
|
25
25
|
'resource.options.actions[].customComponent',
|
|
26
26
|
'resource.options.pageInjections',
|
|
27
27
|
],
|
|
28
|
+
format_tool: (_a) => __awaiter(void 0, [_a], void 0, function* ({}) {
|
|
29
|
+
return "get resource Apartments";
|
|
30
|
+
})
|
|
28
31
|
},
|
|
29
32
|
get_resource_data: {
|
|
30
33
|
post_process_response: (_a) => __awaiter(void 0, [_a], void 0, function* ({ output, inputs, invokeTool, userTimeZone }) {
|
|
@@ -44,6 +47,9 @@ const TOOL_OVERRIDES = {
|
|
|
44
47
|
formatDateTimeColumns(response.data, dateTimeColumnNames, localizedTimeZone);
|
|
45
48
|
return response;
|
|
46
49
|
}),
|
|
50
|
+
format_tool: (_a) => __awaiter(void 0, [_a], void 0, function* ({}) {
|
|
51
|
+
return "get 1-20 Apartment filtered listed=yes";
|
|
52
|
+
})
|
|
47
53
|
},
|
|
48
54
|
};
|
|
49
55
|
function sanitizeForYaml(value) {
|
|
@@ -179,7 +179,7 @@ import { IconChatBubbleLeft20Solid, IconSparklesSolid, IconArrowsPointingOut, Ic
|
|
|
179
179
|
import { IconCloseOutline, IconBarsOutline, IconArrowUpOutline, IconCloseSidebarSolid, IconOpenSidebarSolid, IconAngleDownOutline } from '@iconify-prerendered/vue-flowbite';
|
|
180
180
|
import { useTemplateRef, onMounted, ref,computed } from 'vue';
|
|
181
181
|
import { onClickOutside } from '@vueuse/core'
|
|
182
|
-
import ConversationArea from './ConversationArea.vue';
|
|
182
|
+
import ConversationArea from './conversation_area/ConversationArea.vue';
|
|
183
183
|
import { useAgentStore } from './composables/useAgentStore';
|
|
184
184
|
import { useAgentTransitions } from './composables/useAgentTransitions';
|
|
185
185
|
import { Button } from '@/afcl';
|
|
@@ -246,7 +246,7 @@ onMounted(async () => {
|
|
|
246
246
|
agentStore.setAvailableModes(props.meta.modes, props.meta.defaultModeName);
|
|
247
247
|
agentStore.regisrerTextInput(textInput.value);
|
|
248
248
|
textInput.value?.focus();
|
|
249
|
-
const isTeleportedToBodyFromLocalStorage = agentStore.getLocalStorageItem('isTeleportedToBody') === 'true';
|
|
249
|
+
const isTeleportedToBodyFromLocalStorage = agentStore.getLocalStorageItem('isTeleportedToBody') === 'true' || agentStore.getLocalStorageItem('isTeleportedToBodyBeforeFullScreen') === 'true';
|
|
250
250
|
if( coreStore.isMobile ) {
|
|
251
251
|
agentStore.setIsTeleportedToBody(false);
|
|
252
252
|
} else {
|