@veltra/ai 2.1.8 → 2.1.10

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.
Files changed (40) hide show
  1. package/dist/chat/fold.d.ts +4 -5
  2. package/dist/chat/session.d.ts +5 -6
  3. package/dist/chat/transports/openai.d.ts +3 -4
  4. package/dist/chat/types.d.ts +15 -16
  5. package/dist/chat/use-chat.d.ts +2 -3
  6. package/dist/components/ai-chat/message-item.js +18 -8
  7. package/dist/components/ai-chat/message-item.js.map +1 -1
  8. package/dist/components/ai-chat/message-list.js +3 -3
  9. package/dist/components/ai-chat/message-list.js.map +1 -1
  10. package/dist/components/ai-chat/style.js +1 -0
  11. package/dist/components/ai-chat/style2.css +20 -7
  12. package/dist/components/ai-chat/tool-call.js +18 -11
  13. package/dist/components/ai-chat/tool-call.js.map +1 -1
  14. package/dist/index.d.ts +1 -3
  15. package/dist/index.js +1 -2
  16. package/dist/providers/types.d.ts +4 -5
  17. package/dist/style.js +0 -1
  18. package/dist/tools/ask-question/ask-question.d.ts +4 -5
  19. package/dist/tools/ask-question/ask-question.js +2 -1
  20. package/dist/tools/ask-question/ask-question.js.map +1 -1
  21. package/dist/types/ai-chat.d.ts +4 -5
  22. package/dist/types/index.d.ts +1 -2
  23. package/package.json +6 -6
  24. package/src/components/ai-chat/__test__/ai-chat.test.ts +74 -5
  25. package/src/components/ai-chat/message-item.vue +18 -16
  26. package/src/components/ai-chat/message-list.vue +8 -4
  27. package/src/components/ai-chat/style.scss +22 -8
  28. package/src/components/ai-chat/style.ts +2 -0
  29. package/src/components/ai-chat/tool-call.vue +27 -9
  30. package/src/components/index.ts +0 -1
  31. package/src/style.ts +0 -1
  32. package/src/tools/ask-question/__test__/ask-question.test.ts +20 -2
  33. package/src/tools/ask-question/ask-question.ts +2 -1
  34. package/src/types/index.ts +0 -1
  35. package/dist/components/ai-orb/style.d.ts +0 -1
  36. package/dist/components/ai-orb/style.js +0 -1
  37. package/dist/types/ai-orb.d.ts +0 -27
  38. package/src/components/ai-orb/index.ts +0 -1
  39. package/src/components/ai-orb/style.ts +0 -1
  40. /package/dist/components/ai-orb/{style2.css → style.css} +0 -0
