@adminforth/agent 2.0.9 → 2.1.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 +333 -10
- package/dist/application/ports.d.ts +66 -0
- package/dist/application/runTurnUseCase.d.ts +68 -0
- package/dist/application/runTurnUseCase.js +358 -0
- package/dist/{agentEvents.d.ts → domain/agentEvents.d.ts} +1 -1
- package/dist/{agent → domain}/systemPrompt.js +1 -1
- package/dist/{agent/turn → domain}/turnTypes.d.ts +41 -37
- package/dist/{agent/turn/VegaLiteStreamBuffer.d.ts → domain/vegaLiteStreamBuffer.d.ts} +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +40 -35
- package/dist/{agent/runtime/AgentContext.d.ts → llm/agentContext.d.ts} +3 -3
- package/dist/{agent/simpleAgent.d.ts → llm/agentModels.d.ts} +18 -16
- package/dist/llm/agentModels.js +65 -0
- package/dist/{agent/runtime/AgentRuntime.d.ts → llm/agentRuntime.d.ts} +11 -2
- package/dist/{agent/runtime/AgentRuntime.js → llm/agentRuntime.js} +38 -6
- package/dist/llm/langGraphLlm.d.ts +25 -0
- package/dist/llm/langGraphLlm.js +54 -0
- package/dist/{agent/middleware/apiBasedTools.d.ts → llm/middleware/apiToolsMiddleware.d.ts} +1 -1
- package/dist/{agent/middleware/apiBasedTools.js → llm/middleware/apiToolsMiddleware.js} +8 -14
- package/dist/{agent → llm}/middleware/sequenceDebug.d.ts +1 -1
- package/dist/{agent/models/AgentModelFactory.d.ts → llm/modelFactory.d.ts} +1 -1
- package/dist/{agent/models/AgentModelFactory.js → llm/modelFactory.js} +1 -1
- package/dist/llm/streamAdapter.d.ts +18 -0
- package/dist/llm/streamAdapter.js +117 -0
- package/dist/{sessionStore.d.ts → persistence/sessionStore.d.ts} +12 -2
- package/dist/{sessionStore.js → persistence/sessionStore.js} +33 -0
- package/dist/{agent/tools/AgentToolProvider.d.ts → tools/agentToolProvider.d.ts} +1 -1
- package/dist/{agent/tools/AgentToolProvider.js → tools/agentToolProvider.js} +1 -1
- package/dist/{apiBasedTools.js → tools/apiBasedTools.js} +10 -6
- package/dist/{agent/tools → tools}/apiTool.d.ts +1 -1
- package/dist/{agent/tools → tools}/fetchSkill.js +1 -1
- package/dist/{agent/tools → tools}/fetchToolSchema.d.ts +1 -1
- package/dist/{agent/tools → tools}/index.d.ts +1 -1
- package/dist/{agent/tools → tools}/navigateUser.d.ts +3 -3
- package/dist/{endpoints → transport/http}/context.d.ts +2 -2
- package/dist/transport/http/context.js +1 -0
- package/dist/{endpoints/core.js → transport/http/coreEndpoints.js} +3 -3
- package/dist/{endpoints/sessions.js → transport/http/sessionEndpoints.js} +7 -1
- package/dist/transport/sse/sseWriter.d.ts +29 -0
- package/dist/{surfaces/web-sse/createSseEventEmitter.js → transport/sse/sseWriter.js} +15 -0
- package/dist/{chatSurfaceService.d.ts → transport/surfaces/chatSurfaceService.d.ts} +3 -3
- package/dist/{chatSurfaceService.js → transport/surfaces/chatSurfaceService.js} +7 -5
- package/dist/{agent/speech/SpeechTurnService.d.ts → transport/surfaces/speechTurnService.d.ts} +1 -1
- package/dist/{agent/speech/SpeechTurnService.js → transport/surfaces/speechTurnService.js} +2 -2
- package/dist/types.d.ts +10 -4
- package/package.json +11 -2
- package/.woodpecker/buildRelease.sh +0 -13
- package/.woodpecker/buildSlackNotify.sh +0 -46
- package/.woodpecker/release.yml +0 -57
- package/agent/checkpointer.ts +0 -329
- package/agent/languageDetect.ts +0 -92
- package/agent/middleware/apiBasedTools.ts +0 -174
- package/agent/middleware/openAiResponsesContinuation.ts +0 -92
- package/agent/middleware/sequenceDebug.ts +0 -429
- package/agent/models/AgentModeResolver.ts +0 -9
- package/agent/models/AgentModelFactory.ts +0 -28
- package/agent/runtime/AgentContext.ts +0 -30
- package/agent/runtime/AgentRuntime.ts +0 -89
- package/agent/simpleAgent.ts +0 -199
- package/agent/skills/registry.ts +0 -162
- package/agent/speech/SpeechTurnService.ts +0 -179
- package/agent/systemPrompt.ts +0 -133
- package/agent/toolCallEvents.ts +0 -135
- package/agent/tools/AgentToolProvider.ts +0 -28
- package/agent/tools/apiTool.ts +0 -66
- package/agent/tools/fetchSkill.ts +0 -68
- package/agent/tools/fetchToolSchema.ts +0 -47
- package/agent/tools/getUserLocation.ts +0 -45
- package/agent/tools/index.ts +0 -31
- package/agent/tools/navigateUser.ts +0 -210
- package/agent/turn/TurnContextBuilder.ts +0 -36
- package/agent/turn/TurnLifecycleService.ts +0 -47
- package/agent/turn/TurnPersistenceService.ts +0 -33
- package/agent/turn/TurnPromptBuilder.ts +0 -51
- package/agent/turn/TurnStreamConsumer.ts +0 -69
- package/agent/turn/VegaLiteStreamBuffer.ts +0 -90
- package/agent/turn/turnTypes.ts +0 -100
- package/agentEvents.ts +0 -75
- package/agentTurnService.ts +0 -314
- package/apiBasedTools.ts +0 -702
- package/build.log +0 -67
- package/chatSurfaceService.ts +0 -319
- package/custom/ChatFooter.vue +0 -173
- package/custom/ChatHeader.vue +0 -78
- package/custom/ChatSurface.vue +0 -160
- package/custom/CustomAutoScrollContainer.vue +0 -164
- package/custom/SessionsHistory.vue +0 -88
- package/custom/chat.ts +0 -82
- package/custom/composables/agentAudio/utils.ts +0 -220
- package/custom/composables/agentStore/constants.ts +0 -19
- package/custom/composables/agentStore/pageContext.ts +0 -8
- package/custom/composables/agentStore/useAgentChat.ts +0 -241
- package/custom/composables/agentStore/useAgentPlaceholder.ts +0 -142
- package/custom/composables/agentStore/useAgentSessions.ts +0 -350
- package/custom/composables/useAgentAudio.ts +0 -272
- package/custom/composables/useAgentStore.ts +0 -510
- package/custom/composables/useAgentTransitions.ts +0 -58
- package/custom/conversation_area/ConversationArea.vue +0 -301
- package/custom/conversation_area/MessageRenderer.vue +0 -49
- package/custom/conversation_area/ProcessingTimeline.vue +0 -286
- package/custom/conversation_area/ReasoningRenderer.vue +0 -79
- package/custom/conversation_area/SystemMessageRenderer.vue +0 -28
- package/custom/conversation_area/TextRenderer.vue +0 -182
- package/custom/conversation_area/ThreeDotsAnimation.vue +0 -35
- package/custom/conversation_area/ToolApprovalRenderer.vue +0 -98
- package/custom/conversation_area/ToolRenderer.vue +0 -178
- package/custom/conversation_area/ToolsGroup.vue +0 -59
- package/custom/env.d.ts +0 -7
- package/custom/incremark_code_renderers/IncremarkShikiCodeBlock.vue +0 -393
- package/custom/incremark_code_renderers/incremarkCodeHighlight.ts +0 -285
- package/custom/incremark_code_renderers/incremarkRenderer.ts +0 -653
- package/custom/incremark_code_renderers/renderIncremarkMarkdown.ts +0 -118
- package/custom/package.json +0 -30
- package/custom/pnpm-lock.yaml +0 -2394
- package/custom/public/agentAudio/agent-processing.mp3 +0 -0
- package/custom/skills/analyze_data/SKILL.md +0 -25
- package/custom/skills/charts/SKILL.md +0 -193
- package/custom/skills/fetch_data/SKILL.md +0 -31
- package/custom/skills/mutate_data/SKILL.md +0 -121
- package/custom/speech_recognition_frontend/AudioLines.vue +0 -43
- package/custom/speech_recognition_frontend/MicrophoneButon.vue +0 -185
- package/custom/speech_recognition_frontend/types/voice-activity-detection.d.ts +0 -22
- package/custom/speech_recognition_frontend/voiceActivityDetection.ts +0 -62
- package/custom/tsconfig.json +0 -15
- package/custom/types.ts +0 -108
- package/custom/utils.ts +0 -38
- package/dist/agent/middleware/openAiResponsesContinuation.d.ts +0 -1
- package/dist/agent/middleware/openAiResponsesContinuation.js +0 -66
- package/dist/agent/models/AgentModeResolver.d.ts +0 -9
- package/dist/agent/models/AgentModeResolver.js +0 -9
- package/dist/agent/simpleAgent.js +0 -118
- package/dist/agent/turn/TurnContextBuilder.d.ts +0 -14
- package/dist/agent/turn/TurnContextBuilder.js +0 -31
- package/dist/agent/turn/TurnLifecycleService.d.ts +0 -24
- package/dist/agent/turn/TurnLifecycleService.js +0 -47
- package/dist/agent/turn/TurnPersistenceService.d.ts +0 -13
- package/dist/agent/turn/TurnPersistenceService.js +0 -35
- package/dist/agent/turn/TurnPromptBuilder.d.ts +0 -19
- package/dist/agent/turn/TurnPromptBuilder.js +0 -43
- package/dist/agent/turn/TurnStreamConsumer.d.ts +0 -11
- package/dist/agent/turn/TurnStreamConsumer.js +0 -84
- package/dist/agentTurnService.d.ts +0 -24
- package/dist/agentTurnService.js +0 -269
- package/dist/surfaces/web-sse/createSseEventEmitter.d.ts +0 -14
- package/endpoints/chatSurfaces.ts +0 -66
- package/endpoints/context.ts +0 -52
- package/endpoints/core.ts +0 -181
- package/endpoints/sessions.ts +0 -183
- package/errors.ts +0 -10
- package/index.ts +0 -192
- package/pnpm-workspace.yaml +0 -4
- package/sanitizeSpeechText.ts +0 -32
- package/sessionStore.ts +0 -105
- package/surfaces/web-sse/createSseEventEmitter.ts +0 -311
- package/tsconfig.json +0 -14
- package/types.ts +0 -127
- /package/dist/{agent/turn/turnTypes.js → application/ports.js} +0 -0
- /package/dist/{agentEvents.js → domain/agentEvents.js} +0 -0
- /package/dist/{agent → domain}/languageDetect.d.ts +0 -0
- /package/dist/{agent → domain}/languageDetect.js +0 -0
- /package/dist/{agent → domain}/systemPrompt.d.ts +0 -0
- /package/dist/{agent → domain}/toolCallEvents.d.ts +0 -0
- /package/dist/{agent → domain}/toolCallEvents.js +0 -0
- /package/dist/{endpoints/context.js → domain/turnTypes.js} +0 -0
- /package/dist/{agent/turn/VegaLiteStreamBuffer.js → domain/vegaLiteStreamBuffer.js} +0 -0
- /package/dist/{agent/runtime/AgentContext.js → llm/agentContext.js} +0 -0
- /package/dist/{agent → llm}/middleware/sequenceDebug.js +0 -0
- /package/dist/{agent/checkpointer.d.ts → persistence/checkpointStore.d.ts} +0 -0
- /package/dist/{agent/checkpointer.js → persistence/checkpointStore.js} +0 -0
- /package/dist/{errors.d.ts → shared/errors.d.ts} +0 -0
- /package/dist/{errors.js → shared/errors.js} +0 -0
- /package/dist/{sanitizeSpeechText.d.ts → shared/sanitizeSpeechText.d.ts} +0 -0
- /package/dist/{sanitizeSpeechText.js → shared/sanitizeSpeechText.js} +0 -0
- /package/dist/{apiBasedTools.d.ts → tools/apiBasedTools.d.ts} +0 -0
- /package/dist/{agent/tools → tools}/apiTool.js +0 -0
- /package/dist/{agent/tools → tools}/fetchSkill.d.ts +0 -0
- /package/dist/{agent/tools → tools}/fetchToolSchema.js +0 -0
- /package/dist/{agent/tools → tools}/getUserLocation.d.ts +0 -0
- /package/dist/{agent/tools → tools}/getUserLocation.js +0 -0
- /package/dist/{agent/tools → tools}/index.js +0 -0
- /package/dist/{agent/tools → tools}/navigateUser.js +0 -0
- /package/dist/{agent → tools}/skills/registry.d.ts +0 -0
- /package/dist/{agent → tools}/skills/registry.js +0 -0
- /package/dist/{endpoints/chatSurfaces.d.ts → transport/http/chatSurfaceEndpoints.d.ts} +0 -0
- /package/dist/{endpoints/chatSurfaces.js → transport/http/chatSurfaceEndpoints.js} +0 -0
- /package/dist/{endpoints/core.d.ts → transport/http/coreEndpoints.d.ts} +0 -0
- /package/dist/{endpoints/sessions.d.ts → transport/http/sessionEndpoints.d.ts} +0 -0
package/custom/ChatSurface.vue
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div
|
|
3
|
-
class="relative w-6 h-6 cursor-pointer mr-1 mt-1
|
|
4
|
-
text-lightNavbarIcons hover:text-lightNavbarIcons/80
|
|
5
|
-
dark:text-darkNavbarIcons hover:text-darkNavbarIcons/80
|
|
6
|
-
hover:scale-110 transition-colors duration-200"
|
|
7
|
-
@click="agentStore.setIsChatOpen(!agentStore.isChatOpen)"
|
|
8
|
-
>
|
|
9
|
-
<IconChatBubbleLeft20Solid
|
|
10
|
-
class="w-6 h-6"
|
|
11
|
-
/>
|
|
12
|
-
<div class="absolute w-4 h-4 bg-lightNavbar dark:bg-darkNavbar rounded-full -top-1 -right-2">
|
|
13
|
-
<IconSparklesSolid
|
|
14
|
-
class="w-4 h-4"
|
|
15
|
-
/>
|
|
16
|
-
</div>
|
|
17
|
-
</div>
|
|
18
|
-
|
|
19
|
-
<Teleport to="body">
|
|
20
|
-
<div
|
|
21
|
-
ref="chatSurface"
|
|
22
|
-
id="adminforth-agent-chat-surface"
|
|
23
|
-
class="fixed bg-lightNavbar dark:bg-darkNavbar top-0 right-0 border-x border-b border-gray-200 dark:border-gray-700
|
|
24
|
-
flex flex z-40 h-screen"
|
|
25
|
-
:class="[agentStore.isChatOpen ? 'translate-x-0' : 'translate-x-full', !agentStore.isTeleportedToBody ? 'shadow-2xl' : '']"
|
|
26
|
-
:style="{ width: agentStore.chatWidth + 'rem' }"
|
|
27
|
-
>
|
|
28
|
-
<div
|
|
29
|
-
v-if="!(coreStore.isMobile || agentStore.isFullScreen)"
|
|
30
|
-
class="w-2 cursor-ew-resize absolute left-0 h-full top-0 z-30"
|
|
31
|
-
@mousedown="startResize"
|
|
32
|
-
></div>
|
|
33
|
-
<div
|
|
34
|
-
class="w-full min-h-0 max-h-full flex flex-col h-dvh"
|
|
35
|
-
:style="{
|
|
36
|
-
height: !coreStore.isIos ? dvh + 'px' : '100dvh',
|
|
37
|
-
}"
|
|
38
|
-
>
|
|
39
|
-
<ChatHeader />
|
|
40
|
-
<div
|
|
41
|
-
class="relative flex-1 min-h-0 flex flex-col overflow-hidden"
|
|
42
|
-
>
|
|
43
|
-
<ConversationArea
|
|
44
|
-
ref="conversationArea"
|
|
45
|
-
v-if="agentStore.isChatOpen"
|
|
46
|
-
:messages="agentStore.chatMessages"
|
|
47
|
-
/>
|
|
48
|
-
<ChatFooter
|
|
49
|
-
:meta="props.meta"
|
|
50
|
-
:adminUser="props.adminUser"
|
|
51
|
-
:conversationAreaRef="conversationArea"
|
|
52
|
-
/>
|
|
53
|
-
</div>
|
|
54
|
-
</div>
|
|
55
|
-
</div>
|
|
56
|
-
</Teleport>
|
|
57
|
-
|
|
58
|
-
</template>
|
|
59
|
-
|
|
60
|
-
<script setup lang="ts">
|
|
61
|
-
import { IconChatBubbleLeft20Solid, IconSparklesSolid } from '@iconify-prerendered/vue-heroicons';
|
|
62
|
-
import { useTemplateRef, onMounted, ref, onUnmounted } from 'vue';
|
|
63
|
-
import { onClickOutside } from '@vueuse/core'
|
|
64
|
-
import ConversationArea from './conversation_area/ConversationArea.vue';
|
|
65
|
-
import ChatHeader from './ChatHeader.vue';
|
|
66
|
-
import ChatFooter from './ChatFooter.vue';
|
|
67
|
-
import { useAgentStore } from './composables/useAgentStore';
|
|
68
|
-
import { useAgentTransitions } from './composables/useAgentTransitions';
|
|
69
|
-
import { useCoreStore } from '@/stores/core';
|
|
70
|
-
import { remToPx } from './utils';
|
|
71
|
-
|
|
72
|
-
const props = defineProps<{
|
|
73
|
-
meta: {
|
|
74
|
-
pluginInstanceId: string;
|
|
75
|
-
modes: Array<{
|
|
76
|
-
name: string;
|
|
77
|
-
}>;
|
|
78
|
-
defaultModeName: string | null;
|
|
79
|
-
stickByDefault: boolean;
|
|
80
|
-
hasAudioAdapter: boolean;
|
|
81
|
-
}
|
|
82
|
-
adminUser: any
|
|
83
|
-
}>();
|
|
84
|
-
|
|
85
|
-
const chatSurface = useTemplateRef('chatSurface');
|
|
86
|
-
const conversationArea = useTemplateRef('conversationArea');
|
|
87
|
-
const agentStore = useAgentStore();
|
|
88
|
-
const agentTransitions = useAgentTransitions();
|
|
89
|
-
const coreStore = useCoreStore();
|
|
90
|
-
|
|
91
|
-
const dvh = ref(window.visualViewport?.height || window.innerHeight);
|
|
92
|
-
|
|
93
|
-
let startX = 0
|
|
94
|
-
let startWidth = 0
|
|
95
|
-
|
|
96
|
-
onClickOutside(chatSurface as any, () => {if (!agentStore.isTeleportedToBody && !agentStore.isFullScreen) agentStore.setIsChatOpen(false);});
|
|
97
|
-
|
|
98
|
-
onMounted(async () => {
|
|
99
|
-
window.addEventListener('resize', updateHeight)
|
|
100
|
-
const savedIsTeleportedToBody = agentStore.getLocalStorageItem('isTeleportedToBody');
|
|
101
|
-
const savedIsTeleportedToBodyBeforeFullScreen = agentStore.getLocalStorageItem('isTeleportedToBodyBeforeFullScreen');
|
|
102
|
-
let isTeleportedToBodyFromLocalStorage = true;
|
|
103
|
-
if (savedIsTeleportedToBody !== null || savedIsTeleportedToBodyBeforeFullScreen !== null) {
|
|
104
|
-
isTeleportedToBodyFromLocalStorage = savedIsTeleportedToBody === 'true' || savedIsTeleportedToBodyBeforeFullScreen === 'true';
|
|
105
|
-
}
|
|
106
|
-
if( coreStore.isMobile ) {
|
|
107
|
-
agentStore.setIsTeleportedToBody(false);
|
|
108
|
-
} else {
|
|
109
|
-
const shouldTeleportToBody = isTeleportedToBodyFromLocalStorage || props.meta.stickByDefault;
|
|
110
|
-
const savedIsChatOpen = agentStore.getLocalStorageItem('isChatOpen');
|
|
111
|
-
|
|
112
|
-
agentStore.setIsTeleportedToBody(shouldTeleportToBody);
|
|
113
|
-
if (shouldTeleportToBody && savedIsChatOpen === null) {
|
|
114
|
-
agentStore.setIsChatOpen(true);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
await agentStore.fetchSessionsList();
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
onUnmounted(() => {
|
|
121
|
-
window.removeEventListener('resize', updateHeight)
|
|
122
|
-
})
|
|
123
|
-
|
|
124
|
-
const startResize = (e: MouseEvent) => {
|
|
125
|
-
startX = e.clientX
|
|
126
|
-
startWidth = remToPx(agentStore.chatWidth)
|
|
127
|
-
|
|
128
|
-
document.body.style.userSelect = 'none'
|
|
129
|
-
document.body.style.cursor = 'ew-resize'
|
|
130
|
-
|
|
131
|
-
document.addEventListener('mousemove', onResize)
|
|
132
|
-
document.addEventListener('mouseup', stopResize)
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const onResize = (e: MouseEvent) => {
|
|
136
|
-
const dx = startX - e.clientX
|
|
137
|
-
agentStore.setChatWidth(Math.min(Math.max(startWidth + dx, remToPx(agentStore.MIN_WIDTH)), remToPx(agentStore.MAX_WIDTH)))
|
|
138
|
-
agentTransitions.setChatSurfaceTransition(true);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
const stopResize = () => {
|
|
142
|
-
document.body.style.userSelect = ''
|
|
143
|
-
document.body.style.cursor = ''
|
|
144
|
-
|
|
145
|
-
document.removeEventListener('mousemove', onResize)
|
|
146
|
-
document.removeEventListener('mouseup', stopResize)
|
|
147
|
-
|
|
148
|
-
const appRoot = document.getElementById('app');
|
|
149
|
-
const header = document.getElementById('af-header-nav');
|
|
150
|
-
if (appRoot && header) {
|
|
151
|
-
agentTransitions.setAppRootTransition(false);
|
|
152
|
-
agentTransitions.setChatSurfaceTransition(false);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
function updateHeight() {
|
|
157
|
-
dvh.value = Math.round(window.visualViewport?.height || window.innerHeight);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
</script>
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<CustomScrollbar
|
|
3
|
-
ref="containerRef"
|
|
4
|
-
class="auto-scroll-container mask-y"
|
|
5
|
-
:wrapperStyle = "wrapperStyle"
|
|
6
|
-
:contentStyle = "contentStyle"
|
|
7
|
-
:autoHide = "scrollBarAutoHide"
|
|
8
|
-
@scroll="handleScroll"
|
|
9
|
-
>
|
|
10
|
-
<slot />
|
|
11
|
-
</CustomScrollbar>
|
|
12
|
-
</template>
|
|
13
|
-
|
|
14
|
-
<script setup lang="ts">
|
|
15
|
-
import { ref, onMounted, onUnmounted, nextTick, computed } from 'vue'
|
|
16
|
-
import CustomScrollbar from 'custom-vue-scrollbar';
|
|
17
|
-
import 'custom-vue-scrollbar/dist/style.css';
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const props = withDefaults(defineProps<{
|
|
21
|
-
enabled?: boolean
|
|
22
|
-
threshold?: number
|
|
23
|
-
behavior?: ScrollBehavior
|
|
24
|
-
wrapperStyle?: Record<string, string>
|
|
25
|
-
contentStyle?: Record<string, string>
|
|
26
|
-
scrollBarAutoHide?: boolean
|
|
27
|
-
}>(), {
|
|
28
|
-
enabled: true,
|
|
29
|
-
threshold: 50,
|
|
30
|
-
behavior: 'instant',
|
|
31
|
-
scrollBarAutoHide: true
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
const containerRef = ref<HTMLDivElement | null>(null)
|
|
35
|
-
const isUserScrolledUp = ref(false)
|
|
36
|
-
const scrollElement = ref<HTMLElement | null>(null)
|
|
37
|
-
|
|
38
|
-
let lastScrollTop = 0
|
|
39
|
-
let lastScrollHeight = 0
|
|
40
|
-
let observer: MutationObserver | null = null
|
|
41
|
-
|
|
42
|
-
const scrollParams = ref({
|
|
43
|
-
scrollTop: 0,
|
|
44
|
-
scrollHeight: 0,
|
|
45
|
-
clientHeight: 0
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
defineExpose({
|
|
49
|
-
scrollToBottom: () => scrollToBottom(true),
|
|
50
|
-
isUserScrolledUp: () => isUserScrolledUp.value,
|
|
51
|
-
container: containerRef,
|
|
52
|
-
handleScroll,
|
|
53
|
-
scrollParams
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
onMounted(() => {
|
|
57
|
-
if (!containerRef.value) return
|
|
58
|
-
|
|
59
|
-
scrollElement.value = containerRef.value.scrollEl
|
|
60
|
-
lastScrollTop = containerRef.value.scrollEl.scrollTop
|
|
61
|
-
lastScrollHeight = containerRef.value.scrollEl.scrollHeight
|
|
62
|
-
|
|
63
|
-
observer = new MutationObserver(() => {
|
|
64
|
-
nextTick(() => {
|
|
65
|
-
if (!containerRef.value?.scrollEl) return
|
|
66
|
-
|
|
67
|
-
if (!hasScrollbar()) {
|
|
68
|
-
isUserScrolledUp.value = false
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
lastScrollHeight = containerRef.value.scrollEl.scrollHeight
|
|
72
|
-
scrollParams.value.scrollTop = containerRef.value.scrollEl.scrollTop
|
|
73
|
-
scrollParams.value.scrollHeight = containerRef.value.scrollEl.scrollHeight
|
|
74
|
-
scrollParams.value.clientHeight = containerRef.value.scrollEl.clientHeight
|
|
75
|
-
if (props.enabled && !isUserScrolledUp.value) {
|
|
76
|
-
scrollToBottom()
|
|
77
|
-
}
|
|
78
|
-
})
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
observer.observe(containerRef.value?.scrollEl, {
|
|
82
|
-
childList: true,
|
|
83
|
-
subtree: true,
|
|
84
|
-
characterData: true
|
|
85
|
-
})
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
onUnmounted(() => {
|
|
89
|
-
observer?.disconnect()
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
function isNearBottom(customThreshold?: number): boolean {
|
|
93
|
-
const container = containerRef.value?.scrollEl
|
|
94
|
-
if (!container) return true
|
|
95
|
-
|
|
96
|
-
const { scrollTop, scrollHeight, clientHeight } = container
|
|
97
|
-
scrollParams.value.scrollTop = scrollTop
|
|
98
|
-
scrollParams.value.scrollHeight = scrollHeight
|
|
99
|
-
scrollParams.value.clientHeight = clientHeight
|
|
100
|
-
const threshold = customThreshold ?? props.threshold
|
|
101
|
-
return scrollHeight - scrollTop - clientHeight <= threshold
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function scrollToBottom(force = false): void {
|
|
105
|
-
const container = containerRef.value?.scrollEl
|
|
106
|
-
if (!container) return
|
|
107
|
-
|
|
108
|
-
if (isUserScrolledUp.value && !force) return
|
|
109
|
-
container.scrollTo({
|
|
110
|
-
top: container.scrollHeight,
|
|
111
|
-
behavior: props.behavior
|
|
112
|
-
})
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
function hasScrollbar(): boolean {
|
|
117
|
-
const container = containerRef.value?.scrollEl
|
|
118
|
-
if (!container) return false
|
|
119
|
-
return container.scrollHeight > container.clientHeight
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
function handleScroll(detectScrollDown = true, customThreshold?: number): void {
|
|
124
|
-
const container = containerRef.value.scrollEl
|
|
125
|
-
if (!container) return
|
|
126
|
-
|
|
127
|
-
const { scrollTop, scrollHeight, clientHeight } = container
|
|
128
|
-
if (scrollHeight <= clientHeight) {
|
|
129
|
-
isUserScrolledUp.value = false
|
|
130
|
-
lastScrollTop = 0
|
|
131
|
-
lastScrollHeight = scrollHeight
|
|
132
|
-
return
|
|
133
|
-
}
|
|
134
|
-
if (isNearBottom(customThreshold)) {
|
|
135
|
-
isUserScrolledUp.value = false
|
|
136
|
-
} else {
|
|
137
|
-
const isScrollingUp = scrollTop < lastScrollTop
|
|
138
|
-
const isScrollingDown = detectScrollDown ? scrollTop > lastScrollTop : false
|
|
139
|
-
const isContentUnchanged = scrollHeight === lastScrollHeight
|
|
140
|
-
if ((isScrollingUp || isScrollingDown) && isContentUnchanged) {
|
|
141
|
-
isUserScrolledUp.value = true
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
lastScrollTop = scrollTop
|
|
145
|
-
lastScrollHeight = scrollHeight
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
</script>
|
|
149
|
-
|
|
150
|
-
<style>
|
|
151
|
-
.mask-y {
|
|
152
|
-
mask-image: linear-gradient(
|
|
153
|
-
to bottom,
|
|
154
|
-
transparent,
|
|
155
|
-
black 1.25rem,
|
|
156
|
-
black calc(100% - 1.25rem),
|
|
157
|
-
transparent
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
.scrollbar__thumb {
|
|
162
|
-
border-radius: 0.25rem;
|
|
163
|
-
}
|
|
164
|
-
</style>
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="absolute top-0 left-0 transition-transform
|
|
3
|
-
duration-200 ease-in-out border-y border-r dark:border-gray-600 z-20
|
|
4
|
-
bg-lightNavbar dark:bg-darkNavbar w-96 h-full flex flex-col items-center
|
|
5
|
-
overflow-y-auto overflow-x-hidden
|
|
6
|
-
"
|
|
7
|
-
>
|
|
8
|
-
<h3 :class="h3Style">{{ $t('Chat history') }}</h3>
|
|
9
|
-
<div class="w-full flex items-center justify-center">
|
|
10
|
-
</div>
|
|
11
|
-
<div class="w-full border-b border-gray-200 dark:border-gray-700"/>
|
|
12
|
-
<div v-for="group in groupedSessions" :key="group.dayKey" class="w-full py-2">
|
|
13
|
-
<div class="px-4 pb-2 text-xs font-semibold uppercase tracking-[0.2em] text-gray-500 dark:text-gray-400">
|
|
14
|
-
{{ group.label }}
|
|
15
|
-
</div>
|
|
16
|
-
|
|
17
|
-
<button
|
|
18
|
-
v-for="session in group.sessions"
|
|
19
|
-
:key="session.sessionId"
|
|
20
|
-
class=" flex items-center justify-between w-full px-4 py-2 cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors duration-200 ease-in-out text-gray-800 dark:text-gray-200"
|
|
21
|
-
:class="{
|
|
22
|
-
'bg-lightPrimary/20 hover:bg-lightPrimary/20 dark:bg-darkPrimary/20 dark:hover:bg-darkPrimary/20': agentStore.activeSessionId === session.sessionId,
|
|
23
|
-
}"
|
|
24
|
-
@click="agentStore.setActiveSession(session.sessionId); agentStore.setSessionHistoryOpen(false);"
|
|
25
|
-
>
|
|
26
|
-
<p class="truncate">{{ session.title || session.sessionId }}</p>
|
|
27
|
-
<div @click.stop="agentStore.deleteSession(session.sessionId)" class="w-7 h-7 p-1 hover:scale-110 hover:bg-gray-200 dark:hover:bg-gray-500 flex items-center justify-center rounded">
|
|
28
|
-
<IconPlusOutline class="rotate-45 w-6 h-6"/>
|
|
29
|
-
</div>
|
|
30
|
-
</button>
|
|
31
|
-
</div>
|
|
32
|
-
<p
|
|
33
|
-
v-if="!groupedSessions || groupedSessions.length === 0"
|
|
34
|
-
class="w-full h-full flex items-center justify-center text-gray-800 dark:text-gray-200"
|
|
35
|
-
>
|
|
36
|
-
{{ $t('There are no previous chat sessions') }}
|
|
37
|
-
</p>
|
|
38
|
-
</div>
|
|
39
|
-
</template>
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
<script setup lang="ts">
|
|
43
|
-
import { Button, Spinner } from '@/afcl'
|
|
44
|
-
import { computed } from 'vue';
|
|
45
|
-
import { IconPlusOutline } from '@iconify-prerendered/vue-flowbite';
|
|
46
|
-
import type { ISessionsListItem } from './types';
|
|
47
|
-
import { useAgentStore } from './composables/useAgentStore';
|
|
48
|
-
|
|
49
|
-
const agentStore = useAgentStore();
|
|
50
|
-
|
|
51
|
-
const h3Style = "text-gray-800 dark:text-gray-200 font-medium text-xl tracking-widest my-2"
|
|
52
|
-
const dayLabelFormatter = new Intl.DateTimeFormat(undefined, { month: 'short', day: 'numeric' });
|
|
53
|
-
const dayLabelWithYearFormatter = new Intl.DateTimeFormat(undefined, { month: 'short', day: 'numeric', year: 'numeric' });
|
|
54
|
-
|
|
55
|
-
const groupedSessions = computed(() => {
|
|
56
|
-
const groups = new Map<string, { dayKey: string; label: string; sessions: ISessionsListItem[] }>();
|
|
57
|
-
|
|
58
|
-
for (const session of agentStore.sessionList) {
|
|
59
|
-
const date = new Date(session.timestamp);
|
|
60
|
-
const dayKey = getLocalDayKey(date);
|
|
61
|
-
const label = date.getFullYear() === new Date().getFullYear()
|
|
62
|
-
? dayLabelFormatter.format(date)
|
|
63
|
-
: dayLabelWithYearFormatter.format(date);
|
|
64
|
-
|
|
65
|
-
if (!groups.has(dayKey)) {
|
|
66
|
-
groups.set(dayKey, {
|
|
67
|
-
dayKey,
|
|
68
|
-
label,
|
|
69
|
-
sessions: [],
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
groups.get(dayKey)!.sessions.push(session);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return Array.from(groups.values());
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
function getLocalDayKey(date: Date) {
|
|
81
|
-
const year = date.getFullYear();
|
|
82
|
-
const month = `${date.getMonth() + 1}`.padStart(2, '0');
|
|
83
|
-
const day = `${date.getDate()}`.padStart(2, '0');
|
|
84
|
-
|
|
85
|
-
return `${year}-${month}-${day}`;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
</script>
|
package/custom/chat.ts
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file is used to fix circular module initialization between ai and @ai-sdk/vue
|
|
3
|
-
* These files are depending on each other, but vite put them in different chunks, so they are not initialized at the same time, which causes the circular module initialization issue
|
|
4
|
-
* So I get rid of the @ai-sdk/vue only fixes are:
|
|
5
|
-
* 1) Change vite config to put these files in the same chunk
|
|
6
|
-
* 2) Get rid of the circular module initialization by moving the Chat class to this file
|
|
7
|
-
*
|
|
8
|
-
* Maybe there is a better way to fix this issue
|
|
9
|
-
*
|
|
10
|
-
* If you were updating "ai" package and plugin broke, probably you need to update this file as well
|
|
11
|
-
* Or resolve the circular module initialization issue in a better way
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import type {
|
|
15
|
-
ChatInit as BaseChatInit,
|
|
16
|
-
ChatState,
|
|
17
|
-
ChatStatus,
|
|
18
|
-
UIMessage,
|
|
19
|
-
} from 'ai';
|
|
20
|
-
import { AbstractChat } from 'ai'
|
|
21
|
-
import { Ref, ref } from 'vue';
|
|
22
|
-
|
|
23
|
-
class VueChatState<
|
|
24
|
-
UI_MESSAGE extends UIMessage,
|
|
25
|
-
> implements ChatState<UI_MESSAGE> {
|
|
26
|
-
private messagesRef: Ref<UI_MESSAGE[]>;
|
|
27
|
-
private statusRef = ref<ChatStatus>('ready');
|
|
28
|
-
private errorRef = ref<Error | undefined>(undefined);
|
|
29
|
-
|
|
30
|
-
constructor(messages?: UI_MESSAGE[]) {
|
|
31
|
-
this.messagesRef = ref(messages ?? []) as Ref<UI_MESSAGE[]>;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
get messages(): UI_MESSAGE[] {
|
|
35
|
-
return this.messagesRef.value;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
set messages(messages: UI_MESSAGE[]) {
|
|
39
|
-
this.messagesRef.value = messages;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
get status(): ChatStatus {
|
|
43
|
-
return this.statusRef.value;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
set status(status: ChatStatus) {
|
|
47
|
-
this.statusRef.value = status;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
get error(): Error | undefined {
|
|
51
|
-
return this.errorRef.value;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
set error(error: Error | undefined) {
|
|
55
|
-
this.errorRef.value = error;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
pushMessage = (message: UI_MESSAGE) => {
|
|
59
|
-
this.messagesRef.value = [...this.messagesRef.value, message];
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
popMessage = () => {
|
|
63
|
-
this.messagesRef.value = this.messagesRef.value.slice(0, -1);
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
replaceMessage = (index: number, message: UI_MESSAGE) => {
|
|
67
|
-
this.messagesRef.value[index] = { ...message };
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
snapshot = <T>(value: T): T => value;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export class Chat<
|
|
74
|
-
UI_MESSAGE extends UIMessage,
|
|
75
|
-
> extends AbstractChat<UI_MESSAGE> {
|
|
76
|
-
constructor({ messages, ...init }: BaseChatInit<UI_MESSAGE>) {
|
|
77
|
-
super({
|
|
78
|
-
...init,
|
|
79
|
-
state: new VueChatState(messages),
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
}
|