@jskit-ai/assistant-core 0.1.165 → 0.1.166
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/examples/conversation/App.vue +104 -0
- package/examples/conversation/README.md +42 -0
- package/examples/conversation/dist/assets/index-CSTXm6q3.css +1 -0
- package/examples/conversation/dist/assets/index-DGgOLzoo.js +30 -0
- package/examples/conversation/dist/index.html +4 -0
- package/examples/conversation/index.html +2 -0
- package/examples/conversation/main.js +9 -0
- package/examples/conversation/node_modules/.vite/deps/@mdi_js.js +7450 -0
- package/examples/conversation/node_modules/.vite/deps/@mdi_js.js.map +1 -0
- package/examples/conversation/node_modules/.vite/deps/VTooltip-jIxO6ULs.js +2311 -0
- package/examples/conversation/node_modules/.vite/deps/VTooltip-jIxO6ULs.js.map +1 -0
- package/examples/conversation/node_modules/.vite/deps/_metadata.json +70 -0
- package/examples/conversation/node_modules/.vite/deps/defineComponent-DK6LSjDW.js +710 -0
- package/examples/conversation/node_modules/.vite/deps/defineComponent-DK6LSjDW.js.map +1 -0
- package/examples/conversation/node_modules/.vite/deps/hotkey-parsing-DnoZxtbW.js +1214 -0
- package/examples/conversation/node_modules/.vite/deps/hotkey-parsing-DnoZxtbW.js.map +1 -0
- package/examples/conversation/node_modules/.vite/deps/icons-ze2hmg7j.js +98 -0
- package/examples/conversation/node_modules/.vite/deps/icons-ze2hmg7j.js.map +1 -0
- package/examples/conversation/node_modules/.vite/deps/package.json +3 -0
- package/examples/conversation/node_modules/.vite/deps/theme-D78LVcJg.js +1301 -0
- package/examples/conversation/node_modules/.vite/deps/theme-D78LVcJg.js.map +1 -0
- package/examples/conversation/node_modules/.vite/deps/vue.js +2 -0
- package/examples/conversation/node_modules/.vite/deps/vue.runtime.esm-bundler-YcakWsDn.js +8538 -0
- package/examples/conversation/node_modules/.vite/deps/vue.runtime.esm-bundler-YcakWsDn.js.map +1 -0
- package/examples/conversation/node_modules/.vite/deps/vuetify.js +413 -0
- package/examples/conversation/node_modules/.vite/deps/vuetify.js.map +1 -0
- package/examples/conversation/node_modules/.vite/deps/vuetify_components.js +25370 -0
- package/examples/conversation/node_modules/.vite/deps/vuetify_components.js.map +1 -0
- package/examples/conversation/node_modules/.vite/deps/vuetify_directives.js +132 -0
- package/examples/conversation/node_modules/.vite/deps/vuetify_directives.js.map +1 -0
- package/examples/conversation/node_modules/.vite/deps/vuetify_iconsets_mdi-svg.js +70 -0
- package/examples/conversation/node_modules/.vite/deps/vuetify_iconsets_mdi-svg.js.map +1 -0
- package/examples/conversation/package.json +22 -0
- package/examples/conversation/server.js +123 -0
- package/examples/conversation/vite.config.js +8 -0
- package/package.json +59 -7
- package/src/client/conversation/AssistantComposerActions.vue +43 -0
- package/src/client/conversation/AssistantConversationElement.vue +78 -0
- package/src/client/conversation/AssistantProgress.vue +88 -0
- package/src/client/conversation/AssistantPromptInput.vue +467 -0
- package/src/client/conversation/AssistantTranscript.vue +1361 -0
- package/src/client/conversation/LongTextInlineParts.vue +64 -0
- package/src/client/conversation/LongTextPreviewBlocks.vue +324 -0
- package/src/client/conversation/index.js +9 -0
- package/src/client/conversation/submitText.js +29 -0
- package/src/client/conversation/useScrollToBottom.js +151 -0
- package/src/server/conversation/codexClient.js +328 -0
- package/src/server/conversation/codexEvents.js +623 -0
- package/src/server/conversation/codexTurn.js +280 -0
- package/src/server/conversation/index.js +2 -0
- package/src/server/conversation/memoryStorage.js +76 -0
- package/src/server/conversation/normalize.js +7 -0
- package/src/server/conversation/openCodeClient.js +512 -0
- package/src/server/conversation/transcript.js +92 -0
- package/src/shared/conversation/answerChoiceSugar.js +191 -0
- package/src/shared/conversation/index.js +6 -0
- package/src/shared/conversation/longTextBlocks.js +403 -0
- package/src/shared/conversation/numberedQuestionSugar.js +295 -0
- package/src/shared/conversation/scrollFollowState.js +32 -0
- package/src/shared/conversation/thinkingText.js +13 -0
- package/src/shared/conversation/turns.js +30 -0
- package/src/testing/conversationStorageContract.js +35 -0
- package/test/conversation.test.js +57 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { Dt as mergeProps, Yt as resolveComponent, p as render, pt as h } from "./vue.runtime.esm-bundler-YcakWsDn.js";
|
|
2
|
+
import { G as isObject, gt as consoleError } from "./defineComponent-DK6LSjDW.js";
|
|
3
|
+
import { _ as Ripple, n as Touch, o as ClickOutside, r as Resize, t as VTooltip, x as Intersect } from "./VTooltip-jIxO6ULs.js";
|
|
4
|
+
//#region ../../../../node_modules/vuetify/lib/directives/mutate/index.js
|
|
5
|
+
function mounted$1(el, binding) {
|
|
6
|
+
const modifiers = binding.modifiers || {};
|
|
7
|
+
const value = binding.value;
|
|
8
|
+
const { once, immediate, ...modifierKeys } = modifiers;
|
|
9
|
+
const defaultValue = !Object.keys(modifierKeys).length;
|
|
10
|
+
const { handler, options } = typeof value === "object" ? value : {
|
|
11
|
+
handler: value,
|
|
12
|
+
options: {
|
|
13
|
+
attributes: modifierKeys?.attr ?? defaultValue,
|
|
14
|
+
characterData: modifierKeys?.char ?? defaultValue,
|
|
15
|
+
childList: modifierKeys?.child ?? defaultValue,
|
|
16
|
+
subtree: modifierKeys?.sub ?? defaultValue
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
const observer = new MutationObserver((mutations = [], observer) => {
|
|
20
|
+
handler?.(mutations, observer);
|
|
21
|
+
if (once) unmounted$1(el, binding);
|
|
22
|
+
});
|
|
23
|
+
if (immediate) handler?.([], observer);
|
|
24
|
+
el._mutate = Object(el._mutate);
|
|
25
|
+
el._mutate[binding.instance.$.uid] = { observer };
|
|
26
|
+
observer.observe(el, options);
|
|
27
|
+
}
|
|
28
|
+
function unmounted$1(el, binding) {
|
|
29
|
+
if (!el._mutate?.[binding.instance.$.uid]) return;
|
|
30
|
+
el._mutate[binding.instance.$.uid].observer.disconnect();
|
|
31
|
+
delete el._mutate[binding.instance.$.uid];
|
|
32
|
+
}
|
|
33
|
+
var Mutate = {
|
|
34
|
+
mounted: mounted$1,
|
|
35
|
+
unmounted: unmounted$1
|
|
36
|
+
};
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region ../../../../node_modules/vuetify/lib/directives/scroll/index.js
|
|
39
|
+
function mounted(el, binding) {
|
|
40
|
+
const { self = false } = binding.modifiers ?? {};
|
|
41
|
+
const value = binding.value;
|
|
42
|
+
const options = typeof value === "object" && value.options || { passive: true };
|
|
43
|
+
const handler = typeof value === "function" || "handleEvent" in value ? value : value.handler;
|
|
44
|
+
const target = self ? el : binding.arg ? document.querySelector(binding.arg) : window;
|
|
45
|
+
if (!target) return;
|
|
46
|
+
target.addEventListener("scroll", handler, options);
|
|
47
|
+
el._onScroll = Object(el._onScroll);
|
|
48
|
+
el._onScroll[binding.instance.$.uid] = {
|
|
49
|
+
handler,
|
|
50
|
+
options,
|
|
51
|
+
target: self ? void 0 : target
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function unmounted(el, binding) {
|
|
55
|
+
if (!el._onScroll?.[binding.instance.$.uid]) return;
|
|
56
|
+
const { handler, options, target = el } = el._onScroll[binding.instance.$.uid];
|
|
57
|
+
target.removeEventListener("scroll", handler, options);
|
|
58
|
+
delete el._onScroll[binding.instance.$.uid];
|
|
59
|
+
}
|
|
60
|
+
function updated(el, binding) {
|
|
61
|
+
if (binding.value === binding.oldValue) return;
|
|
62
|
+
unmounted(el, binding);
|
|
63
|
+
mounted(el, binding);
|
|
64
|
+
}
|
|
65
|
+
var Scroll = {
|
|
66
|
+
mounted,
|
|
67
|
+
unmounted,
|
|
68
|
+
updated
|
|
69
|
+
};
|
|
70
|
+
//#endregion
|
|
71
|
+
//#region ../../../../node_modules/vuetify/lib/composables/directiveComponent.js
|
|
72
|
+
function useDirectiveComponent(component, props) {
|
|
73
|
+
const hook = mountComponent(typeof component === "string" ? resolveComponent(component) : component, props);
|
|
74
|
+
return {
|
|
75
|
+
mounted: hook,
|
|
76
|
+
updated: hook,
|
|
77
|
+
unmounted(el) {
|
|
78
|
+
render(null, el);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function mountComponent(component, props) {
|
|
83
|
+
return function(el, binding, vnode) {
|
|
84
|
+
const _props = typeof props === "function" ? props(binding) : props;
|
|
85
|
+
const text = binding.value?.text ?? binding.value ?? _props?.text;
|
|
86
|
+
const value = isObject(binding.value) ? binding.value : {};
|
|
87
|
+
const children = () => text ?? el.textContent;
|
|
88
|
+
const provides = (vnode.ctx === binding.instance.$ ? findComponentParent(vnode, binding.instance.$)?.provides : vnode.ctx?.provides) ?? binding.instance.$.provides;
|
|
89
|
+
const node = h(component, mergeProps(_props, value), children);
|
|
90
|
+
node.appContext = Object.assign(Object.create(null), binding.instance.$.appContext, { provides });
|
|
91
|
+
render(node, el);
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function findComponentParent(vnode, root) {
|
|
95
|
+
const stack = /* @__PURE__ */ new Set();
|
|
96
|
+
const walk = (children) => {
|
|
97
|
+
for (const child of children) {
|
|
98
|
+
if (!child) continue;
|
|
99
|
+
if (child === vnode || child.el && vnode.el && child.el === vnode.el) return true;
|
|
100
|
+
stack.add(child);
|
|
101
|
+
let result;
|
|
102
|
+
if (child.suspense) result = walk([child.ssContent]);
|
|
103
|
+
else if (Array.isArray(child.children)) result = walk(child.children);
|
|
104
|
+
else if (child.component?.vnode) result = walk([child.component?.subTree]);
|
|
105
|
+
if (result) return result;
|
|
106
|
+
stack.delete(child);
|
|
107
|
+
}
|
|
108
|
+
return false;
|
|
109
|
+
};
|
|
110
|
+
if (!walk([root.subTree])) {
|
|
111
|
+
consoleError("Could not find original vnode, component will not inherit provides");
|
|
112
|
+
return root;
|
|
113
|
+
}
|
|
114
|
+
const result = Array.from(stack).reverse();
|
|
115
|
+
for (const child of result) if (child.component) return child.component;
|
|
116
|
+
return root;
|
|
117
|
+
}
|
|
118
|
+
//#endregion
|
|
119
|
+
//#region ../../../../node_modules/vuetify/lib/directives/tooltip/index.js
|
|
120
|
+
var Tooltip = useDirectiveComponent(VTooltip, (binding) => {
|
|
121
|
+
return {
|
|
122
|
+
activator: (isObject(binding.value) ? !binding.value.text : [
|
|
123
|
+
"",
|
|
124
|
+
false,
|
|
125
|
+
null
|
|
126
|
+
].includes(binding.value)) ? null : "parent",
|
|
127
|
+
location: binding.arg?.replace("-", " "),
|
|
128
|
+
text: typeof binding.value === "boolean" ? void 0 : binding.value
|
|
129
|
+
};
|
|
130
|
+
});
|
|
131
|
+
//#endregion
|
|
132
|
+
export { ClickOutside, Intersect, Mutate, Resize, Ripple, Scroll, Tooltip, Touch };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vuetify_directives.js","names":["mounted","unmounted"],"sources":["../../../../../../../node_modules/vuetify/lib/directives/mutate/index.js","../../../../../../../node_modules/vuetify/lib/directives/scroll/index.js","../../../../../../../node_modules/vuetify/lib/composables/directiveComponent.js","../../../../../../../node_modules/vuetify/lib/directives/tooltip/index.js"],"sourcesContent":["// Types\n\nfunction mounted(el, binding) {\n const modifiers = binding.modifiers || {};\n const value = binding.value;\n const {\n once,\n immediate,\n ...modifierKeys\n } = modifiers;\n const defaultValue = !Object.keys(modifierKeys).length;\n const {\n handler,\n options\n } = typeof value === 'object' ? value : {\n handler: value,\n options: {\n attributes: modifierKeys?.attr ?? defaultValue,\n characterData: modifierKeys?.char ?? defaultValue,\n childList: modifierKeys?.child ?? defaultValue,\n subtree: modifierKeys?.sub ?? defaultValue\n }\n };\n const observer = new MutationObserver((mutations = [], observer) => {\n handler?.(mutations, observer);\n if (once) unmounted(el, binding);\n });\n if (immediate) handler?.([], observer);\n el._mutate = Object(el._mutate);\n el._mutate[binding.instance.$.uid] = {\n observer\n };\n observer.observe(el, options);\n}\nfunction unmounted(el, binding) {\n if (!el._mutate?.[binding.instance.$.uid]) return;\n el._mutate[binding.instance.$.uid].observer.disconnect();\n delete el._mutate[binding.instance.$.uid];\n}\nexport const Mutate = {\n mounted,\n unmounted\n};\nexport default Mutate;\n//# sourceMappingURL=index.js.map","// Types\n\nfunction mounted(el, binding) {\n const {\n self = false\n } = binding.modifiers ?? {};\n const value = binding.value;\n const options = typeof value === 'object' && value.options || {\n passive: true\n };\n const handler = typeof value === 'function' || 'handleEvent' in value ? value : value.handler;\n const target = self ? el : binding.arg ? document.querySelector(binding.arg) : window;\n if (!target) return;\n target.addEventListener('scroll', handler, options);\n el._onScroll = Object(el._onScroll);\n el._onScroll[binding.instance.$.uid] = {\n handler,\n options,\n // Don't reference self\n target: self ? undefined : target\n };\n}\nfunction unmounted(el, binding) {\n if (!el._onScroll?.[binding.instance.$.uid]) return;\n const {\n handler,\n options,\n target = el\n } = el._onScroll[binding.instance.$.uid];\n target.removeEventListener('scroll', handler, options);\n delete el._onScroll[binding.instance.$.uid];\n}\nfunction updated(el, binding) {\n if (binding.value === binding.oldValue) return;\n unmounted(el, binding);\n mounted(el, binding);\n}\nexport const Scroll = {\n mounted,\n unmounted,\n updated\n};\nexport default Scroll;\n//# sourceMappingURL=index.js.map","// Utilities\nimport { h, mergeProps, render, resolveComponent } from 'vue';\nimport { consoleError, isObject } from \"../util/index.js\"; // Types\nexport function useDirectiveComponent(component, props) {\n const concreteComponent = typeof component === 'string' ? resolveComponent(component) : component;\n const hook = mountComponent(concreteComponent, props);\n return {\n mounted: hook,\n updated: hook,\n unmounted(el) {\n render(null, el);\n }\n };\n}\nfunction mountComponent(component, props) {\n return function (el, binding, vnode) {\n const _props = typeof props === 'function' ? props(binding) : props;\n const text = binding.value?.text ?? binding.value ?? _props?.text;\n const value = isObject(binding.value) ? binding.value : {};\n\n // Get the children from the props or directive value, or the element's children\n const children = () => text ?? el.textContent;\n\n // If vnode.ctx is the same as the instance, then we're bound to a plain element\n // and need to find the nearest parent component instance to inherit provides from\n const provides = (vnode.ctx === binding.instance.$ ? findComponentParent(vnode, binding.instance.$)?.provides : vnode.ctx?.provides) ?? binding.instance.$.provides;\n const node = h(component, mergeProps(_props, value), children);\n node.appContext = Object.assign(Object.create(null), binding.instance.$.appContext, {\n provides\n });\n render(node, el);\n };\n}\nfunction findComponentParent(vnode, root) {\n // Walk the tree from root until we find the child vnode\n const stack = new Set();\n const walk = children => {\n for (const child of children) {\n if (!child) continue;\n if (child === vnode || child.el && vnode.el && child.el === vnode.el) {\n return true;\n }\n stack.add(child);\n let result;\n if (child.suspense) {\n result = walk([child.ssContent]);\n } else if (Array.isArray(child.children)) {\n result = walk(child.children);\n } else if (child.component?.vnode) {\n result = walk([child.component?.subTree]);\n }\n if (result) {\n return result;\n }\n stack.delete(child);\n }\n return false;\n };\n if (!walk([root.subTree])) {\n consoleError('Could not find original vnode, component will not inherit provides');\n return root;\n }\n\n // Return the first component parent\n const result = Array.from(stack).reverse();\n for (const child of result) {\n if (child.component) {\n return child.component;\n }\n }\n return root;\n}\n//# sourceMappingURL=directiveComponent.js.map","// Components\nimport { VTooltip } from \"../../components/VTooltip/index.js\"; // Composables\nimport { useDirectiveComponent } from \"../../composables/directiveComponent.js\"; // Utilities\nimport { isObject } from \"../../util/index.js\"; // Types\nexport const Tooltip = useDirectiveComponent(VTooltip, binding => {\n const disabled = isObject(binding.value) ? !binding.value.text : ['', false, null].includes(binding.value); // undefined means true\n\n return {\n activator: disabled ? null : 'parent',\n location: binding.arg?.replace('-', ' '),\n text: typeof binding.value === 'boolean' ? undefined : binding.value\n };\n});\nexport default Tooltip;\n//# sourceMappingURL=index.js.map"],"x_google_ignoreList":[0,1,2,3],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { o as VSvgIcon } from "./icons-ze2hmg7j.js";
|
|
2
|
+
//#region ../../../../node_modules/vuetify/lib/iconsets/mdi-svg.js
|
|
3
|
+
var aliases = {
|
|
4
|
+
collapse: "svg:M7.41,15.41L12,10.83L16.59,15.41L18,14L12,8L6,14L7.41,15.41Z",
|
|
5
|
+
complete: "svg:M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z",
|
|
6
|
+
cancel: "svg:M12,2C17.53,2 22,6.47 22,12C22,17.53 17.53,22 12,22C6.47,22 2,17.53 2,12C2,6.47 6.47,2 12,2M15.59,7L12,10.59L8.41,7L7,8.41L10.59,12L7,15.59L8.41,17L12,13.41L15.59,17L17,15.59L13.41,12L17,8.41L15.59,7Z",
|
|
7
|
+
close: "svg:M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z",
|
|
8
|
+
delete: "svg:M12,2C17.53,2 22,6.47 22,12C22,17.53 17.53,22 12,22C6.47,22 2,17.53 2,12C2,6.47 6.47,2 12,2M15.59,7L12,10.59L8.41,7L7,8.41L10.59,12L7,15.59L8.41,17L12,13.41L15.59,17L17,15.59L13.41,12L17,8.41L15.59,7Z",
|
|
9
|
+
clear: "svg:M12,2C17.53,2 22,6.47 22,12C22,17.53 17.53,22 12,22C6.47,22 2,17.53 2,12C2,6.47 6.47,2 12,2M15.59,7L12,10.59L8.41,7L7,8.41L10.59,12L7,15.59L8.41,17L12,13.41L15.59,17L17,15.59L13.41,12L17,8.41L15.59,7Z",
|
|
10
|
+
success: "svg:M12,2C17.52,2 22,6.48 22,12C22,17.52 17.52,22 12,22C6.48,22 2,17.52 2,12C2,6.48 6.48,2 12,2M11,16.5L18,9.5L16.59,8.09L11,13.67L7.91,10.59L6.5,12L11,16.5Z",
|
|
11
|
+
info: "svg:M13,9H11V7H13M13,17H11V11H13M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2Z",
|
|
12
|
+
warning: "svg:M13,13H11V7H13M13,17H11V15H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z",
|
|
13
|
+
error: "svg:M12,2C17.53,2 22,6.47 22,12C22,17.53 17.53,22 12,22C6.47,22 2,17.53 2,12C2,6.47 6.47,2 12,2M15.59,7L12,10.59L8.41,7L7,8.41L10.59,12L7,15.59L8.41,17L12,13.41L15.59,17L17,15.59L13.41,12L17,8.41L15.59,7Z",
|
|
14
|
+
prev: "svg:M15.41,16.58L10.83,12L15.41,7.41L14,6L8,12L14,18L15.41,16.58Z",
|
|
15
|
+
next: "svg:M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z",
|
|
16
|
+
checkboxOn: "svg:M10,17L5,12L6.41,10.58L10,14.17L17.59,6.58L19,8M19,3H5C3.89,3 3,3.89 3,5V19C3,20.1 3.9,21 5,21H19C20.1,21 21,20.1 21,19V5C21,3.89 20.1,3 19,3Z",
|
|
17
|
+
checkboxOff: "svg:M19,3H5C3.89,3 3,3.89 3,5V19C3,20.1 3.9,21 5,21H19C20.1,21 21,20.1 21,19V5C21,3.89 20.1,3 19,3M19,5V19H5V5H19Z",
|
|
18
|
+
checkboxIndeterminate: "svg:M17,13H7V11H17M19,3H5C3.89,3 3,3.89 3,5V19C3,20.1 3.9,21 5,21H19C20.1,21 21,20.1 21,19V5C21,3.89 20.1,3 19,3Z",
|
|
19
|
+
delimiter: "svg:M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2Z",
|
|
20
|
+
sortAsc: "svg:M13,20H11V8L5.5,13.5L4.08,12.08L12,4.16L19.92,12.08L18.5,13.5L13,8V20Z",
|
|
21
|
+
sortDesc: "svg:M11,4H13V16L18.5,10.5L19.92,11.92L12,19.84L4.08,11.92L5.5,10.5L11,16V4Z",
|
|
22
|
+
expand: "svg:M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z",
|
|
23
|
+
menu: "svg:M3,6H21V8H3V6M3,11H21V13H3V11M3,16H21V18H3V16Z",
|
|
24
|
+
subgroup: "svg:M7,10L12,15L17,10H7Z",
|
|
25
|
+
dropdown: "svg:M7,10L12,15L17,10H7Z",
|
|
26
|
+
radioOn: "svg:M12,20C7.58,20 4,16.42 4,12C4,7.58 7.58,4 12,4C16.42,4 20,7.58 20,12C20,16.42 16.42,20 12,20M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2M12,7C9.24,7 7,9.24 7,12C7,14.76 9.24,17 12,17C14.76,17 17,14.76 17,12C17,9.24 14.76,7 12,7Z",
|
|
27
|
+
radioOff: "svg:M12,20C7.58,20 4,16.42 4,12C4,7.58 7.58,4 12,4C16.42,4 20,7.58 20,12C20,16.42 16.42,20 12,20M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2Z",
|
|
28
|
+
edit: "svg:M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z",
|
|
29
|
+
ratingEmpty: "svg:M12,15.39L8.24,17.66L9.23,13.38L5.91,10.5L10.29,10.13L12,6.09L13.71,10.13L18.09,10.5L14.77,13.38L15.76,17.66M22,9.24L14.81,8.63L12,2L9.19,8.63L2,9.24L7.45,13.97L5.82,21L12,17.27L18.18,21L16.54,13.97L22,9.24Z",
|
|
30
|
+
ratingFull: "svg:M12,17.27L18.18,21L16.54,13.97L22,9.24L14.81,8.62L12,2L9.19,8.62L2,9.24L7.45,13.97L5.82,21L12,17.27Z",
|
|
31
|
+
ratingHalf: "svg:M12,15.4V6.1L13.71,10.13L18.09,10.5L14.77,13.39L15.76,17.67M22,9.24L14.81,8.63L12,2L9.19,8.63L2,9.24L7.45,13.97L5.82,21L12,17.27L18.18,21L16.54,13.97L22,9.24Z",
|
|
32
|
+
loading: "svg:M19,8L15,12H18C18,15.31 15.31,18 12,18C11,18 10.03,17.75 9.2,17.3L7.74,18.76C8.97,19.54 10.43,20 12,20C16.42,20 20,16.42 20,12H23M6,12C6,8.69 8.69,6 12,6C13,6 13.97,6.25 14.8,6.7L16.26,5.24C15.03,4.46 13.57,4 12,4C7.58,4 4,7.58 4,12H1L5,16L9,12",
|
|
33
|
+
first: "svg:M18.41,16.59L13.82,12L18.41,7.41L17,6L11,12L17,18L18.41,16.59M6,6H8V18H6V6Z",
|
|
34
|
+
last: "svg:M5.59,7.41L10.18,12L5.59,16.59L7,18L13,12L7,6L5.59,7.41M16,6H18V18H16V6Z",
|
|
35
|
+
unfold: "svg:M12,18.17L8.83,15L7.42,16.41L12,21L16.59,16.41L15.17,15M12,5.83L15.17,9L16.58,7.59L12,3L7.41,7.59L8.83,9L12,5.83Z",
|
|
36
|
+
file: "svg:M16.5,6V17.5C16.5,19.71 14.71,21.5 12.5,21.5C10.29,21.5 8.5,19.71 8.5,17.5V5C8.5,3.62 9.62,2.5 11,2.5C12.38,2.5 13.5,3.62 13.5,5V15.5C13.5,16.05 13.05,16.5 12.5,16.5C11.95,16.5 11.5,16.05 11.5,15.5V6H10V15.5C10,16.88 11.12,18 12.5,18C13.88,18 15,16.88 15,15.5V5C15,2.79 13.21,1 11,1C8.79,1 7,2.79 7,5V17.5C7,20.54 9.46,23 12.5,23C15.54,23 18,20.54 18,17.5V6H16.5Z",
|
|
37
|
+
plus: "svg:M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z",
|
|
38
|
+
minus: "svg:M19,13H5V11H19V13Z",
|
|
39
|
+
calendar: "svg:M19,19H5V8H19M16,1V3H8V1H6V3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3H18V1M17,12H12V17H17V12Z",
|
|
40
|
+
treeviewCollapse: "svg:M7,10L12,15L17,10H7Z",
|
|
41
|
+
treeviewExpand: "svg:M10,17L15,12L10,7V17Z",
|
|
42
|
+
tableGroupExpand: "svg:M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z",
|
|
43
|
+
tableGroupCollapse: "svg:M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z",
|
|
44
|
+
eyeDropper: "svg:M19.35,11.72L17.22,13.85L15.81,12.43L8.1,20.14L3.5,22L2,20.5L3.86,15.9L11.57,8.19L10.15,6.78L12.28,4.65L19.35,11.72M16.76,3C17.93,1.83 19.83,1.83 21,3C22.17,4.17 22.17,6.07 21,7.24L19.08,9.16L14.84,4.92L16.76,3M5.56,17.03L4.5,19.5L6.97,18.44L14.4,11L13,9.6L5.56,17.03Z",
|
|
45
|
+
upload: "svg:M11 20H6.5q-2.28 0-3.89-1.57Q1 16.85 1 14.58q0-1.95 1.17-3.48q1.18-1.53 3.08-1.95q.63-2.3 2.5-3.72Q9.63 4 12 4q2.93 0 4.96 2.04Q19 8.07 19 11q1.73.2 2.86 1.5q1.14 1.28 1.14 3q0 1.88-1.31 3.19T18.5 20H13v-7.15l1.6 1.55L16 13l-4-4l-4 4l1.4 1.4l1.6-1.55Z",
|
|
46
|
+
color: "svg:M17.5 12a1.5 1.5 0 0 1-1.5-1.5A1.5 1.5 0 0 1 17.5 9a1.5 1.5 0 0 1 1.5 1.5a1.5 1.5 0 0 1-1.5 1.5m-3-4A1.5 1.5 0 0 1 13 6.5A1.5 1.5 0 0 1 14.5 5A1.5 1.5 0 0 1 16 6.5A1.5 1.5 0 0 1 14.5 8m-5 0A1.5 1.5 0 0 1 8 6.5A1.5 1.5 0 0 1 9.5 5A1.5 1.5 0 0 1 11 6.5A1.5 1.5 0 0 1 9.5 8m-3 4A1.5 1.5 0 0 1 5 10.5A1.5 1.5 0 0 1 6.5 9A1.5 1.5 0 0 1 8 10.5A1.5 1.5 0 0 1 6.5 12M12 3a9 9 0 0 0-9 9a9 9 0 0 0 9 9a1.5 1.5 0 0 0 1.5-1.5c0-.39-.15-.74-.39-1c-.23-.27-.38-.62-.38-1a1.5 1.5 0 0 1 1.5-1.5H16a5 5 0 0 0 5-5c0-4.42-4.03-8-9-8",
|
|
47
|
+
command: "svg:M6,2A4,4 0 0,1 10,6V8H14V6A4,4 0 0,1 18,2A4,4 0 0,1 22,6A4,4 0 0,1 18,10H16V14H18A4,4 0 0,1 22,18A4,4 0 0,1 18,22A4,4 0 0,1 14,18V16H10V18A4,4 0 0,1 6,22A4,4 0 0,1 2,18A4,4 0 0,1 6,14H8V10H6A4,4 0 0,1 2,6A4,4 0 0,1 6,2M16,18A2,2 0 0,0 18,20A2,2 0 0,0 20,18A2,2 0 0,0 18,16H16V18M14,10H10V14H14V10M6,16A2,2 0 0,0 4,18A2,2 0 0,0 6,20A2,2 0 0,0 8,18V16H6M8,6A2,2 0 0,0 6,4A2,2 0 0,0 4,6A2,2 0 0,0 6,8H8V6M18,8A2,2 0 0,0 20,6A2,2 0 0,0 18,4A2,2 0 0,0 16,6V8H18Z",
|
|
48
|
+
ctrl: "svg:M19.78,11.78L18.36,13.19L12,6.83L5.64,13.19L4.22,11.78L12,4L19.78,11.78Z",
|
|
49
|
+
space: "svg:M3 15H5V19H19V15H21V19C21 20.1 20.1 21 19 21H5C3.9 21 3 20.1 3 19V15Z",
|
|
50
|
+
shift: "svg:M15 18v-6h2.17L12 6.83L6.83 12H9v6zM12 4l10 10h-5v6H7v-6H2z",
|
|
51
|
+
alt: "svg:M3 4h6.11l7.04 14H21v2h-6.12L7.84 6H3zm11 0h7v2h-7z",
|
|
52
|
+
enter: "svg:M19 7v4H5.83l3.58-3.59L8 6l-6 6l6 6l1.41-1.42L5.83 13H21V7z",
|
|
53
|
+
arrowup: "svg:M13 20h-2V8l-5.5 5.5l-1.42-1.42L12 4.16l7.92 7.92l-1.42 1.42L13 8z",
|
|
54
|
+
arrowdown: "svg:M11 4h2v12l5.5-5.5l1.42 1.42L12 19.84l-7.92-7.92L5.5 10.5L11 16z",
|
|
55
|
+
arrowleft: "svg:M20 11v2H8l5.5 5.5l-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5L8 11z",
|
|
56
|
+
arrowright: "svg:M4 11v2h12l-5.5 5.5l1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5L16 11z",
|
|
57
|
+
backspace: "svg:M19 15.59L17.59 17L14 13.41L10.41 17L9 15.59L12.59 12L9 8.41L10.41 7L14 10.59L17.59 7L19 8.41L15.41 12zM22 3a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H7c-.69 0-1.23-.36-1.59-.89L0 12l5.41-8.12C5.77 3.35 6.31 3 7 3zm0 2H7l-4.72 7L7 19h15z",
|
|
58
|
+
play: "svg:M8,5.14V19.14L19,12.14L8,5.14Z",
|
|
59
|
+
pause: "svg:M14,19H18V5H14M6,19H10V5H6V19Z",
|
|
60
|
+
fullscreen: "svg:M5,5H10V7H7V10H5V5M14,5H19V10H17V7H14V5M17,14H19V19H14V17H17V14M10,17V19H5V14H7V17H10Z",
|
|
61
|
+
fullscreenExit: "svg:M14,14H19V16H16V19H14V14M5,14H10V19H8V16H5V14M8,5H10V10H5V8H8V5M19,8V10H14V5H16V8H19Z",
|
|
62
|
+
volumeHigh: "svg:M14,3.23V5.29C16.89,6.15 19,8.83 19,12C19,15.17 16.89,17.84 14,18.7V20.77C18,19.86 21,16.28 21,12C21,7.72 18,4.14 14,3.23M16.5,12C16.5,10.23 15.5,8.71 14,7.97V16C15.5,15.29 16.5,13.76 16.5,12M3,9V15H7L12,20V4L7,9H3Z",
|
|
63
|
+
volumeMedium: "svg:M5,9V15H9L14,20V4L9,9M18.5,12C18.5,10.23 17.5,8.71 16,7.97V16C17.5,15.29 18.5,13.76 18.5,12Z",
|
|
64
|
+
volumeLow: "svg:M7,9V15H11L16,20V4L11,9H7Z",
|
|
65
|
+
volumeOff: "svg:M5.64,3.64L21.36,19.36L19.95,20.78L16,16.83V20L11,15H7V9H8.17L4.22,5.05L5.64,3.64M16,4V11.17L12.41,7.58L16,4Z",
|
|
66
|
+
search: "svg:M9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z"
|
|
67
|
+
};
|
|
68
|
+
var mdi = { component: VSvgIcon };
|
|
69
|
+
//#endregion
|
|
70
|
+
export { aliases, mdi };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vuetify_iconsets_mdi-svg.js","names":[],"sources":["../../../../../../../node_modules/vuetify/lib/iconsets/mdi-svg.js"],"sourcesContent":["/* eslint-disable max-len */\n// Composables\nimport { VSvgIcon } from \"../composables/icons.js\"; // Types\nconst aliases = {\n collapse: 'svg:M7.41,15.41L12,10.83L16.59,15.41L18,14L12,8L6,14L7.41,15.41Z',\n complete: 'svg:M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z',\n cancel: 'svg:M12,2C17.53,2 22,6.47 22,12C22,17.53 17.53,22 12,22C6.47,22 2,17.53 2,12C2,6.47 6.47,2 12,2M15.59,7L12,10.59L8.41,7L7,8.41L10.59,12L7,15.59L8.41,17L12,13.41L15.59,17L17,15.59L13.41,12L17,8.41L15.59,7Z',\n close: 'svg:M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z',\n delete: 'svg:M12,2C17.53,2 22,6.47 22,12C22,17.53 17.53,22 12,22C6.47,22 2,17.53 2,12C2,6.47 6.47,2 12,2M15.59,7L12,10.59L8.41,7L7,8.41L10.59,12L7,15.59L8.41,17L12,13.41L15.59,17L17,15.59L13.41,12L17,8.41L15.59,7Z',\n // delete (e.g. v-chip close)\n clear: 'svg:M12,2C17.53,2 22,6.47 22,12C22,17.53 17.53,22 12,22C6.47,22 2,17.53 2,12C2,6.47 6.47,2 12,2M15.59,7L12,10.59L8.41,7L7,8.41L10.59,12L7,15.59L8.41,17L12,13.41L15.59,17L17,15.59L13.41,12L17,8.41L15.59,7Z',\n success: 'svg:M12,2C17.52,2 22,6.48 22,12C22,17.52 17.52,22 12,22C6.48,22 2,17.52 2,12C2,6.48 6.48,2 12,2M11,16.5L18,9.5L16.59,8.09L11,13.67L7.91,10.59L6.5,12L11,16.5Z',\n info: 'svg:M13,9H11V7H13M13,17H11V11H13M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2Z',\n warning: 'svg:M13,13H11V7H13M13,17H11V15H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z',\n error: 'svg:M12,2C17.53,2 22,6.47 22,12C22,17.53 17.53,22 12,22C6.47,22 2,17.53 2,12C2,6.47 6.47,2 12,2M15.59,7L12,10.59L8.41,7L7,8.41L10.59,12L7,15.59L8.41,17L12,13.41L15.59,17L17,15.59L13.41,12L17,8.41L15.59,7Z',\n prev: 'svg:M15.41,16.58L10.83,12L15.41,7.41L14,6L8,12L14,18L15.41,16.58Z',\n next: 'svg:M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z',\n checkboxOn: 'svg:M10,17L5,12L6.41,10.58L10,14.17L17.59,6.58L19,8M19,3H5C3.89,3 3,3.89 3,5V19C3,20.1 3.9,21 5,21H19C20.1,21 21,20.1 21,19V5C21,3.89 20.1,3 19,3Z',\n checkboxOff: 'svg:M19,3H5C3.89,3 3,3.89 3,5V19C3,20.1 3.9,21 5,21H19C20.1,21 21,20.1 21,19V5C21,3.89 20.1,3 19,3M19,5V19H5V5H19Z',\n checkboxIndeterminate: 'svg:M17,13H7V11H17M19,3H5C3.89,3 3,3.89 3,5V19C3,20.1 3.9,21 5,21H19C20.1,21 21,20.1 21,19V5C21,3.89 20.1,3 19,3Z',\n delimiter: 'svg:M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2Z',\n // for carousel\n sortAsc: 'svg:M13,20H11V8L5.5,13.5L4.08,12.08L12,4.16L19.92,12.08L18.5,13.5L13,8V20Z',\n sortDesc: 'svg:M11,4H13V16L18.5,10.5L19.92,11.92L12,19.84L4.08,11.92L5.5,10.5L11,16V4Z',\n expand: 'svg:M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z',\n menu: 'svg:M3,6H21V8H3V6M3,11H21V13H3V11M3,16H21V18H3V16Z',\n subgroup: 'svg:M7,10L12,15L17,10H7Z',\n dropdown: 'svg:M7,10L12,15L17,10H7Z',\n radioOn: 'svg:M12,20C7.58,20 4,16.42 4,12C4,7.58 7.58,4 12,4C16.42,4 20,7.58 20,12C20,16.42 16.42,20 12,20M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2M12,7C9.24,7 7,9.24 7,12C7,14.76 9.24,17 12,17C14.76,17 17,14.76 17,12C17,9.24 14.76,7 12,7Z',\n radioOff: 'svg:M12,20C7.58,20 4,16.42 4,12C4,7.58 7.58,4 12,4C16.42,4 20,7.58 20,12C20,16.42 16.42,20 12,20M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2Z',\n edit: 'svg:M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z',\n ratingEmpty: 'svg:M12,15.39L8.24,17.66L9.23,13.38L5.91,10.5L10.29,10.13L12,6.09L13.71,10.13L18.09,10.5L14.77,13.38L15.76,17.66M22,9.24L14.81,8.63L12,2L9.19,8.63L2,9.24L7.45,13.97L5.82,21L12,17.27L18.18,21L16.54,13.97L22,9.24Z',\n ratingFull: 'svg:M12,17.27L18.18,21L16.54,13.97L22,9.24L14.81,8.62L12,2L9.19,8.62L2,9.24L7.45,13.97L5.82,21L12,17.27Z',\n ratingHalf: 'svg:M12,15.4V6.1L13.71,10.13L18.09,10.5L14.77,13.39L15.76,17.67M22,9.24L14.81,8.63L12,2L9.19,8.63L2,9.24L7.45,13.97L5.82,21L12,17.27L18.18,21L16.54,13.97L22,9.24Z',\n loading: 'svg:M19,8L15,12H18C18,15.31 15.31,18 12,18C11,18 10.03,17.75 9.2,17.3L7.74,18.76C8.97,19.54 10.43,20 12,20C16.42,20 20,16.42 20,12H23M6,12C6,8.69 8.69,6 12,6C13,6 13.97,6.25 14.8,6.7L16.26,5.24C15.03,4.46 13.57,4 12,4C7.58,4 4,7.58 4,12H1L5,16L9,12',\n first: 'svg:M18.41,16.59L13.82,12L18.41,7.41L17,6L11,12L17,18L18.41,16.59M6,6H8V18H6V6Z',\n last: 'svg:M5.59,7.41L10.18,12L5.59,16.59L7,18L13,12L7,6L5.59,7.41M16,6H18V18H16V6Z',\n unfold: 'svg:M12,18.17L8.83,15L7.42,16.41L12,21L16.59,16.41L15.17,15M12,5.83L15.17,9L16.58,7.59L12,3L7.41,7.59L8.83,9L12,5.83Z',\n file: 'svg:M16.5,6V17.5C16.5,19.71 14.71,21.5 12.5,21.5C10.29,21.5 8.5,19.71 8.5,17.5V5C8.5,3.62 9.62,2.5 11,2.5C12.38,2.5 13.5,3.62 13.5,5V15.5C13.5,16.05 13.05,16.5 12.5,16.5C11.95,16.5 11.5,16.05 11.5,15.5V6H10V15.5C10,16.88 11.12,18 12.5,18C13.88,18 15,16.88 15,15.5V5C15,2.79 13.21,1 11,1C8.79,1 7,2.79 7,5V17.5C7,20.54 9.46,23 12.5,23C15.54,23 18,20.54 18,17.5V6H16.5Z',\n plus: 'svg:M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z',\n minus: 'svg:M19,13H5V11H19V13Z',\n calendar: 'svg:M19,19H5V8H19M16,1V3H8V1H6V3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3H18V1M17,12H12V17H17V12Z',\n treeviewCollapse: 'svg:M7,10L12,15L17,10H7Z',\n treeviewExpand: 'svg:M10,17L15,12L10,7V17Z',\n tableGroupExpand: 'svg:M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z',\n tableGroupCollapse: 'svg:M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z',\n eyeDropper: 'svg:M19.35,11.72L17.22,13.85L15.81,12.43L8.1,20.14L3.5,22L2,20.5L3.86,15.9L11.57,8.19L10.15,6.78L12.28,4.65L19.35,11.72M16.76,3C17.93,1.83 19.83,1.83 21,3C22.17,4.17 22.17,6.07 21,7.24L19.08,9.16L14.84,4.92L16.76,3M5.56,17.03L4.5,19.5L6.97,18.44L14.4,11L13,9.6L5.56,17.03Z',\n upload: 'svg:M11 20H6.5q-2.28 0-3.89-1.57Q1 16.85 1 14.58q0-1.95 1.17-3.48q1.18-1.53 3.08-1.95q.63-2.3 2.5-3.72Q9.63 4 12 4q2.93 0 4.96 2.04Q19 8.07 19 11q1.73.2 2.86 1.5q1.14 1.28 1.14 3q0 1.88-1.31 3.19T18.5 20H13v-7.15l1.6 1.55L16 13l-4-4l-4 4l1.4 1.4l1.6-1.55Z',\n color: 'svg:M17.5 12a1.5 1.5 0 0 1-1.5-1.5A1.5 1.5 0 0 1 17.5 9a1.5 1.5 0 0 1 1.5 1.5a1.5 1.5 0 0 1-1.5 1.5m-3-4A1.5 1.5 0 0 1 13 6.5A1.5 1.5 0 0 1 14.5 5A1.5 1.5 0 0 1 16 6.5A1.5 1.5 0 0 1 14.5 8m-5 0A1.5 1.5 0 0 1 8 6.5A1.5 1.5 0 0 1 9.5 5A1.5 1.5 0 0 1 11 6.5A1.5 1.5 0 0 1 9.5 8m-3 4A1.5 1.5 0 0 1 5 10.5A1.5 1.5 0 0 1 6.5 9A1.5 1.5 0 0 1 8 10.5A1.5 1.5 0 0 1 6.5 12M12 3a9 9 0 0 0-9 9a9 9 0 0 0 9 9a1.5 1.5 0 0 0 1.5-1.5c0-.39-.15-.74-.39-1c-.23-.27-.38-.62-.38-1a1.5 1.5 0 0 1 1.5-1.5H16a5 5 0 0 0 5-5c0-4.42-4.03-8-9-8',\n command: 'svg:M6,2A4,4 0 0,1 10,6V8H14V6A4,4 0 0,1 18,2A4,4 0 0,1 22,6A4,4 0 0,1 18,10H16V14H18A4,4 0 0,1 22,18A4,4 0 0,1 18,22A4,4 0 0,1 14,18V16H10V18A4,4 0 0,1 6,22A4,4 0 0,1 2,18A4,4 0 0,1 6,14H8V10H6A4,4 0 0,1 2,6A4,4 0 0,1 6,2M16,18A2,2 0 0,0 18,20A2,2 0 0,0 20,18A2,2 0 0,0 18,16H16V18M14,10H10V14H14V10M6,16A2,2 0 0,0 4,18A2,2 0 0,0 6,20A2,2 0 0,0 8,18V16H6M8,6A2,2 0 0,0 6,4A2,2 0 0,0 4,6A2,2 0 0,0 6,8H8V6M18,8A2,2 0 0,0 20,6A2,2 0 0,0 18,4A2,2 0 0,0 16,6V8H18Z',\n ctrl: 'svg:M19.78,11.78L18.36,13.19L12,6.83L5.64,13.19L4.22,11.78L12,4L19.78,11.78Z',\n space: 'svg:M3 15H5V19H19V15H21V19C21 20.1 20.1 21 19 21H5C3.9 21 3 20.1 3 19V15Z',\n shift: 'svg:M15 18v-6h2.17L12 6.83L6.83 12H9v6zM12 4l10 10h-5v6H7v-6H2z',\n alt: 'svg:M3 4h6.11l7.04 14H21v2h-6.12L7.84 6H3zm11 0h7v2h-7z',\n enter: 'svg:M19 7v4H5.83l3.58-3.59L8 6l-6 6l6 6l1.41-1.42L5.83 13H21V7z',\n arrowup: 'svg:M13 20h-2V8l-5.5 5.5l-1.42-1.42L12 4.16l7.92 7.92l-1.42 1.42L13 8z',\n arrowdown: 'svg:M11 4h2v12l5.5-5.5l1.42 1.42L12 19.84l-7.92-7.92L5.5 10.5L11 16z',\n arrowleft: 'svg:M20 11v2H8l5.5 5.5l-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5L8 11z',\n arrowright: 'svg:M4 11v2h12l-5.5 5.5l1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5L16 11z',\n backspace: 'svg:M19 15.59L17.59 17L14 13.41L10.41 17L9 15.59L12.59 12L9 8.41L10.41 7L14 10.59L17.59 7L19 8.41L15.41 12zM22 3a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H7c-.69 0-1.23-.36-1.59-.89L0 12l5.41-8.12C5.77 3.35 6.31 3 7 3zm0 2H7l-4.72 7L7 19h15z',\n play: 'svg:M8,5.14V19.14L19,12.14L8,5.14Z',\n pause: 'svg:M14,19H18V5H14M6,19H10V5H6V19Z',\n fullscreen: 'svg:M5,5H10V7H7V10H5V5M14,5H19V10H17V7H14V5M17,14H19V19H14V17H17V14M10,17V19H5V14H7V17H10Z',\n fullscreenExit: 'svg:M14,14H19V16H16V19H14V14M5,14H10V19H8V16H5V14M8,5H10V10H5V8H8V5M19,8V10H14V5H16V8H19Z',\n volumeHigh: 'svg:M14,3.23V5.29C16.89,6.15 19,8.83 19,12C19,15.17 16.89,17.84 14,18.7V20.77C18,19.86 21,16.28 21,12C21,7.72 18,4.14 14,3.23M16.5,12C16.5,10.23 15.5,8.71 14,7.97V16C15.5,15.29 16.5,13.76 16.5,12M3,9V15H7L12,20V4L7,9H3Z',\n volumeMedium: 'svg:M5,9V15H9L14,20V4L9,9M18.5,12C18.5,10.23 17.5,8.71 16,7.97V16C17.5,15.29 18.5,13.76 18.5,12Z',\n volumeLow: 'svg:M7,9V15H11L16,20V4L11,9H7Z',\n volumeOff: 'svg:M5.64,3.64L21.36,19.36L19.95,20.78L16,16.83V20L11,15H7V9H8.17L4.22,5.05L5.64,3.64M16,4V11.17L12.41,7.58L16,4Z',\n search: 'svg:M9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z'\n};\nconst mdi = {\n component: VSvgIcon\n};\nexport { aliases, mdi };\n//# sourceMappingURL=mdi-svg.js.map"],"x_google_ignoreList":[0],"mappings":";;AAGA,IAAM,UAAU;CACd,UAAU;CACV,UAAU;CACV,QAAQ;CACR,OAAO;CACP,QAAQ;CAER,OAAO;CACP,SAAS;CACT,MAAM;CACN,SAAS;CACT,OAAO;CACP,MAAM;CACN,MAAM;CACN,YAAY;CACZ,aAAa;CACb,uBAAuB;CACvB,WAAW;CAEX,SAAS;CACT,UAAU;CACV,QAAQ;CACR,MAAM;CACN,UAAU;CACV,UAAU;CACV,SAAS;CACT,UAAU;CACV,MAAM;CACN,aAAa;CACb,YAAY;CACZ,YAAY;CACZ,SAAS;CACT,OAAO;CACP,MAAM;CACN,QAAQ;CACR,MAAM;CACN,MAAM;CACN,OAAO;CACP,UAAU;CACV,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,oBAAoB;CACpB,YAAY;CACZ,QAAQ;CACR,OAAO;CACP,SAAS;CACT,MAAM;CACN,OAAO;CACP,OAAO;CACP,KAAK;CACL,OAAO;CACP,SAAS;CACT,WAAW;CACX,WAAW;CACX,YAAY;CACZ,WAAW;CACX,MAAM;CACN,OAAO;CACP,YAAY;CACZ,gBAAgB;CAChB,YAAY;CACZ,cAAc;CACd,WAAW;CACX,WAAW;CACX,QAAQ;AACV;AACA,IAAM,MAAM,EACV,WAAW,SACb"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "assistant-conversation-example",
|
|
3
|
+
"private": true,
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "vite --host=127.0.0.1 --port=5175 --strictPort",
|
|
7
|
+
"server": "node server.js",
|
|
8
|
+
"build": "vite build"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@jskit-ai/assistant-core": "0.1.166",
|
|
12
|
+
"@jskit-ai/http-runtime": "0.1.188",
|
|
13
|
+
"@jskit-ai/kernel": "0.1.190",
|
|
14
|
+
"@mdi/js": "^7.4.47",
|
|
15
|
+
"vue": "^3.5.13",
|
|
16
|
+
"vuetify": "^4.0.0"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@vitejs/plugin-vue": "^6.0.7",
|
|
20
|
+
"vite": "^8.2.1"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { createServer } from "node:http";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
4
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
5
|
+
import { createAiClient } from "@jskit-ai/assistant-core/server";
|
|
6
|
+
import { createConversationTranscript, createMemoryConversationStorage } from "@jskit-ai/assistant-core/server/conversation";
|
|
7
|
+
|
|
8
|
+
// This template is a single-user local application. A hosted app derives scope
|
|
9
|
+
// from authenticated actor/workspace/conversation ownership on every operation.
|
|
10
|
+
const scope = "example:local-user:conversation";
|
|
11
|
+
const storage = process.env.ASSISTANT_STORAGE_MODULE
|
|
12
|
+
? await (await import(pathToFileURL(resolve(process.env.ASSISTANT_STORAGE_MODULE)).href)).createStorage()
|
|
13
|
+
: createMemoryConversationStorage();
|
|
14
|
+
const transcript = createConversationTranscript({ storage });
|
|
15
|
+
const configurationMode = process.env.ASSISTANT_CONFIGURATION_MODE || "editable";
|
|
16
|
+
if (!["hidden", "readonly", "editable"].includes(configurationMode)) throw new Error("Invalid configuration mode.");
|
|
17
|
+
const fixedConfiguration = Object.freeze({ tone: "concise" });
|
|
18
|
+
const ai = process.env.ASSISTANT_API_KEY ? createAiClient({
|
|
19
|
+
provider: process.env.ASSISTANT_PROVIDER || "openai", apiKey: process.env.ASSISTANT_API_KEY,
|
|
20
|
+
model: process.env.ASSISTANT_MODEL
|
|
21
|
+
}) : null;
|
|
22
|
+
let active = null;
|
|
23
|
+
|
|
24
|
+
function configurationFor(input) {
|
|
25
|
+
if (configurationMode !== "editable") return fixedConfiguration;
|
|
26
|
+
if (!input || Object.keys(input).some((key) => key !== "tone") || !["concise", "detailed"].includes(input.tone)) {
|
|
27
|
+
throw new Error("Choose a supported answer style.");
|
|
28
|
+
}
|
|
29
|
+
return { tone: input.tone };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function* reply(messages, configuration, signal) {
|
|
33
|
+
if (ai) {
|
|
34
|
+
const stream = await ai.createChatCompletionStream({ signal, messages: [
|
|
35
|
+
{ role: "system", content: `Answer in a ${configuration.tone} style.` }, ...messages
|
|
36
|
+
] });
|
|
37
|
+
for await (const chunk of stream) {
|
|
38
|
+
const text = chunk.choices?.[0]?.delta?.content;
|
|
39
|
+
if (text) yield text;
|
|
40
|
+
}
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const answer = `This is the **demo provider**. Your message was:\n\n${messages.at(-1).content}\n\nThe application supplies the provider and storage; JSKIT supplies the conversation UI and transcript behavior.`;
|
|
44
|
+
for (const word of answer.match(/\S+\s*/g) || []) {
|
|
45
|
+
await delay(35, undefined, { signal });
|
|
46
|
+
yield word;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function body(request) {
|
|
51
|
+
if (!request.headers["content-type"]?.startsWith("application/json")) throw new Error("Expected JSON.");
|
|
52
|
+
let text = "";
|
|
53
|
+
for await (const chunk of request) {
|
|
54
|
+
text += chunk;
|
|
55
|
+
if (Buffer.byteLength(text) > 16_384) throw new Error("Message is too large.");
|
|
56
|
+
}
|
|
57
|
+
return JSON.parse(text);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function json(response, status, value) {
|
|
61
|
+
response.writeHead(status, { "Content-Type": "application/json", "Cache-Control": "no-store" });
|
|
62
|
+
response.end(JSON.stringify(value));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
createServer(async (request, response) => {
|
|
66
|
+
try {
|
|
67
|
+
if (request.method === "GET" && request.url === "/api/conversation") {
|
|
68
|
+
json(response, 200, { turns: await transcript.readConversationLog(scope), configurationMode,
|
|
69
|
+
configuration: fixedConfiguration, providerLabel: ai ? `${ai.provider} · ${ai.defaultModel}` : "Demo provider · transient storage" });
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (request.method === "DELETE" && request.url === "/api/run") {
|
|
73
|
+
active?.abort();
|
|
74
|
+
json(response, 200, { stopped: true });
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (request.method !== "POST" || request.url !== "/api/messages") { json(response, 404, { error: "Not found." }); return; }
|
|
78
|
+
const input = await body(request);
|
|
79
|
+
if (typeof input.text !== "string" || !input.text.trim() || input.text.length > 8000 ||
|
|
80
|
+
typeof input.messageId !== "string" || !/^[A-Za-z0-9_-]{1,128}$/.test(input.messageId)) throw new Error("Invalid message.");
|
|
81
|
+
const configuration = configurationFor(input.configuration);
|
|
82
|
+
if (active) { json(response, 409, { error: "The assistant is already working." }); return; }
|
|
83
|
+
const controller = new AbortController();
|
|
84
|
+
active = controller;
|
|
85
|
+
let turn;
|
|
86
|
+
try { turn = await transcript.writeConversationUserMessage(scope, input); }
|
|
87
|
+
catch (failure) { active = null; throw failure; }
|
|
88
|
+
response.writeHead(200, { "Content-Type": "application/x-ndjson", "Cache-Control": "no-store" });
|
|
89
|
+
const emit = (event) => { if (!response.destroyed) response.write(`${JSON.stringify(event)}\n`); };
|
|
90
|
+
const disconnected = () => controller.abort();
|
|
91
|
+
response.on("close", disconnected);
|
|
92
|
+
let answer = "";
|
|
93
|
+
try {
|
|
94
|
+
// A duplicate request returns saved state; it never launches the provider again.
|
|
95
|
+
if (turn) {
|
|
96
|
+
const history = await transcript.readConversationLog(scope);
|
|
97
|
+
emit({ type: "snapshot", turns: history.map((entry) => entry.turnId === turn.turnId ? { ...entry, pending: true } : entry) });
|
|
98
|
+
const messages = history.flatMap((entry) => [entry.user, entry.assistant].filter(Boolean))
|
|
99
|
+
.slice(-20).map((entry) => ({ role: entry.role, content: entry.text }));
|
|
100
|
+
for await (const text of reply(messages, configuration, controller.signal)) {
|
|
101
|
+
answer += text;
|
|
102
|
+
if (answer.length > 32_000) throw new Error("Response limit reached.");
|
|
103
|
+
emit({ type: "snapshot", turns: history.map((entry) => entry.turnId === turn.turnId
|
|
104
|
+
? { ...entry, pending: true, assistant: { role: "assistant", text: answer }, messages: [...entry.messages, { role: "assistant", text: answer }] }
|
|
105
|
+
: entry) });
|
|
106
|
+
}
|
|
107
|
+
if (!answer.trim()) throw new Error("The provider returned an empty answer.");
|
|
108
|
+
}
|
|
109
|
+
} catch (failure) {
|
|
110
|
+
emit({ type: "error", message: controller.signal.aborted ? "Stopped." : failure.message });
|
|
111
|
+
answer ||= controller.signal.aborted ? "Stopped." : "The assistant could not complete this request.";
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
if (turn) await transcript.upsertConversationAssistantMessage(scope, { turnId: turn.turnId, text: answer });
|
|
115
|
+
emit({ type: "snapshot", turns: await transcript.readConversationLog(scope) });
|
|
116
|
+
} catch (failure) { emit({ type: "error", message: `Conversation could not be saved: ${failure.message}` }); }
|
|
117
|
+
finally {
|
|
118
|
+
response.off("close", disconnected);
|
|
119
|
+
active = null;
|
|
120
|
+
response.end();
|
|
121
|
+
}
|
|
122
|
+
} catch (failure) { json(response, 400, { error: failure.message }); }
|
|
123
|
+
}).listen(3041, "127.0.0.1", () => { console.log("Assistant example API: http://127.0.0.1:3041"); });
|
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.166",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test"
|
|
@@ -8,19 +8,31 @@
|
|
|
8
8
|
"exports": {
|
|
9
9
|
"./client": "./src/client/index.js",
|
|
10
10
|
"./server": "./src/server/index.js",
|
|
11
|
-
"./shared": "./src/shared/index.js"
|
|
11
|
+
"./shared": "./src/shared/index.js",
|
|
12
|
+
"./client/conversation": "./src/client/conversation/index.js",
|
|
13
|
+
"./server/codex-events": "./src/server/conversation/codexEvents.js",
|
|
14
|
+
"./server/codex-turn": "./src/server/conversation/codexTurn.js",
|
|
15
|
+
"./server/codex-client": "./src/server/conversation/codexClient.js",
|
|
16
|
+
"./server/opencode-client": "./src/server/conversation/openCodeClient.js",
|
|
17
|
+
"./server/conversation": "./src/server/conversation/index.js",
|
|
18
|
+
"./shared/conversation": "./src/shared/conversation/index.js",
|
|
19
|
+
"./client/conversation-submit": "./src/client/conversation/submitText.js",
|
|
20
|
+
"./client/conversation-scroll": "./src/client/conversation/useScrollToBottom.js",
|
|
21
|
+
"./testing/conversation-storage": "./src/testing/conversationStorageContract.js"
|
|
12
22
|
},
|
|
13
23
|
"dependencies": {
|
|
14
|
-
"@jskit-ai/resource-core": "0.1.
|
|
15
|
-
"@jskit-ai/resource-crud-core": "0.1.
|
|
24
|
+
"@jskit-ai/resource-core": "0.1.132",
|
|
25
|
+
"@jskit-ai/resource-crud-core": "0.1.132",
|
|
16
26
|
"dompurify": "^3.4.13",
|
|
17
27
|
"json-rest-schema": "^1.0.17",
|
|
18
28
|
"marked": "^17.0.4",
|
|
19
|
-
"openai": "^6.22.0"
|
|
29
|
+
"openai": "^6.22.0",
|
|
30
|
+
"@mdi/js": "^7.4.47",
|
|
31
|
+
"ws": "^8.20.1"
|
|
20
32
|
},
|
|
21
33
|
"peerDependencies": {
|
|
22
|
-
"@jskit-ai/http-runtime": "0.1.
|
|
23
|
-
"@jskit-ai/kernel": "0.1.
|
|
34
|
+
"@jskit-ai/http-runtime": "0.1.188",
|
|
35
|
+
"@jskit-ai/kernel": "0.1.190",
|
|
24
36
|
"vue": "^3.5.13",
|
|
25
37
|
"vuetify": "^4.0.0"
|
|
26
38
|
},
|
|
@@ -55,6 +67,46 @@
|
|
|
55
67
|
{
|
|
56
68
|
"subpath": "./shared",
|
|
57
69
|
"summary": "Exports reusable assistant validators, path helpers, query keys, and stream/settings events."
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"subpath": "./client/conversation",
|
|
73
|
+
"summary": "Embeddable conversation element, transcript, composer and progress presentation with application-owned state and actions."
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"subpath": "./server/conversation",
|
|
77
|
+
"summary": "Conversation transcript lifecycle with replaceable application storage and an explicit transient memory adapter."
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"subpath": "./shared/conversation",
|
|
81
|
+
"summary": "Turn mapping, rich-text parsing, question helpers and scroll-follow state."
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"subpath": "./server/codex-client",
|
|
85
|
+
"summary": "Codex app-server JSON-RPC client; the application supplies the endpoint, identity and request authorization."
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"subpath": "./server/codex-turn",
|
|
89
|
+
"summary": "Native Codex detached-turn observation and final-result recovery."
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"subpath": "./server/codex-events",
|
|
93
|
+
"summary": "Native Codex notification and thread-history classification."
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"subpath": "./server/opencode-client",
|
|
97
|
+
"summary": "Bounded OpenCode loopback HTTP and SSE client."
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"subpath": "./client/conversation-submit",
|
|
101
|
+
"summary": "Companion text submission through the application draft and canonical send action."
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"subpath": "./client/conversation-scroll",
|
|
105
|
+
"summary": "Layout-aware scroll-follow operations."
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"subpath": "./testing/conversation-storage",
|
|
109
|
+
"summary": "Reusable checks for application conversation storage adapters."
|
|
58
110
|
}
|
|
59
111
|
],
|
|
60
112
|
"capabilities": []
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="assistant-composer-actions">
|
|
3
|
+
<div class="assistant-composer-actions__tools"><slot /></div>
|
|
4
|
+
<div class="assistant-composer-actions__delivery">
|
|
5
|
+
<v-btn
|
|
6
|
+
v-if="state.canStop" color="error" :disabled="state.stopDisabled || state.stopPending"
|
|
7
|
+
:aria-busy="state.stopPending ? 'true' : undefined" :prepend-icon="mdiStopCircleOutline"
|
|
8
|
+
size="small" variant="tonal" @click="emit('stop')"
|
|
9
|
+
>
|
|
10
|
+
{{ state.stopPending ? 'Stopping…' : 'Stop' }}
|
|
11
|
+
</v-btn>
|
|
12
|
+
<v-btn
|
|
13
|
+
ref="sendButton" class="assistant-composer-actions__send" color="primary" :disabled="!state.canSend"
|
|
14
|
+
:aria-busy="state.pending ? 'true' : undefined" :aria-label="state.submitAriaLabel || state.submitLabel || 'Send message'"
|
|
15
|
+
:title="state.submitTitle" :prepend-icon="state.submitIcon || mdiSend" size="small" variant="flat"
|
|
16
|
+
@click="emit('submit')"
|
|
17
|
+
>
|
|
18
|
+
{{ state.submitLabel || (state.pending ? 'Sending…' : 'Send') }}
|
|
19
|
+
</v-btn>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
</template>
|
|
23
|
+
<script setup>
|
|
24
|
+
import { ref } from "vue";
|
|
25
|
+
import { mdiSend, mdiStopCircleOutline } from "@mdi/js";
|
|
26
|
+
defineProps({ state: { type: Object, required: true } });
|
|
27
|
+
const emit = defineEmits(["submit", "stop"]);
|
|
28
|
+
const sendButton = ref(null);
|
|
29
|
+
defineExpose({ focus() { (sendButton.value?.$el || sendButton.value)?.focus?.(); } });
|
|
30
|
+
</script>
|
|
31
|
+
<style scoped>
|
|
32
|
+
.assistant-composer-actions, .assistant-composer-actions__tools, .assistant-composer-actions__delivery {
|
|
33
|
+
align-items: center; display: flex; gap: 0.3rem; min-width: 0;
|
|
34
|
+
}
|
|
35
|
+
.assistant-composer-actions { flex-wrap: wrap; justify-content: space-between; }
|
|
36
|
+
.assistant-composer-actions__tools { flex: 1 1 auto; flex-wrap: wrap; }
|
|
37
|
+
.assistant-composer-actions__delivery { flex: 0 0 auto; margin-left: auto; }
|
|
38
|
+
.assistant-composer-actions__send { min-width: 5.25rem; }
|
|
39
|
+
@media (pointer: coarse) {
|
|
40
|
+
.assistant-composer-actions__delivery > .v-btn { min-height: 3rem; min-width: 3rem; }
|
|
41
|
+
.assistant-composer-actions__delivery > .assistant-composer-actions__send { min-width: 5.25rem; }
|
|
42
|
+
}
|
|
43
|
+
</style>
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<section class="assistant-conversation" :aria-label="label">
|
|
3
|
+
<AssistantTranscript
|
|
4
|
+
v-bind="adapter.conversation" class="assistant-conversation__transcript"
|
|
5
|
+
@load-more="adapter.actions?.loadMore?.($event)" @reload="adapter.actions?.reload?.()"
|
|
6
|
+
@resend-turn="adapter.actions?.resend?.($event)" @cancel-turn="adapter.actions?.cancel?.($event)"
|
|
7
|
+
@edit-turn="adapter.actions?.edit?.($event)" @link-click="adapter.actions?.openLink?.($event)"
|
|
8
|
+
>
|
|
9
|
+
<template v-for="name in transcriptSlots" #[name]="scope"><slot :name="name" v-bind="scope" /></template>
|
|
10
|
+
</AssistantTranscript>
|
|
11
|
+
<slot name="hints" :adapter="adapter" />
|
|
12
|
+
<slot name="composer" :adapter="adapter">
|
|
13
|
+
<AssistantPromptInput
|
|
14
|
+
v-if="adapter.composer" ref="input" v-bind="adapter.composer"
|
|
15
|
+
:model-value="adapter.composer.draft || ''" :submit-enabled="adapter.composer.canSend"
|
|
16
|
+
:aria-label="adapter.composer.ariaLabel || 'Message AI assistant'" :rows="adapter.composer.rows || 2"
|
|
17
|
+
tab-to-submit @update:model-value="adapter.actions.setDraft($event)"
|
|
18
|
+
@submit="submit" @tab-to-submit="delivery?.focus()"
|
|
19
|
+
>
|
|
20
|
+
<template v-if="$slots['input-start']" #input-start><slot name="input-start" :adapter="adapter" /></template>
|
|
21
|
+
<template #footer>
|
|
22
|
+
<AssistantComposerActions ref="delivery" :state="adapter.composer" @submit="submit" @stop="stop">
|
|
23
|
+
<slot
|
|
24
|
+
v-if="configurationMode !== 'hidden'" name="configuration"
|
|
25
|
+
:configuration="configuration" :disabled="configurationMode !== 'editable' || adapter.composer.pending"
|
|
26
|
+
:update="updateConfiguration"
|
|
27
|
+
>
|
|
28
|
+
<v-select
|
|
29
|
+
v-for="field in configurationFields" :key="field.name"
|
|
30
|
+
:model-value="configuration[field.name]" :label="field.label" :items="field.items"
|
|
31
|
+
:disabled="configurationMode !== 'editable' || adapter.composer.pending"
|
|
32
|
+
density="compact" hide-details variant="outlined" class="assistant-conversation__setting"
|
|
33
|
+
@update:model-value="updateConfiguration({ ...configuration, [field.name]: $event })"
|
|
34
|
+
/>
|
|
35
|
+
</slot>
|
|
36
|
+
<slot name="composer-tools" :adapter="adapter" />
|
|
37
|
+
</AssistantComposerActions>
|
|
38
|
+
</template>
|
|
39
|
+
</AssistantPromptInput>
|
|
40
|
+
</slot>
|
|
41
|
+
</section>
|
|
42
|
+
</template>
|
|
43
|
+
<script setup>
|
|
44
|
+
import { computed, ref, useSlots } from "vue";
|
|
45
|
+
import AssistantTranscript from "./AssistantTranscript.vue";
|
|
46
|
+
import AssistantPromptInput from "./AssistantPromptInput.vue";
|
|
47
|
+
import AssistantComposerActions from "./AssistantComposerActions.vue";
|
|
48
|
+
const props = defineProps({
|
|
49
|
+
adapter: { type: Object, required: true },
|
|
50
|
+
label: { type: String, default: "Assistant conversation" },
|
|
51
|
+
configuration: { type: Object, default: () => ({}) },
|
|
52
|
+
configurationFields: { type: Array, default: () => [] },
|
|
53
|
+
configurationMode: { type: String, default: "hidden", validator: (value) => ["hidden", "readonly", "editable"].includes(value) }
|
|
54
|
+
});
|
|
55
|
+
const slots = useSlots();
|
|
56
|
+
const transcriptSlots = computed(() => ["attachments", "system-message", "message-actions"].filter((name) => slots[name]));
|
|
57
|
+
const input = ref(null);
|
|
58
|
+
const delivery = ref(null);
|
|
59
|
+
function submit() {
|
|
60
|
+
if (!props.adapter.composer?.canSend) return;
|
|
61
|
+
return props.adapter.actions.submit({ configuration: props.configuration });
|
|
62
|
+
}
|
|
63
|
+
function stop() {
|
|
64
|
+
const state = props.adapter.composer;
|
|
65
|
+
if (!state?.canStop || state.stopDisabled || state.stopPending) return;
|
|
66
|
+
return props.adapter.actions.stop();
|
|
67
|
+
}
|
|
68
|
+
function updateConfiguration(value) {
|
|
69
|
+
if (props.configurationMode !== "editable" || props.adapter.composer?.pending) return;
|
|
70
|
+
return props.adapter.actions?.updateConfiguration?.(value);
|
|
71
|
+
}
|
|
72
|
+
defineExpose({ focus: () => input.value?.focus(), submit, stop });
|
|
73
|
+
</script>
|
|
74
|
+
<style scoped>
|
|
75
|
+
.assistant-conversation { display: flex; flex-direction: column; min-height: 0; min-width: 0; height: 100%; gap: 0; }
|
|
76
|
+
.assistant-conversation__transcript { flex: 1 1 auto; min-height: 0; }
|
|
77
|
+
.assistant-conversation__setting { min-width: 8rem; max-width: 16rem; }
|
|
78
|
+
</style>
|