feat: add skill and assistant knowledge bases
This commit is contained in:
1 parent
dd0ee282df
commit
fbd8dec48f
45 files changed
+5262
-21
No files matched your search
@@ -0,0 +1,96 @@
|
||||
import pytest
|
||||
import pytest_asyncio
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine
|
||||
|
||||
from deerflow.persistence.assistant_knowledge import AssistantKnowledgeRepository
|
||||
from deerflow.persistence.assistant_knowledge.model import (
|
||||
AssistantKnowledgeEntityContributionRow,
|
||||
AssistantKnowledgeEntityRow,
|
||||
)
|
||||
from deerflow.persistence.base import Base
|
||||
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
async def repository():
|
||||
engine = create_async_engine("sqlite+aiosqlite:///:memory:")
|
||||
async with engine.begin() as connection:
|
||||
await connection.run_sync(Base.metadata.create_all)
|
||||
yield AssistantKnowledgeRepository(async_sessionmaker(engine, expire_on_commit=False))
|
||||
await engine.dispose()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_single_base_entity_alignment_search_and_revision(repository: AssistantKnowledgeRepository) -> None:
|
||||
first = await repository.initialize(created_by="admin")
|
||||
second = await repository.initialize(created_by="someone-else")
|
||||
assert first["id"] == second["id"]
|
||||
|
||||
package = {
|
||||
"source": {"type": "skill"},
|
||||
"wiki_pages": [{"slug": "skills/demo/overview", "title": "示例知识", "content": "张三负责测试。"}],
|
||||
"entities": [{"local_id": "e1", "type": "person", "name": "张三", "aliases": ["Zhang San"]}],
|
||||
"relations": [],
|
||||
"documents": [],
|
||||
"chunks": [],
|
||||
"graph": {"nodes": [], "edges": []},
|
||||
}
|
||||
await repository.import_package(
|
||||
package=package,
|
||||
source_type="skill",
|
||||
source_key="demo",
|
||||
source_name="示例技能",
|
||||
trigger="skill_direct",
|
||||
created_by="admin",
|
||||
skill_name="demo",
|
||||
)
|
||||
await repository.import_package(
|
||||
package=package,
|
||||
source_type="weknora",
|
||||
source_key="kb-1",
|
||||
source_name="普通库",
|
||||
trigger="manual_from_weknora",
|
||||
created_by="admin",
|
||||
)
|
||||
|
||||
results = await repository.list_pages(query="张三")
|
||||
alias_results = await repository.list_pages(query="Zhang San")
|
||||
revisions = await repository.list_revisions("skills/demo/overview")
|
||||
assert {row["page_type"] for row in results} == {"source", "entity"}
|
||||
assert [row["page_type"] for row in alias_results] == ["entity"]
|
||||
assert len(revisions) == 2
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_delete_source_keeps_entity_until_last_contribution_is_removed(
|
||||
repository: AssistantKnowledgeRepository,
|
||||
) -> None:
|
||||
package = {
|
||||
"source": {},
|
||||
"wiki_pages": [],
|
||||
"entities": [{"local_id": "e1", "type": "concept", "name": "共享实体"}],
|
||||
"relations": [],
|
||||
}
|
||||
for source_key in ("one", "two"):
|
||||
await repository.import_package(
|
||||
package=package,
|
||||
source_type="skill",
|
||||
source_key=source_key,
|
||||
source_name=source_key,
|
||||
trigger="skill_direct",
|
||||
created_by="admin",
|
||||
skill_name=source_key,
|
||||
)
|
||||
|
||||
sources = await repository.list_sources()
|
||||
await repository.delete_source(next(row["id"] for row in sources if row["source_key"] == "one"))
|
||||
async with repository._sf() as session:
|
||||
entity = (await session.execute(select(AssistantKnowledgeEntityRow))).scalar_one()
|
||||
contributions = (await session.execute(select(AssistantKnowledgeEntityContributionRow))).scalars().all()
|
||||
assert entity.status == "active"
|
||||
assert len(contributions) == 1
|
||||
|
||||
await repository.delete_source(next(row["id"] for row in sources if row["source_key"] == "two"))
|
||||
async with repository._sf() as session:
|
||||
entity = (await session.execute(select(AssistantKnowledgeEntityRow))).scalar_one()
|
||||
assert entity.status == "deleted"
|
||||
Reference in new issue
Block a user