feat(agent): 检索工具、模型接入与结构化回复
Agent 按组织与知识源范围调用检索工具,密钥加密保存,回复含来源与转人工意图。
This commit is contained in:
1 parent
738e37fbb0
commit
362d79a5c2
65 files changed
+33409
No files matched your search
@@ -0,0 +1,77 @@
|
||||
// @vitest-environment jsdom
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
||||
import { mount, flushPromises } from '@vue/test-utils'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const getAgentQueueItems = vi.fn()
|
||||
const getKnowledgeByAgent = vi.fn()
|
||||
|
||||
vi.mock('@/services/knowledge', () => ({
|
||||
knowledgeService: {
|
||||
getAgentQueueItems: (...a: unknown[]) => getAgentQueueItems(...a),
|
||||
getKnowledgeByAgent: (...a: unknown[]) => getKnowledgeByAgent(...a)
|
||||
}
|
||||
}))
|
||||
vi.mock('@/services/widget', () => ({ widgetService: { createAgentWidget: vi.fn() } }))
|
||||
vi.mock('@/composables/useOnboardingTestChat', () => ({
|
||||
useOnboardingTestChat: () => ({
|
||||
messages: ref([]), loading: ref(false), connecting: ref(false), connectionError: ref(''),
|
||||
start: vi.fn(), send: vi.fn(), cleanup: vi.fn()
|
||||
})
|
||||
}))
|
||||
|
||||
import StepTest from '@/components/aiagent/onboarding/steps/StepTest.vue'
|
||||
|
||||
const SITE = 'https://teeckbox.com'
|
||||
const REASON = 'This site could not be found — the domain does not resolve.'
|
||||
const queue = (status: string) => ({
|
||||
queue_items: [{ id: 1, source: SITE, source_type: 'website', status, created_at: '',
|
||||
reason: status === 'failed' ? REASON : null }]
|
||||
})
|
||||
const knowledgePage = (count: number) => ({ knowledge: [], pagination: { total_count: count } })
|
||||
|
||||
const mountStep = async () => {
|
||||
const wrapper = mount(StepTest, { props: { agentId: 'agent-1', agentName: 'Rex', widgetId: 'w-1' } })
|
||||
await flushPromises()
|
||||
return wrapper
|
||||
}
|
||||
|
||||
describe('StepTest - what the agent knows', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
vi.useFakeTimers()
|
||||
})
|
||||
afterEach(() => vi.useRealTimers())
|
||||
|
||||
it('a crawl that fails after Teach says why, not "Knowledge indexed"', async () => {
|
||||
getAgentQueueItems.mockResolvedValueOnce(queue('pending')).mockResolvedValue(queue('failed'))
|
||||
getKnowledgeByAgent.mockResolvedValue(knowledgePage(0))
|
||||
const wrapper = await mountStep()
|
||||
expect(wrapper.text()).toContain('知识库仍在后台建立索引')
|
||||
|
||||
await vi.advanceTimersByTimeAsync(5000)
|
||||
await flushPromises()
|
||||
|
||||
expect(wrapper.text()).not.toContain('知识库已索引')
|
||||
expect(wrapper.text()).toContain(`无法读取 ${SITE}。${REASON}`)
|
||||
expect(wrapper.text()).toContain('它还完全不了解你的业务')
|
||||
})
|
||||
|
||||
it('a crawl that finishes says it is indexed', async () => {
|
||||
getAgentQueueItems.mockResolvedValueOnce(queue('pending')).mockResolvedValue(queue('completed'))
|
||||
getKnowledgeByAgent.mockResolvedValue(knowledgePage(1))
|
||||
const wrapper = await mountStep()
|
||||
|
||||
await vi.advanceTimersByTimeAsync(5000)
|
||||
await flushPromises()
|
||||
|
||||
expect(wrapper.text()).toContain('知识库已索引')
|
||||
})
|
||||
|
||||
it('arriving after the failure shows it too', async () => {
|
||||
getAgentQueueItems.mockResolvedValue(queue('failed'))
|
||||
getKnowledgeByAgent.mockResolvedValue(knowledgePage(0))
|
||||
const wrapper = await mountStep()
|
||||
expect(wrapper.text()).toContain(`无法读取 ${SITE}。`)
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user