@adminforth/agent 1.26.13 → 1.26.15
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/agent/simpleAgent.ts +1 -1
- package/apiBasedTools.ts +15 -46
- package/build.log +2 -2
- package/custom/ChatSurface.vue +19 -18
- package/custom/CustomAutoScrollContainer.vue +51 -51
- package/dist/agent/simpleAgent.js +1 -1
- package/dist/apiBasedTools.js +9 -31
- package/dist/custom/ChatSurface.vue +19 -18
- package/dist/custom/CustomAutoScrollContainer.vue +51 -51
- package/package.json +1 -1
package/agent/simpleAgent.ts
CHANGED
package/apiBasedTools.ts
CHANGED
|
@@ -46,9 +46,11 @@ type GetResourceDataToolResponse = {
|
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
type DateTimeColumnType = AdminForthDataTypes.DATETIME | AdminForthDataTypes.TIME;
|
|
49
|
+
type InternalApiOriginProvider = {
|
|
50
|
+
getInternalApiOrigin?: () => string | undefined;
|
|
51
|
+
};
|
|
49
52
|
|
|
50
53
|
const DEFAULT_USER_TIME_ZONE = 'UTC';
|
|
51
|
-
const DEFAULT_REQUEST_PROTOCOL = process.env.NODE_ENV === 'production' ? 'https' : 'http';
|
|
52
54
|
|
|
53
55
|
function getInputString(inputs: Record<string, unknown> | undefined, key: string) {
|
|
54
56
|
const value = inputs?.[key];
|
|
@@ -580,22 +582,6 @@ const HEADERS_NOT_FORWARDED_TO_API_TOOL = new Set([
|
|
|
580
582
|
'upgrade',
|
|
581
583
|
]);
|
|
582
584
|
|
|
583
|
-
function getHeaderValue(
|
|
584
|
-
headers: Partial<HttpExtra>['headers'] | undefined,
|
|
585
|
-
headerName: string,
|
|
586
|
-
) {
|
|
587
|
-
const normalizedHeaderName = headerName.toLowerCase();
|
|
588
|
-
const value = Object.entries(headers ?? {}).find(
|
|
589
|
-
([name]) => name.toLowerCase() === normalizedHeaderName,
|
|
590
|
-
)?.[1];
|
|
591
|
-
|
|
592
|
-
if (typeof value !== 'string') {
|
|
593
|
-
return undefined;
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
return value.split(',')[0].trim();
|
|
597
|
-
}
|
|
598
|
-
|
|
599
585
|
function isAbsoluteHttpUrl(value: string) {
|
|
600
586
|
try {
|
|
601
587
|
const url = new URL(value);
|
|
@@ -605,42 +591,25 @@ function isAbsoluteHttpUrl(value: string) {
|
|
|
605
591
|
}
|
|
606
592
|
}
|
|
607
593
|
|
|
608
|
-
function getRequestOrigin(httpExtra?: Partial<HttpExtra>) {
|
|
609
|
-
const requestUrl = httpExtra?.requestUrl;
|
|
610
|
-
|
|
611
|
-
if (requestUrl && isAbsoluteHttpUrl(requestUrl)) {
|
|
612
|
-
return new URL(requestUrl).origin;
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
const host = getHeaderValue(httpExtra?.headers, 'x-forwarded-host')
|
|
616
|
-
?? getHeaderValue(httpExtra?.headers, 'host');
|
|
617
|
-
|
|
618
|
-
if (!host) {
|
|
619
|
-
return undefined;
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
const protocol = DEFAULT_REQUEST_PROTOCOL;
|
|
623
|
-
return `${protocol}://${host}`;
|
|
624
|
-
}
|
|
625
|
-
|
|
626
594
|
function resolveOpenApiRequestUrl(params: {
|
|
627
|
-
|
|
595
|
+
adminforth: IAdminForth;
|
|
628
596
|
path: string;
|
|
629
597
|
toolName: string;
|
|
630
598
|
}) {
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
}
|
|
599
|
+
const internalApiOrigin = (params.adminforth.express as InternalApiOriginProvider)
|
|
600
|
+
.getInternalApiOrigin?.();
|
|
634
601
|
|
|
635
|
-
|
|
602
|
+
if (internalApiOrigin) {
|
|
603
|
+
const path = isAbsoluteHttpUrl(params.path)
|
|
604
|
+
? `${new URL(params.path).pathname}${new URL(params.path).search}`
|
|
605
|
+
: params.path;
|
|
636
606
|
|
|
637
|
-
|
|
638
|
-
throw new Error(
|
|
639
|
-
`Tool "${params.toolName}" has relative OpenAPI path "${params.path}" but request host header is unavailable.`,
|
|
640
|
-
);
|
|
607
|
+
return new URL(path, internalApiOrigin).toString();
|
|
641
608
|
}
|
|
642
609
|
|
|
643
|
-
|
|
610
|
+
throw new Error(
|
|
611
|
+
`Tool "${params.toolName}" cannot call OpenAPI path "${params.path}" because internal API origin is unavailable.`,
|
|
612
|
+
);
|
|
644
613
|
}
|
|
645
614
|
|
|
646
615
|
function createToolRequestHeaders(
|
|
@@ -736,7 +705,7 @@ async function callOpenApiSchema(params: {
|
|
|
736
705
|
userTimeZone,
|
|
737
706
|
);
|
|
738
707
|
const requestUrl = resolveOpenApiRequestUrl({
|
|
739
|
-
|
|
708
|
+
adminforth,
|
|
740
709
|
path: schema.path,
|
|
741
710
|
toolName,
|
|
742
711
|
});
|
package/build.log
CHANGED
|
@@ -38,5 +38,5 @@ custom/skills/fetch_data/SKILL.md
|
|
|
38
38
|
custom/skills/mutate_data/
|
|
39
39
|
custom/skills/mutate_data/SKILL.md
|
|
40
40
|
|
|
41
|
-
sent 207,
|
|
42
|
-
total size is 205,
|
|
41
|
+
sent 207,843 bytes received 562 bytes 416,810.00 bytes/sec
|
|
42
|
+
total size is 205,567 speedup is 0.99
|
package/custom/ChatSurface.vue
CHANGED
|
@@ -178,14 +178,14 @@
|
|
|
178
178
|
<script setup lang="ts">
|
|
179
179
|
import { IconChatBubbleLeft20Solid, IconSparklesSolid, IconArrowsPointingOut, IconArrowsPointingIn } from '@iconify-prerendered/vue-heroicons';
|
|
180
180
|
import { IconCloseOutline, IconBarsOutline, IconArrowUpOutline, IconCloseSidebarSolid, IconOpenSidebarSolid, IconAngleDownOutline } from '@iconify-prerendered/vue-flowbite';
|
|
181
|
-
import { useTemplateRef, onMounted, ref
|
|
181
|
+
import { useTemplateRef, onMounted, ref } from 'vue';
|
|
182
182
|
import { onClickOutside } from '@vueuse/core'
|
|
183
183
|
import ConversationArea from './conversation_area/ConversationArea.vue';
|
|
184
184
|
import { useAgentStore } from './composables/useAgentStore';
|
|
185
185
|
import { useAgentTransitions } from './composables/useAgentTransitions';
|
|
186
186
|
import { Button } from '@/afcl';
|
|
187
187
|
import { useCoreStore } from '@/stores/core';
|
|
188
|
-
import { remToPx
|
|
188
|
+
import { remToPx } from './utils';
|
|
189
189
|
|
|
190
190
|
const props = defineProps<{
|
|
191
191
|
meta: {
|
|
@@ -210,6 +210,23 @@ const isModeMenuOpen = ref(false);
|
|
|
210
210
|
let startX = 0
|
|
211
211
|
let startWidth = 0
|
|
212
212
|
|
|
213
|
+
onClickOutside(chatSurface, () => {if (!agentStore.isTeleportedToBody) agentStore.setIsChatOpen(false);});
|
|
214
|
+
onClickOutside(modeMenu, () => { isModeMenuOpen.value = false; });
|
|
215
|
+
|
|
216
|
+
onMounted(async () => {
|
|
217
|
+
agentStore.setAvailableModes(props.meta.modes, props.meta.defaultModeName);
|
|
218
|
+
agentStore.regisrerTextInput(textInput.value);
|
|
219
|
+
textInput.value?.focus();
|
|
220
|
+
const isTeleportedToBodyFromLocalStorage = agentStore.getLocalStorageItem('isTeleportedToBody') === 'true' || agentStore.getLocalStorageItem('isTeleportedToBodyBeforeFullScreen') === 'true';
|
|
221
|
+
if( coreStore.isMobile ) {
|
|
222
|
+
agentStore.setIsTeleportedToBody(false);
|
|
223
|
+
} else {
|
|
224
|
+
agentStore.setIsTeleportedToBody(isTeleportedToBodyFromLocalStorage || props.meta.stickByDefault);
|
|
225
|
+
}
|
|
226
|
+
await agentStore.fetchSessionsList();
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
|
|
213
230
|
const startResize = (e: MouseEvent) => {
|
|
214
231
|
startX = e.clientX
|
|
215
232
|
startWidth = remToPx(agentStore.chatWidth)
|
|
@@ -242,22 +259,6 @@ const stopResize = () => {
|
|
|
242
259
|
}
|
|
243
260
|
}
|
|
244
261
|
|
|
245
|
-
onClickOutside(chatSurface, () => {if (!agentStore.isTeleportedToBody) agentStore.setIsChatOpen(false);});
|
|
246
|
-
onClickOutside(modeMenu, () => { isModeMenuOpen.value = false; });
|
|
247
|
-
|
|
248
|
-
onMounted(async () => {
|
|
249
|
-
agentStore.setAvailableModes(props.meta.modes, props.meta.defaultModeName);
|
|
250
|
-
agentStore.regisrerTextInput(textInput.value);
|
|
251
|
-
textInput.value?.focus();
|
|
252
|
-
const isTeleportedToBodyFromLocalStorage = agentStore.getLocalStorageItem('isTeleportedToBody') === 'true' || agentStore.getLocalStorageItem('isTeleportedToBodyBeforeFullScreen') === 'true';
|
|
253
|
-
if( coreStore.isMobile ) {
|
|
254
|
-
agentStore.setIsTeleportedToBody(false);
|
|
255
|
-
} else {
|
|
256
|
-
agentStore.setIsTeleportedToBody(isTeleportedToBodyFromLocalStorage || props.meta.stickByDefault);
|
|
257
|
-
}
|
|
258
|
-
await agentStore.fetchSessionsList();
|
|
259
|
-
});
|
|
260
|
-
|
|
261
262
|
function autoResize() {
|
|
262
263
|
const el = textInput.value
|
|
263
264
|
if (!el) return
|
|
@@ -15,13 +15,7 @@
|
|
|
15
15
|
import { ref, onMounted, onUnmounted, nextTick, computed } from 'vue'
|
|
16
16
|
import CustomScrollbar from 'custom-vue-scrollbar';
|
|
17
17
|
import 'custom-vue-scrollbar/dist/style.css';
|
|
18
|
-
import { useAgentStore } from './composables/useAgentStore';
|
|
19
18
|
|
|
20
|
-
const scrollParams = ref({
|
|
21
|
-
scrollTop: 0,
|
|
22
|
-
scrollHeight: 0,
|
|
23
|
-
clientHeight: 0
|
|
24
|
-
});
|
|
25
19
|
|
|
26
20
|
const props = withDefaults(defineProps<{
|
|
27
21
|
enabled?: boolean
|
|
@@ -43,6 +37,57 @@ const scrollElement = ref<HTMLElement | null>(null)
|
|
|
43
37
|
|
|
44
38
|
let lastScrollTop = 0
|
|
45
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
|
+
})
|
|
46
91
|
|
|
47
92
|
function isNearBottom(): boolean {
|
|
48
93
|
const container = containerRef.value?.scrollEl
|
|
@@ -99,51 +144,6 @@ function handleScroll(detectScrollDown = true): void {
|
|
|
99
144
|
lastScrollHeight = scrollHeight
|
|
100
145
|
}
|
|
101
146
|
|
|
102
|
-
let observer: MutationObserver | null = null
|
|
103
|
-
|
|
104
|
-
onMounted(() => {
|
|
105
|
-
if (!containerRef.value) return
|
|
106
|
-
|
|
107
|
-
scrollElement.value = containerRef.value.scrollEl
|
|
108
|
-
lastScrollTop = containerRef.value.scrollEl.scrollTop
|
|
109
|
-
lastScrollHeight = containerRef.value.scrollEl.scrollHeight
|
|
110
|
-
|
|
111
|
-
observer = new MutationObserver(() => {
|
|
112
|
-
nextTick(() => {
|
|
113
|
-
if (!containerRef.value?.scrollEl) return
|
|
114
|
-
|
|
115
|
-
if (!hasScrollbar()) {
|
|
116
|
-
isUserScrolledUp.value = false
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
lastScrollHeight = containerRef.value.scrollEl.scrollHeight
|
|
120
|
-
scrollParams.value.scrollTop = containerRef.value.scrollEl.scrollTop
|
|
121
|
-
scrollParams.value.scrollHeight = containerRef.value.scrollEl.scrollHeight
|
|
122
|
-
scrollParams.value.clientHeight = containerRef.value.scrollEl.clientHeight
|
|
123
|
-
if (props.enabled && !isUserScrolledUp.value) {
|
|
124
|
-
scrollToBottom()
|
|
125
|
-
}
|
|
126
|
-
})
|
|
127
|
-
})
|
|
128
|
-
|
|
129
|
-
observer.observe(containerRef.value?.scrollEl, {
|
|
130
|
-
childList: true,
|
|
131
|
-
subtree: true,
|
|
132
|
-
characterData: true
|
|
133
|
-
})
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
onUnmounted(() => {
|
|
137
|
-
observer?.disconnect()
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
defineExpose({
|
|
141
|
-
scrollToBottom: () => scrollToBottom(true),
|
|
142
|
-
isUserScrolledUp: () => isUserScrolledUp.value,
|
|
143
|
-
container: containerRef,
|
|
144
|
-
handleScroll,
|
|
145
|
-
scrollParams
|
|
146
|
-
})
|
|
147
147
|
</script>
|
|
148
148
|
|
|
149
149
|
<style>
|
package/dist/apiBasedTools.js
CHANGED
|
@@ -16,7 +16,6 @@ import YAML from 'yaml';
|
|
|
16
16
|
dayjs.extend(utc);
|
|
17
17
|
dayjs.extend(timezone);
|
|
18
18
|
const DEFAULT_USER_TIME_ZONE = 'UTC';
|
|
19
|
-
const DEFAULT_REQUEST_PROTOCOL = process.env.NODE_ENV === 'production' ? 'https' : 'http';
|
|
20
19
|
function getInputString(inputs, key) {
|
|
21
20
|
const value = inputs === null || inputs === void 0 ? void 0 : inputs[key];
|
|
22
21
|
return typeof value === 'string' && value ? value : undefined;
|
|
@@ -395,15 +394,6 @@ const HEADERS_NOT_FORWARDED_TO_API_TOOL = new Set([
|
|
|
395
394
|
'transfer-encoding',
|
|
396
395
|
'upgrade',
|
|
397
396
|
]);
|
|
398
|
-
function getHeaderValue(headers, headerName) {
|
|
399
|
-
var _a;
|
|
400
|
-
const normalizedHeaderName = headerName.toLowerCase();
|
|
401
|
-
const value = (_a = Object.entries(headers !== null && headers !== void 0 ? headers : {}).find(([name]) => name.toLowerCase() === normalizedHeaderName)) === null || _a === void 0 ? void 0 : _a[1];
|
|
402
|
-
if (typeof value !== 'string') {
|
|
403
|
-
return undefined;
|
|
404
|
-
}
|
|
405
|
-
return value.split(',')[0].trim();
|
|
406
|
-
}
|
|
407
397
|
function isAbsoluteHttpUrl(value) {
|
|
408
398
|
try {
|
|
409
399
|
const url = new URL(value);
|
|
@@ -413,28 +403,16 @@ function isAbsoluteHttpUrl(value) {
|
|
|
413
403
|
return false;
|
|
414
404
|
}
|
|
415
405
|
}
|
|
416
|
-
function getRequestOrigin(httpExtra) {
|
|
417
|
-
var _a;
|
|
418
|
-
const requestUrl = httpExtra === null || httpExtra === void 0 ? void 0 : httpExtra.requestUrl;
|
|
419
|
-
if (requestUrl && isAbsoluteHttpUrl(requestUrl)) {
|
|
420
|
-
return new URL(requestUrl).origin;
|
|
421
|
-
}
|
|
422
|
-
const host = (_a = getHeaderValue(httpExtra === null || httpExtra === void 0 ? void 0 : httpExtra.headers, 'x-forwarded-host')) !== null && _a !== void 0 ? _a : getHeaderValue(httpExtra === null || httpExtra === void 0 ? void 0 : httpExtra.headers, 'host');
|
|
423
|
-
if (!host) {
|
|
424
|
-
return undefined;
|
|
425
|
-
}
|
|
426
|
-
const protocol = DEFAULT_REQUEST_PROTOCOL;
|
|
427
|
-
return `${protocol}://${host}`;
|
|
428
|
-
}
|
|
429
406
|
function resolveOpenApiRequestUrl(params) {
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
407
|
+
var _a, _b;
|
|
408
|
+
const internalApiOrigin = (_b = (_a = params.adminforth.express).getInternalApiOrigin) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
409
|
+
if (internalApiOrigin) {
|
|
410
|
+
const path = isAbsoluteHttpUrl(params.path)
|
|
411
|
+
? `${new URL(params.path).pathname}${new URL(params.path).search}`
|
|
412
|
+
: params.path;
|
|
413
|
+
return new URL(path, internalApiOrigin).toString();
|
|
436
414
|
}
|
|
437
|
-
|
|
415
|
+
throw new Error(`Tool "${params.toolName}" cannot call OpenAPI path "${params.path}" because internal API origin is unavailable.`);
|
|
438
416
|
}
|
|
439
417
|
function createToolRequestHeaders(httpExtra, userTimeZone) {
|
|
440
418
|
var _a;
|
|
@@ -499,7 +477,7 @@ function callOpenApiSchema(params) {
|
|
|
499
477
|
const method = schema.method.toUpperCase();
|
|
500
478
|
const body = normalizeDateTimeInputsToUtc(((_a = inputs !== null && inputs !== void 0 ? inputs : httpExtra === null || httpExtra === void 0 ? void 0 : httpExtra.body) !== null && _a !== void 0 ? _a : {}), adminforth, userTimeZone);
|
|
501
479
|
const requestUrl = resolveOpenApiRequestUrl({
|
|
502
|
-
|
|
480
|
+
adminforth,
|
|
503
481
|
path: schema.path,
|
|
504
482
|
toolName,
|
|
505
483
|
});
|
|
@@ -178,14 +178,14 @@
|
|
|
178
178
|
<script setup lang="ts">
|
|
179
179
|
import { IconChatBubbleLeft20Solid, IconSparklesSolid, IconArrowsPointingOut, IconArrowsPointingIn } from '@iconify-prerendered/vue-heroicons';
|
|
180
180
|
import { IconCloseOutline, IconBarsOutline, IconArrowUpOutline, IconCloseSidebarSolid, IconOpenSidebarSolid, IconAngleDownOutline } from '@iconify-prerendered/vue-flowbite';
|
|
181
|
-
import { useTemplateRef, onMounted, ref
|
|
181
|
+
import { useTemplateRef, onMounted, ref } from 'vue';
|
|
182
182
|
import { onClickOutside } from '@vueuse/core'
|
|
183
183
|
import ConversationArea from './conversation_area/ConversationArea.vue';
|
|
184
184
|
import { useAgentStore } from './composables/useAgentStore';
|
|
185
185
|
import { useAgentTransitions } from './composables/useAgentTransitions';
|
|
186
186
|
import { Button } from '@/afcl';
|
|
187
187
|
import { useCoreStore } from '@/stores/core';
|
|
188
|
-
import { remToPx
|
|
188
|
+
import { remToPx } from './utils';
|
|
189
189
|
|
|
190
190
|
const props = defineProps<{
|
|
191
191
|
meta: {
|
|
@@ -210,6 +210,23 @@ const isModeMenuOpen = ref(false);
|
|
|
210
210
|
let startX = 0
|
|
211
211
|
let startWidth = 0
|
|
212
212
|
|
|
213
|
+
onClickOutside(chatSurface, () => {if (!agentStore.isTeleportedToBody) agentStore.setIsChatOpen(false);});
|
|
214
|
+
onClickOutside(modeMenu, () => { isModeMenuOpen.value = false; });
|
|
215
|
+
|
|
216
|
+
onMounted(async () => {
|
|
217
|
+
agentStore.setAvailableModes(props.meta.modes, props.meta.defaultModeName);
|
|
218
|
+
agentStore.regisrerTextInput(textInput.value);
|
|
219
|
+
textInput.value?.focus();
|
|
220
|
+
const isTeleportedToBodyFromLocalStorage = agentStore.getLocalStorageItem('isTeleportedToBody') === 'true' || agentStore.getLocalStorageItem('isTeleportedToBodyBeforeFullScreen') === 'true';
|
|
221
|
+
if( coreStore.isMobile ) {
|
|
222
|
+
agentStore.setIsTeleportedToBody(false);
|
|
223
|
+
} else {
|
|
224
|
+
agentStore.setIsTeleportedToBody(isTeleportedToBodyFromLocalStorage || props.meta.stickByDefault);
|
|
225
|
+
}
|
|
226
|
+
await agentStore.fetchSessionsList();
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
|
|
213
230
|
const startResize = (e: MouseEvent) => {
|
|
214
231
|
startX = e.clientX
|
|
215
232
|
startWidth = remToPx(agentStore.chatWidth)
|
|
@@ -242,22 +259,6 @@ const stopResize = () => {
|
|
|
242
259
|
}
|
|
243
260
|
}
|
|
244
261
|
|
|
245
|
-
onClickOutside(chatSurface, () => {if (!agentStore.isTeleportedToBody) agentStore.setIsChatOpen(false);});
|
|
246
|
-
onClickOutside(modeMenu, () => { isModeMenuOpen.value = false; });
|
|
247
|
-
|
|
248
|
-
onMounted(async () => {
|
|
249
|
-
agentStore.setAvailableModes(props.meta.modes, props.meta.defaultModeName);
|
|
250
|
-
agentStore.regisrerTextInput(textInput.value);
|
|
251
|
-
textInput.value?.focus();
|
|
252
|
-
const isTeleportedToBodyFromLocalStorage = agentStore.getLocalStorageItem('isTeleportedToBody') === 'true' || agentStore.getLocalStorageItem('isTeleportedToBodyBeforeFullScreen') === 'true';
|
|
253
|
-
if( coreStore.isMobile ) {
|
|
254
|
-
agentStore.setIsTeleportedToBody(false);
|
|
255
|
-
} else {
|
|
256
|
-
agentStore.setIsTeleportedToBody(isTeleportedToBodyFromLocalStorage || props.meta.stickByDefault);
|
|
257
|
-
}
|
|
258
|
-
await agentStore.fetchSessionsList();
|
|
259
|
-
});
|
|
260
|
-
|
|
261
262
|
function autoResize() {
|
|
262
263
|
const el = textInput.value
|
|
263
264
|
if (!el) return
|
|
@@ -15,13 +15,7 @@
|
|
|
15
15
|
import { ref, onMounted, onUnmounted, nextTick, computed } from 'vue'
|
|
16
16
|
import CustomScrollbar from 'custom-vue-scrollbar';
|
|
17
17
|
import 'custom-vue-scrollbar/dist/style.css';
|
|
18
|
-
import { useAgentStore } from './composables/useAgentStore';
|
|
19
18
|
|
|
20
|
-
const scrollParams = ref({
|
|
21
|
-
scrollTop: 0,
|
|
22
|
-
scrollHeight: 0,
|
|
23
|
-
clientHeight: 0
|
|
24
|
-
});
|
|
25
19
|
|
|
26
20
|
const props = withDefaults(defineProps<{
|
|
27
21
|
enabled?: boolean
|
|
@@ -43,6 +37,57 @@ const scrollElement = ref<HTMLElement | null>(null)
|
|
|
43
37
|
|
|
44
38
|
let lastScrollTop = 0
|
|
45
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
|
+
})
|
|
46
91
|
|
|
47
92
|
function isNearBottom(): boolean {
|
|
48
93
|
const container = containerRef.value?.scrollEl
|
|
@@ -99,51 +144,6 @@ function handleScroll(detectScrollDown = true): void {
|
|
|
99
144
|
lastScrollHeight = scrollHeight
|
|
100
145
|
}
|
|
101
146
|
|
|
102
|
-
let observer: MutationObserver | null = null
|
|
103
|
-
|
|
104
|
-
onMounted(() => {
|
|
105
|
-
if (!containerRef.value) return
|
|
106
|
-
|
|
107
|
-
scrollElement.value = containerRef.value.scrollEl
|
|
108
|
-
lastScrollTop = containerRef.value.scrollEl.scrollTop
|
|
109
|
-
lastScrollHeight = containerRef.value.scrollEl.scrollHeight
|
|
110
|
-
|
|
111
|
-
observer = new MutationObserver(() => {
|
|
112
|
-
nextTick(() => {
|
|
113
|
-
if (!containerRef.value?.scrollEl) return
|
|
114
|
-
|
|
115
|
-
if (!hasScrollbar()) {
|
|
116
|
-
isUserScrolledUp.value = false
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
lastScrollHeight = containerRef.value.scrollEl.scrollHeight
|
|
120
|
-
scrollParams.value.scrollTop = containerRef.value.scrollEl.scrollTop
|
|
121
|
-
scrollParams.value.scrollHeight = containerRef.value.scrollEl.scrollHeight
|
|
122
|
-
scrollParams.value.clientHeight = containerRef.value.scrollEl.clientHeight
|
|
123
|
-
if (props.enabled && !isUserScrolledUp.value) {
|
|
124
|
-
scrollToBottom()
|
|
125
|
-
}
|
|
126
|
-
})
|
|
127
|
-
})
|
|
128
|
-
|
|
129
|
-
observer.observe(containerRef.value?.scrollEl, {
|
|
130
|
-
childList: true,
|
|
131
|
-
subtree: true,
|
|
132
|
-
characterData: true
|
|
133
|
-
})
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
onUnmounted(() => {
|
|
137
|
-
observer?.disconnect()
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
defineExpose({
|
|
141
|
-
scrollToBottom: () => scrollToBottom(true),
|
|
142
|
-
isUserScrolledUp: () => isUserScrolledUp.value,
|
|
143
|
-
container: containerRef,
|
|
144
|
-
handleScroll,
|
|
145
|
-
scrollParams
|
|
146
|
-
})
|
|
147
147
|
</script>
|
|
148
148
|
|
|
149
149
|
<style>
|