@@ -95,19 +95,39 @@ const markUserToggled = () => {
95
95
  /** 面板工具:render 展示在右侧侧边面板,卡片 body 仅保留「查看面板」入口 */
96
96
  const isPanelTool = computed(() => tool.value?.renderTo === 'panel')
97
97
 
98
- /** 完成后是否自动折叠:缺省面板工具折叠;有 render 时不折叠,否则折叠 */
99
- const autoCollapse = computed(
100
- () => tool.value?.autoCollapse ?? (isPanelTool.value || !tool.value?.render)
98
+ /** 「UI 即答复」的终结工具(session 元信息无 terminal,恒为 false) */
99
+ const isAnswerTool = computed(() => {
100
+ const t = tool.value
101
+ return !!(t && 'terminal' in t && t.terminal)
102
+ })
103
+
104
+ /** 内联自定义 body(render / tool-<name> 插槽):进行中可能是提问表单等交互 UI,需展开可见 */
105
+ const hasInlineBody = computed(
106
+ () => !isPanelTool.value && !!(tool.value?.render || di?.slots[`tool-${props.toolCall.name}`])
101
107
  )
102
108
 
109
+ /** 完成后是否自动折叠:缺省一律折叠;「UI 即答复」的终结工具缺省保持展开 */
110
+ const autoCollapse = computed(() => tool.value?.autoCollapse ?? !isAnswerTool.value)
111
+
112
+ /** 需要用户交互/展示的进行中状态:待确认(看参数再决策)、有内联自定义 body(提问表单等) */
113
+ const needsInteraction = computed(() => {
114
+ if (props.toolCall.status === 'awaiting-confirm') return true
115
+ const active = props.toolCall.status === 'pending' || props.toolCall.status === 'running'
116
+ return active && hasInlineBody.value
117
+ })
118
+
119
+ const isSettledStatus = (status: ChatToolCall['status']) =>
120
+ status === 'success' || status === 'error' || status === 'rejected'
121
+
122
+ // 默认折叠(含进行中);仅交互/答复类自动展开,用户手动切换过后不再自动变化
103
123
  watch(
104
124
  () => props.toolCall.status,
105
125
  (status) => {
106
126
  if (userToggled) return
107
- if (status === 'pending' || status === 'running' || status === 'awaiting-confirm') {
108
- isExpanded.value = true
109
- } else {
127
+ if (isSettledStatus(status)) {
110
128
  isExpanded.value = !autoCollapse.value
129
+ } else {
130
+ isExpanded.value = needsInteraction.value
111
131
  }
112
132
  },
113
133
  { immediate: true }
@@ -130,9 +150,7 @@ const isActive = computed(() => {
130
150
  })
131
151
 
132
152
  /** 终态(成功/失败/拒绝) */
133
- const isSettled = computed(() => {
134
- return ['success', 'error', 'rejected'].includes(props.toolCall.status)
135
- })
153
+ const isSettled = computed(() => isSettledStatus(props.toolCall.status))
136
154
 
137
155
  /**
138
156
  * 折叠后卸载内容 DOM:仅终态且非面板工具时启用——
@@ -1,2 +1 @@
1
1
  export * from './ai-chat'
2
- export * from './ai-orb'
package/src/style.ts CHANGED
@@ -1,2 +1 @@
1
1
  import './components/ai-chat/style'
2
- import './components/ai-orb/style'
@@ -76,6 +76,15 @@ async function expandProcess(host: HTMLElement) {
76
76
  await nextTick()
77
77
  }
78
78
 
79
+ /** 工具卡片终态默认折叠(destroyOnCollapse 卸载内容 DOM):点头部展开后内容才挂载 */
80
+ async function expandToolCard(host: HTMLElement) {
81
+ const header = host.querySelector<HTMLElement>('.u-ai-chat__tool-call .u-collapse__header')!
82
+ expect(header, '工具卡片头部应存在').toBeTruthy()
83
+ click(header)
84
+ await nextTick()
85
+ await nextTick()
86
+ }
87
+
79
88
  /** 底部导航按钮(UButton disabled 体现为 is-disabled class) */
80
89
  const actionButton = (host: HTMLElement, text: string) => {
81
90
  return [...host.querySelectorAll<HTMLElement>('.u-ai-chat__ask-question-actions button')].find(
@@ -169,10 +178,13 @@ describe('内置提问工具', () => {
169
178
  ]
170
179
  })
171
180
 
172
- // 第二轮文本输出后,提问工具卡片收进「已完成」过程块,先展开
181
+ // 第二轮文本输出后,提问工具卡片收进「已完成」过程块,先展开过程块
173
182
  await expandProcess(host)
174
183
 
175
- // 问答摘要视图:命中选项的回答渲染为 chip,完成后保持展开
184
+ // 工具卡片终态默认折叠且卸载内容 DOM,手动展开后才挂载摘要视图
185
+ await expandToolCard(host)
186
+
187
+ // 问答摘要视图:命中选项的回答渲染为 chip
176
188
  expect(host.querySelectorAll('.u-ai-chat__ask-question-result').length).toBe(3)
177
189
  const summary = host.querySelector('.u-ai-chat__ask-question')!.textContent!
178
190
  expect(summary).toContain('目标用户是谁?')
@@ -200,6 +212,12 @@ describe('内置提问工具', () => {
200
212
 
201
213
  chat.value?.abort()
202
214
 
215
+ // 中止后调用进入终态:卡片默认折叠并卸载内容 DOM,展开后显示状态
216
+ await vi.waitFor(() => {
217
+ expect(host.querySelector('.u-ai-chat__tool-call.is-error')).toBeTruthy()
218
+ })
219
+ await expandToolCard(host)
220
+
203
221
  await vi.waitFor(() => {
204
222
  expect(host.querySelector('.u-ai-chat__ask-question-status')?.textContent).toBe('已取消')
205
223
  })
@@ -126,7 +126,8 @@ const AskQuestionRender = defineComponent({
126
126
 
127
127
  /**
128
128
  * 创建内置提问工具:execute 挂起等待用户在 UI 中作答,提交后结果回灌模型。
129
- * 工具卡片由内联提问表单渲染(多题分页导航,提交后展示问答摘要,不自动折叠)。
129
+ * 工具卡片由内联提问表单渲染(多题分页导航,提交后展示问答摘要);
130
+ * 进行中因有内联 render 自动展开,终态默认折叠,展开后可查看问答摘要。
130
131
  */
131
132
  export function createAskQuestionTool(
132
133
  options: CreateAskQuestionToolOptions = {}
@@ -1,2 +1 @@
1
1
  export * from './ai-chat'
2
- export * from './ai-orb'
@@ -1 +0,0 @@
1
- export {}
@@ -1 +0,0 @@
1
- import "./style2.css";
@@ -1,27 +0,0 @@
1
- //#region src/types/ai-orb.d.ts
2
- /** 活体球生命状态:驱动常态动画(平静 / 思考 / 输出) */
3
- type AiOrbStatus = 'idle' | 'thinking' | 'speaking';
4
- /**
5
- * 瞬时表情:播放约 1-2s 后自动回到 status 驱动的常态。
6
- * - happy:成功 / 回答完毕 —— 先睁大眼睛,再弯眼大笑 + 点头
7
- * - shock:惊讶 —— 睁大眼睛 + 小嘴微张 + 轻微后仰
8
- * - frustrated:受挫(如工具调用失败)—— 闭紧眼睛 + 摇头 + 嘴角下撇
9
- */
10
- type AiOrbReaction = 'happy' | 'shock' | 'frustrated';
11
- interface AiOrbProps {
12
- /** 球体直径(px),默认 48 */
13
- size?: number;
14
- /** 生命状态,默认 idle */
15
- status?: AiOrbStatus;
16
- }
17
- interface AiOrbEmits {
18
- /** 点击球体(球体同时会做 Q 弹反馈) */
19
- (e: 'click'): void;
20
- }
21
- interface AiOrbExposed {
22
- /** 播放一次瞬时表情(对应阶段性事件,如回答完毕 / 工具调用失败) */
23
- react: (reaction: AiOrbReaction) => void;
24
- }
25
- //#endregion
26
- export { AiOrbEmits, AiOrbExposed, AiOrbProps, AiOrbReaction, AiOrbStatus };
27
- //# sourceMappingURL=ai-orb.d.ts.map
@@ -1 +0,0 @@
1
- export { default as UAiOrb } from './ai-orb.vue'
@@ -1 +0,0 @@
1
- import './style.scss'