@jskit-ai/assistant-core 0.1.142 → 0.1.144
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/fixtures/responsive-assistant/App.vue +106 -0
- package/fixtures/responsive-assistant/index.html +12 -0
- package/fixtures/responsive-assistant/main.js +24 -0
- package/fixtures/responsive-assistant/vite.config.mjs +18 -0
- package/package.json +5 -5
- package/src/client/components/AssistantClientElement.vue +30 -20
- package/src/server/lib/serviceToolCatalog.js +531 -80
- package/test/assistantScroll.browser.test.js +139 -0
- package/test/componentContracts.test.js +11 -0
- package/test/serviceToolCatalog.test.js +318 -9
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, ref } from "vue";
|
|
3
|
+
import AssistantClientElement from "../../src/client/components/AssistantClientElement.vue";
|
|
4
|
+
|
|
5
|
+
const longConversation = Array.from(
|
|
6
|
+
{ length: 90 },
|
|
7
|
+
(_, index) => `Conversation line ${index + 1}: responsive scroll containment must keep the composer visible.`
|
|
8
|
+
).join("\n\n");
|
|
9
|
+
|
|
10
|
+
const messages = ref([
|
|
11
|
+
{
|
|
12
|
+
id: "message-1",
|
|
13
|
+
role: "assistant",
|
|
14
|
+
kind: "chat",
|
|
15
|
+
status: "completed",
|
|
16
|
+
text: longConversation
|
|
17
|
+
}
|
|
18
|
+
]);
|
|
19
|
+
const input = ref("");
|
|
20
|
+
const isStreaming = ref(false);
|
|
21
|
+
const isRestoringConversation = ref(false);
|
|
22
|
+
const conversationId = ref("conversation-1");
|
|
23
|
+
const conversationHistory = ref([
|
|
24
|
+
{
|
|
25
|
+
id: "conversation-1",
|
|
26
|
+
title: "Responsive layout regression",
|
|
27
|
+
status: "completed",
|
|
28
|
+
startedAt: "2026-08-24T00:00:00.000Z",
|
|
29
|
+
messageCount: 1
|
|
30
|
+
}
|
|
31
|
+
]);
|
|
32
|
+
const conversationHistoryLoading = ref(false);
|
|
33
|
+
const conversationHistoryLoadingMore = ref(false);
|
|
34
|
+
const conversationHistoryHasMore = ref(false);
|
|
35
|
+
const conversationHistoryError = ref("");
|
|
36
|
+
const pendingToolEvents = ref([
|
|
37
|
+
{
|
|
38
|
+
id: "tool-1",
|
|
39
|
+
name: "assistant_action_search",
|
|
40
|
+
status: "completed"
|
|
41
|
+
}
|
|
42
|
+
]);
|
|
43
|
+
|
|
44
|
+
const state = Object.freeze({
|
|
45
|
+
messages,
|
|
46
|
+
input,
|
|
47
|
+
isStreaming,
|
|
48
|
+
isRestoringConversation,
|
|
49
|
+
pendingToolEvents,
|
|
50
|
+
conversationId,
|
|
51
|
+
conversationHistory,
|
|
52
|
+
conversationHistoryLoading,
|
|
53
|
+
conversationHistoryLoadingMore,
|
|
54
|
+
conversationHistoryHasMore,
|
|
55
|
+
conversationHistoryError,
|
|
56
|
+
isAdminSurface: ref(false),
|
|
57
|
+
canSend: computed(() => input.value.trim().length > 0),
|
|
58
|
+
canStartNewConversation: ref(true)
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const actions = Object.freeze({
|
|
62
|
+
async sendMessage() {},
|
|
63
|
+
handleInputKeydown() {},
|
|
64
|
+
async cancelStream() {},
|
|
65
|
+
async startNewConversation() {},
|
|
66
|
+
async selectConversation() {},
|
|
67
|
+
async refreshConversationHistory() {},
|
|
68
|
+
async loadMoreConversationHistory() {}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const meta = Object.freeze({
|
|
72
|
+
formatConversationStartedAt() {
|
|
73
|
+
return "Aug 24, 2026";
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
</script>
|
|
77
|
+
|
|
78
|
+
<template>
|
|
79
|
+
<v-app>
|
|
80
|
+
<v-main>
|
|
81
|
+
<main class="assistant-responsive-fixture">
|
|
82
|
+
<AssistantClientElement
|
|
83
|
+
:meta="meta"
|
|
84
|
+
:state="state"
|
|
85
|
+
:actions="actions"
|
|
86
|
+
:viewer="{ displayName: 'Ada Lovelace' }"
|
|
87
|
+
/>
|
|
88
|
+
</main>
|
|
89
|
+
</v-main>
|
|
90
|
+
</v-app>
|
|
91
|
+
</template>
|
|
92
|
+
|
|
93
|
+
<style>
|
|
94
|
+
html,
|
|
95
|
+
body,
|
|
96
|
+
#app {
|
|
97
|
+
block-size: 100%;
|
|
98
|
+
margin: 0;
|
|
99
|
+
min-block-size: 0;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.assistant-responsive-fixture {
|
|
103
|
+
block-size: 100%;
|
|
104
|
+
min-block-size: 0;
|
|
105
|
+
}
|
|
106
|
+
</style>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Assistant responsive fixture</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="app"></div>
|
|
10
|
+
<script type="module" src="/main.js"></script>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createApp } from "vue";
|
|
2
|
+
import "vuetify/styles";
|
|
3
|
+
import { createVuetify } from "vuetify";
|
|
4
|
+
import * as components from "vuetify/components";
|
|
5
|
+
import * as directives from "vuetify/directives";
|
|
6
|
+
import { aliases as mdiAliases, mdi } from "vuetify/iconsets/mdi-svg";
|
|
7
|
+
import App from "./App.vue";
|
|
8
|
+
|
|
9
|
+
const vuetify = createVuetify({
|
|
10
|
+
components,
|
|
11
|
+
directives,
|
|
12
|
+
icons: {
|
|
13
|
+
defaultSet: "mdi",
|
|
14
|
+
aliases: mdiAliases,
|
|
15
|
+
sets: { mdi }
|
|
16
|
+
},
|
|
17
|
+
theme: {
|
|
18
|
+
defaultTheme: "light"
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
createApp(App)
|
|
23
|
+
.use(vuetify)
|
|
24
|
+
.mount("#app");
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { defineConfig } from "vite";
|
|
4
|
+
import vue from "@vitejs/plugin-vue";
|
|
5
|
+
|
|
6
|
+
const fixtureRoot = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
|
|
8
|
+
export default defineConfig({
|
|
9
|
+
root: fixtureRoot,
|
|
10
|
+
plugins: [vue()],
|
|
11
|
+
resolve: {
|
|
12
|
+
preserveSymlinks: true
|
|
13
|
+
},
|
|
14
|
+
server: {
|
|
15
|
+
host: "127.0.0.1",
|
|
16
|
+
strictPort: true
|
|
17
|
+
}
|
|
18
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/assistant-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.144",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test"
|
|
@@ -11,16 +11,16 @@
|
|
|
11
11
|
"./shared": "./src/shared/index.js"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@jskit-ai/
|
|
15
|
-
"@jskit-ai/
|
|
16
|
-
"@jskit-ai/resource-core": "0.1.108",
|
|
17
|
-
"@jskit-ai/resource-crud-core": "0.1.108",
|
|
14
|
+
"@jskit-ai/resource-core": "0.1.110",
|
|
15
|
+
"@jskit-ai/resource-crud-core": "0.1.110",
|
|
18
16
|
"dompurify": "^3.4.13",
|
|
19
17
|
"json-rest-schema": "^1.0.17",
|
|
20
18
|
"marked": "^17.0.4",
|
|
21
19
|
"openai": "^6.22.0"
|
|
22
20
|
},
|
|
23
21
|
"peerDependencies": {
|
|
22
|
+
"@jskit-ai/http-runtime": "0.1.166",
|
|
23
|
+
"@jskit-ai/kernel": "0.1.168",
|
|
24
24
|
"vue": "^3.5.13",
|
|
25
25
|
"vuetify": "^4.0.0"
|
|
26
26
|
},
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
@focus="onRootFocus"
|
|
8
8
|
@pointerdown.capture="onRootPointerDown"
|
|
9
9
|
>
|
|
10
|
-
<v-row class="assistant-layout h-100 flex-grow-1 my-0">
|
|
11
|
-
<v-col cols="12"
|
|
10
|
+
<v-row class="assistant-layout h-100 flex-grow-1 flex-nowrap my-0">
|
|
11
|
+
<v-col cols="12" md="8" class="assistant-main-col d-flex flex-column overflow-hidden">
|
|
12
12
|
<v-card rounded="lg" elevation="1" border class="assistant-main-card d-flex flex-column flex-grow-1">
|
|
13
13
|
<v-card-text class="assistant-main-card-text d-flex flex-column flex-grow-1">
|
|
14
14
|
<div
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
<div v-if="resolvedFeatures.composerActions" class="assistant-actions d-flex ga-2 flex-wrap mt-2">
|
|
92
92
|
<v-btn
|
|
93
93
|
v-if="resolvedFeatures.mobilePicker"
|
|
94
|
-
class="d-
|
|
94
|
+
class="d-md-none"
|
|
95
95
|
variant="tonal"
|
|
96
96
|
:disabled="isStreaming || isRestoringConversation"
|
|
97
97
|
@click="onConversationPickerOpen"
|
|
@@ -104,13 +104,13 @@
|
|
|
104
104
|
</v-card>
|
|
105
105
|
</v-col>
|
|
106
106
|
|
|
107
|
-
<v-col cols="12"
|
|
107
|
+
<v-col cols="12" md="4" class="assistant-side-col d-none d-md-flex flex-column overflow-hidden">
|
|
108
108
|
<v-card
|
|
109
109
|
v-if="resolvedFeatures.historyPanel"
|
|
110
110
|
rounded="lg"
|
|
111
111
|
elevation="1"
|
|
112
112
|
border
|
|
113
|
-
class="d-
|
|
113
|
+
class="d-flex flex-column mb-3 assistant-history-card overflow-hidden"
|
|
114
114
|
>
|
|
115
115
|
<v-card-item>
|
|
116
116
|
<v-card-title class="text-subtitle-2 font-weight-bold">{{ copyText.conversationHistory }}</v-card-title>
|
|
@@ -1025,6 +1025,8 @@ onBeforeUnmount(() => {
|
|
|
1025
1025
|
}
|
|
1026
1026
|
|
|
1027
1027
|
.assistant-layout {
|
|
1028
|
+
height: 100%;
|
|
1029
|
+
max-height: 100%;
|
|
1028
1030
|
min-height: 0;
|
|
1029
1031
|
overflow: hidden;
|
|
1030
1032
|
}
|
|
@@ -1060,6 +1062,29 @@ onBeforeUnmount(() => {
|
|
|
1060
1062
|
min-height: 0;
|
|
1061
1063
|
}
|
|
1062
1064
|
|
|
1065
|
+
.assistant-main-col,
|
|
1066
|
+
.assistant-side-col,
|
|
1067
|
+
.assistant-main-card,
|
|
1068
|
+
.assistant-main-card-text {
|
|
1069
|
+
height: 100%;
|
|
1070
|
+
max-height: 100%;
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
.assistant-main-card-text,
|
|
1074
|
+
.assistant-history-card-text {
|
|
1075
|
+
overflow: hidden;
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
.assistant-history-card {
|
|
1079
|
+
flex: 1 1 auto;
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
.assistant-tools-card {
|
|
1083
|
+
flex: 0 1 var(--assistant-tools-panel-height, 320px);
|
|
1084
|
+
max-height: var(--assistant-tools-panel-height, 320px);
|
|
1085
|
+
min-height: min(var(--assistant-tools-panel-height, 320px), 45%);
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1063
1088
|
.messages-panel {
|
|
1064
1089
|
flex: 1 1 auto;
|
|
1065
1090
|
border: 1px solid rgba(var(--v-theme-on-surface), 0.14);
|
|
@@ -1299,19 +1324,4 @@ onBeforeUnmount(() => {
|
|
|
1299
1324
|
text-transform: uppercase;
|
|
1300
1325
|
}
|
|
1301
1326
|
|
|
1302
|
-
@media (min-width: 1280px) {
|
|
1303
|
-
.assistant-layout {
|
|
1304
|
-
flex-wrap: nowrap;
|
|
1305
|
-
}
|
|
1306
|
-
|
|
1307
|
-
.assistant-history-card {
|
|
1308
|
-
flex: 1 1 auto;
|
|
1309
|
-
}
|
|
1310
|
-
|
|
1311
|
-
.assistant-tools-card {
|
|
1312
|
-
flex: 0 0 var(--assistant-tools-panel-height, 320px);
|
|
1313
|
-
max-height: var(--assistant-tools-panel-height, 320px);
|
|
1314
|
-
min-height: var(--assistant-tools-panel-height, 320px);
|
|
1315
|
-
}
|
|
1316
|
-
}
|
|
1317
1327
|
</style>
|