@veltra/ai 1.4.0 → 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/dist/chat/index.d.ts +3 -3
- package/dist/chat/transports/index.d.ts +2 -2
- package/dist/chat/transports/openai.d.ts +16 -12
- package/dist/chat/transports/openai.js +56 -15
- package/dist/chat/transports/openai.js.map +1 -1
- package/dist/chat/types.d.ts +41 -2
- package/dist/chat/use-chat.d.ts +26 -1
- package/dist/chat/use-chat.js +132 -13
- package/dist/chat/use-chat.js.map +1 -1
- package/dist/components/ai-chat/ai-chat.js +222 -41
- package/dist/components/ai-chat/ai-chat.js.map +1 -1
- package/dist/components/ai-chat/ask-question.js +2 -2
- package/dist/components/ai-chat/ask-question.js.map +1 -1
- package/dist/components/ai-chat/chat-input.js +81 -44
- package/dist/components/ai-chat/chat-input.js.map +1 -1
- package/dist/components/ai-chat/di.js.map +1 -1
- package/dist/components/ai-chat/message-item.js +101 -23
- package/dist/components/ai-chat/message-item.js.map +1 -1
- package/dist/components/ai-chat/message-list.js +217 -32
- package/dist/components/ai-chat/message-list.js.map +1 -1
- package/dist/components/ai-chat/model-picker.js +140 -0
- package/dist/components/ai-chat/model-picker.js.map +1 -0
- package/dist/components/ai-chat/queue-list.js +70 -0
- package/dist/components/ai-chat/queue-list.js.map +1 -0
- package/dist/components/ai-chat/side-panel.js +96 -0
- package/dist/components/ai-chat/side-panel.js.map +1 -0
- package/dist/components/ai-chat/style.d.ts +6 -0
- package/dist/components/ai-chat/style.js +6 -0
- package/dist/components/ai-chat/style2.css +552 -41
- package/dist/components/ai-chat/tool-call.js +61 -27
- package/dist/components/ai-chat/tool-call.js.map +1 -1
- package/dist/components/ai-orb/ai-orb.js +94 -0
- package/dist/components/ai-orb/ai-orb.js.map +1 -0
- package/dist/components/ai-orb/orb-renderer.js +411 -0
- package/dist/components/ai-orb/orb-renderer.js.map +1 -0
- package/dist/components/ai-orb/style.d.ts +1 -0
- package/dist/components/ai-orb/style.js +1 -0
- package/dist/components/ai-orb/style2.css +23 -0
- package/dist/index.d.ts +8 -6
- package/dist/index.js +2 -2
- package/dist/providers/types.d.ts +47 -0
- package/dist/style.js +1 -0
- package/dist/tools/ask-question/ask-question.d.ts +2 -17
- package/dist/tools/ask-question/index.d.ts +2 -2
- package/dist/tools/index.d.ts +3 -2
- package/dist/tools/index.js +10 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types/ai-chat.d.ts +35 -7
- package/dist/types/ai-orb.d.ts +27 -0
- package/dist/types/index.d.ts +2 -1
- package/package.json +8 -8
- package/src/chat/__test__/use-chat.test.ts +295 -9
- package/src/chat/transports/__test__/openai.test.ts +317 -0
- package/src/chat/transports/openai.ts +88 -26
- package/src/chat/types.ts +41 -1
- package/src/chat/use-chat.ts +177 -14
- package/src/components/ai-chat/__test__/ai-chat.test.ts +690 -12
- package/src/components/ai-chat/ai-chat.vue +241 -31
- package/src/components/ai-chat/chat-input.vue +78 -31
- package/src/components/ai-chat/di.ts +2 -0
- package/src/components/ai-chat/message-item.vue +98 -11
- package/src/components/ai-chat/message-list.vue +261 -21
- package/src/components/ai-chat/model-picker.vue +177 -0
- package/src/components/ai-chat/queue-list.vue +63 -0
- package/src/components/ai-chat/side-panel.vue +76 -0
- package/src/components/ai-chat/style.scss +621 -43
- package/src/components/ai-chat/style.ts +6 -0
- package/src/components/ai-chat/tool-call.vue +86 -42
- package/src/components/ai-orb/__test__/ai-orb.test.ts +251 -0
- package/src/components/ai-orb/ai-orb.vue +107 -0
- package/src/components/ai-orb/index.ts +1 -0
- package/src/components/ai-orb/orb-renderer.ts +505 -0
- package/src/components/ai-orb/style.scss +10 -0
- package/src/components/ai-orb/style.ts +1 -0
- package/src/components/index.ts +1 -0
- package/src/index.ts +8 -1
- package/src/providers/index.ts +1 -0
- package/src/providers/types.ts +46 -0
- package/src/style.ts +1 -0
- package/src/tools/ask-question/__test__/ask-question.test.ts +4 -4
- package/src/tools/index.ts +14 -1
- package/src/types/ai-chat.ts +35 -6
- package/src/types/ai-orb.ts +27 -0
- package/src/types/index.ts +1 -0
- package/dist/components/ai-chat/ai-chat.vue.d.ts +0 -36
- package/dist/components/ai-chat/index.d.ts +0 -2
- package/dist/components/index.d.ts +0 -3
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { AiChatDIKey } from "./di.js";
|
|
2
|
+
import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, inject, normalizeClass, openBlock, resolveDynamicComponent, toDisplayString, unref, withCtx } from "vue";
|
|
3
|
+
import { CircleCheckFilled, CircleClose, Close, Loading, WarningFilled } from "@veltra/icons/normal";
|
|
4
|
+
import { UIcon, UScroll } from "@veltra/desktop";
|
|
5
|
+
import { bem } from "@veltra/utils";
|
|
6
|
+
//#region src/components/ai-chat/side-panel.vue
|
|
7
|
+
const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
8
|
+
name: "UAiChatSidePanel",
|
|
9
|
+
__name: "side-panel",
|
|
10
|
+
props: { toolCall: {} },
|
|
11
|
+
emits: ["close"],
|
|
12
|
+
setup(__props, { emit: __emit }) {
|
|
13
|
+
const props = __props;
|
|
14
|
+
const emit = __emit;
|
|
15
|
+
const di = inject(AiChatDIKey);
|
|
16
|
+
const cls = di?.cls ?? bem("ai-chat");
|
|
17
|
+
/** 当前调用对应的工具定义(解析 icon/label/render) */
|
|
18
|
+
const tool = computed(() => di?.tools.value[props.toolCall.name]);
|
|
19
|
+
const STATUS_META = {
|
|
20
|
+
pending: {
|
|
21
|
+
icon: Loading,
|
|
22
|
+
class: "is-active"
|
|
23
|
+
},
|
|
24
|
+
running: {
|
|
25
|
+
icon: Loading,
|
|
26
|
+
class: "is-active"
|
|
27
|
+
},
|
|
28
|
+
"awaiting-confirm": {
|
|
29
|
+
icon: WarningFilled,
|
|
30
|
+
class: "is-warning"
|
|
31
|
+
},
|
|
32
|
+
success: {
|
|
33
|
+
icon: CircleCheckFilled,
|
|
34
|
+
class: "is-success"
|
|
35
|
+
},
|
|
36
|
+
error: {
|
|
37
|
+
icon: CircleClose,
|
|
38
|
+
class: "is-danger"
|
|
39
|
+
},
|
|
40
|
+
rejected: {
|
|
41
|
+
icon: Close,
|
|
42
|
+
class: "is-danger"
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
const statusIcon = computed(() => STATUS_META[props.toolCall.status]?.icon ?? Loading);
|
|
46
|
+
const statusClass = computed(() => STATUS_META[props.toolCall.status]?.class ?? "");
|
|
47
|
+
/** 头部图标:工具自定义图标优先,缺省用状态图标(与工具卡片一致) */
|
|
48
|
+
const headerIcon = computed(() => tool.value?.icon ?? statusIcon.value);
|
|
49
|
+
/** 面板标题:优先工具定义的 panelTitle(业务对象 + 动作),缺省回落到 label ?? name */
|
|
50
|
+
const panelTitle = computed(() => {
|
|
51
|
+
const t = tool.value;
|
|
52
|
+
const pt = t?.panelTitle;
|
|
53
|
+
if (typeof pt === "function") return pt(props.toolCall);
|
|
54
|
+
return pt ?? t?.label ?? props.toolCall.name;
|
|
55
|
+
});
|
|
56
|
+
/** 未提供 render 时的兜底展示(面板工具通常都应提供 render) */
|
|
57
|
+
const fallbackResult = computed(() => {
|
|
58
|
+
const raw = props.toolCall.error ?? props.toolCall.result ?? "";
|
|
59
|
+
try {
|
|
60
|
+
return JSON.stringify(JSON.parse(raw), null, 2);
|
|
61
|
+
} catch {
|
|
62
|
+
return raw;
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
return (_ctx, _cache) => {
|
|
66
|
+
return openBlock(), createElementBlock("aside", { class: normalizeClass(unref(cls).e("panel")) }, [createElementVNode("div", { class: normalizeClass(unref(cls).e("panel-card")) }, [createElementVNode("div", { class: normalizeClass(unref(cls).e("panel-header")) }, [
|
|
67
|
+
createVNode(unref(UIcon), { class: normalizeClass([unref(cls).e("panel-icon"), statusClass.value]) }, {
|
|
68
|
+
default: withCtx(() => [(openBlock(), createBlock(resolveDynamicComponent(headerIcon.value)))]),
|
|
69
|
+
_: 1
|
|
70
|
+
}, 8, ["class"]),
|
|
71
|
+
createElementVNode("span", { class: normalizeClass(unref(cls).e("panel-title")) }, toDisplayString(panelTitle.value), 3),
|
|
72
|
+
createVNode(unref(UIcon), {
|
|
73
|
+
class: normalizeClass(unref(cls).e("panel-close")),
|
|
74
|
+
title: "关闭面板",
|
|
75
|
+
onClick: _cache[0] || (_cache[0] = ($event) => emit("close"))
|
|
76
|
+
}, {
|
|
77
|
+
default: withCtx(() => [createVNode(unref(Close))]),
|
|
78
|
+
_: 1
|
|
79
|
+
}, 8, ["class"])
|
|
80
|
+
], 2), createVNode(unref(UScroll), { class: normalizeClass(unref(cls).e("panel-body")) }, {
|
|
81
|
+
default: withCtx(() => [createCommentVNode(" render 组件与工具卡片同一契约(ChatToolRenderProps),可随 toolCall 状态实时更新 "), tool.value?.render ? (openBlock(), createBlock(resolveDynamicComponent(tool.value.render), {
|
|
82
|
+
key: 0,
|
|
83
|
+
"tool-call": __props.toolCall
|
|
84
|
+
}, null, 8, ["tool-call"])) : (openBlock(), createElementBlock("pre", {
|
|
85
|
+
key: 1,
|
|
86
|
+
class: normalizeClass(unref(cls).e("panel-fallback"))
|
|
87
|
+
}, toDisplayString(fallbackResult.value), 3))]),
|
|
88
|
+
_: 1
|
|
89
|
+
}, 8, ["class"])], 2)], 2);
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
//#endregion
|
|
94
|
+
export { _sfc_main as default };
|
|
95
|
+
|
|
96
|
+
//# sourceMappingURL=side-panel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"side-panel.js","names":[],"sources":["../../../src/components/ai-chat/side-panel.vue"],"sourcesContent":["<template>\n <aside :class=\"cls.e('panel')\">\n <div :class=\"cls.e('panel-card')\">\n <div :class=\"cls.e('panel-header')\">\n <UIcon :class=\"[cls.e('panel-icon'), statusClass]\">\n <component :is=\"headerIcon\" />\n </UIcon>\n <span :class=\"cls.e('panel-title')\">{{ panelTitle }}</span>\n <UIcon :class=\"cls.e('panel-close')\" title=\"关闭面板\" @click=\"emit('close')\">\n <Close />\n </UIcon>\n </div>\n\n <UScroll :class=\"cls.e('panel-body')\">\n <!-- render 组件与工具卡片同一契约(ChatToolRenderProps),可随 toolCall 状态实时更新 -->\n <component :is=\"tool.render\" v-if=\"tool?.render\" :tool-call=\"toolCall\" />\n <pre v-else :class=\"cls.e('panel-fallback')\">{{ fallbackResult }}</pre>\n </UScroll>\n </div>\n </aside>\n</template>\n\n<script lang=\"ts\" setup>\nimport { UIcon, UScroll } from '@veltra/desktop'\nimport { CircleCheckFilled, CircleClose, Close, Loading, WarningFilled } from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\nimport { computed, inject, type Component } from 'vue'\n\nimport type { ChatToolCall } from '../../chat/types'\nimport { AiChatDIKey } from './di'\n\ndefineOptions({ name: 'UAiChatSidePanel' })\n\nconst props = defineProps<{ toolCall: ChatToolCall }>()\n\nconst emit = defineEmits<{ (e: 'close'): void }>()\n\nconst di = inject(AiChatDIKey)\nconst cls = di?.cls ?? bem('ai-chat')\n\n/** 当前调用对应的工具定义(解析 icon/label/render) */\nconst tool = computed(() => di?.tools.value[props.toolCall.name])\n\nconst STATUS_META: Record<string, { icon: Component; class: string }> = {\n pending: { icon: Loading, class: 'is-active' },\n running: { icon: Loading, class: 'is-active' },\n 'awaiting-confirm': { icon: WarningFilled, class: 'is-warning' },\n success: { icon: CircleCheckFilled, class: 'is-success' },\n error: { icon: CircleClose, class: 'is-danger' },\n rejected: { icon: Close, class: 'is-danger' }\n}\n\nconst statusIcon = computed(() => STATUS_META[props.toolCall.status]?.icon ?? Loading)\nconst statusClass = computed(() => STATUS_META[props.toolCall.status]?.class ?? '')\n\n/** 头部图标:工具自定义图标优先,缺省用状态图标(与工具卡片一致) */\nconst headerIcon = computed(() => tool.value?.icon ?? statusIcon.value)\n\n/** 面板标题:优先工具定义的 panelTitle(业务对象 + 动作),缺省回落到 label ?? name */\nconst panelTitle = computed(() => {\n const t = tool.value\n const pt = t?.panelTitle\n if (typeof pt === 'function') return pt(props.toolCall)\n return pt ?? t?.label ?? props.toolCall.name\n})\n\n/** 未提供 render 时的兜底展示(面板工具通常都应提供 render) */\nconst fallbackResult = computed(() => {\n const raw = props.toolCall.error ?? props.toolCall.result ?? ''\n try {\n return JSON.stringify(JSON.parse(raw), null, 2)\n } catch {\n return raw\n }\n})\n</script>\n"],"mappings":";;;;;;;;;;;;EAiCA,MAAM,QAAQ;EAEd,MAAM,OAAO;EAEb,MAAM,KAAK,OAAO,WAAW;EAC7B,MAAM,MAAM,IAAI,OAAO,IAAI,SAAS;;EAGpC,MAAM,OAAO,eAAe,IAAI,MAAM,MAAM,MAAM,SAAS,KAAK;EAEhE,MAAM,cAAkE;GACtE,SAAS;IAAE,MAAM;IAAS,OAAO;GAAY;GAC7C,SAAS;IAAE,MAAM;IAAS,OAAO;GAAY;GAC7C,oBAAoB;IAAE,MAAM;IAAe,OAAO;GAAa;GAC/D,SAAS;IAAE,MAAM;IAAmB,OAAO;GAAa;GACxD,OAAO;IAAE,MAAM;IAAa,OAAO;GAAY;GAC/C,UAAU;IAAE,MAAM;IAAO,OAAO;GAAY;EAC9C;EAEA,MAAM,aAAa,eAAe,YAAY,MAAM,SAAS,OAAO,EAAE,QAAQ,OAAO;EACrF,MAAM,cAAc,eAAe,YAAY,MAAM,SAAS,OAAO,EAAE,SAAS,EAAE;;EAGlF,MAAM,aAAa,eAAe,KAAK,OAAO,QAAQ,WAAW,KAAK;;EAGtE,MAAM,aAAa,eAAe;GAChC,MAAM,IAAI,KAAK;GACf,MAAM,KAAK,GAAG;GACd,IAAI,OAAO,OAAO,YAAY,OAAO,GAAG,MAAM,QAAQ;GACtD,OAAO,MAAM,GAAG,SAAS,MAAM,SAAS;EAC1C,CAAC;;EAGD,MAAM,iBAAiB,eAAe;GACpC,MAAM,MAAM,MAAM,SAAS,SAAS,MAAM,SAAS,UAAU;GAC7D,IAAI;IACF,OAAO,KAAK,UAAU,KAAK,MAAM,GAAG,GAAG,MAAM,CAAC;GAChD,QAAQ;IACN,OAAO;GACT;EACF,CAAC;;GAzEC,OAAA,UAAA,GAAA,mBAkBQ,SAAA,EAlBA,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,OAAA,CAAA,EAAA,GAClB,CAAA,mBAgBM,OAAA,EAhBA,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,YAAA,CAAA,EAAA,GAChB,CAAA,mBAQM,OAAA,EARA,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,cAAA,CAAA,EAAA,GAAA;IAChB,YAEQ,MAAA,KAAA,GAAA,EAFA,OAAK,eAAA,CAAG,MAAA,GAAA,CAAG,CAAC,EAAC,YAAA,GAAgB,YAAA,KAAW,CAAA,EAAA,GAAA;KAChB,SAAA,cAAA,EAAA,UAAA,GAA9B,YAA8B,wBAAd,WAAA,KAAU,CAAA,EAAA,CAAA;;;IAE5B,mBAA2D,QAAA,EAApD,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,aAAA,CAAA,EAAA,GAAoB,gBAAA,WAAA,KAAU,GAAA,CAAA;IACjD,YAEQ,MAAA,KAAA,GAAA;KAFA,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,aAAA,CAAA;KAAiB,OAAM;KAAQ,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,OAAA;;KACnD,SAAA,cAAA,CAAT,YAAS,MAAA,KAAA,CAAA,CAAA,CAAA;;;GAIb,GAAA,CAAA,GAAA,YAIU,MAAA,OAAA,GAAA,EAJA,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,YAAA,CAAA,EAAA,GAAA;IAC+C,SAAA,cAAA,CAAnE,mBAAA,8DAAA,GACmC,KAAA,OAAM,UAAA,UAAA,GAAzC,YAAyE,wBAAzD,KAAA,MAAK,MAAM,GAAA;;KAAuB,aAAW,QAAA;IAC7D,GAAA,MAAA,GAAA,CAAA,WAAA,CAAA,MAAA,UAAA,GAAA,mBAAuE,OAAA;;KAA1D,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,gBAAA,CAAA;IAAuB,GAAA,gBAAA,eAAA,KAAc,GAAA,CAAA,EAAA,CAAA"}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import "@veltra/desktop/components/button/style";
|
|
2
|
+
import "@veltra/desktop/components/collapse/style";
|
|
3
|
+
import "@veltra/desktop/components/file-picker/style";
|
|
2
4
|
import "@veltra/desktop/components/icon/style";
|
|
3
5
|
import "@veltra/desktop/components/input/style";
|
|
6
|
+
import "@veltra/desktop/components/layout/style";
|
|
7
|
+
import "@veltra/desktop/components/message/style";
|
|
4
8
|
import "@veltra/desktop/components/scroll/style";
|
|
9
|
+
import "@veltra/desktop/components/select/style";
|
|
10
|
+
import "@veltra/styles/animations/shine.scss";
|
|
5
11
|
import "markstream-vue/index.css";
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import "./style2.css";
|
|
2
2
|
import "@veltra/desktop/components/button/style";
|
|
3
|
+
import "@veltra/desktop/components/collapse/style";
|
|
4
|
+
import "@veltra/desktop/components/file-picker/style";
|
|
3
5
|
import "@veltra/desktop/components/icon/style";
|
|
4
6
|
import "@veltra/desktop/components/input/style";
|
|
7
|
+
import "@veltra/desktop/components/layout/style";
|
|
8
|
+
import "@veltra/desktop/components/message/style";
|
|
5
9
|
import "@veltra/desktop/components/scroll/style";
|
|
10
|
+
import "@veltra/desktop/components/select/style";
|
|
11
|
+
import "@veltra/styles/animations/shine.scss";
|
|
6
12
|
import "markstream-vue/index.css";
|