Merge branch 'ji'

This commit is contained in:
吉鑫升 committed 2026-06-11 19:59:58 +08:00
commit 82600a3404
25 files changed
+929 -279

No files matched your search

@@ -864,9 +864,12 @@ async def update_agent(agent_id: str, request: AgentUpdateRequest, http_request:
tool_groups=next_tool_groups,
common_questions=next_common_questions,
)
# Keep the listing cache in lock-step with config.yaml on every write.
await store.replace_skills(agent_id, next_skills)
await store.set_extras(agent_id, tool_groups=next_tool_groups, model=next_model)
# Keep the listing cache in lock-step with config.yaml, but only
# when the cached fields were actually touched — a partial update
# (e.g. 常用问题 only) skips the DELETE/INSERT churn.
if any(key in fields_set for key in ("skills", "model", "tool_groups")):
await store.replace_skills(agent_id, next_skills)
await store.set_extras(agent_id, tool_groups=next_tool_groups, model=next_model)
if request.soul is not None:
_write_agent_soul(agent_id, request.soul)
@@ -571,6 +571,37 @@ async def get_graph(request: Request) -> dict[str, Any]:
return await service.get_graph()
class GraphBlacklistAddRequest(BaseModel):
labels: list[str] = Field(default_factory=list)
@router.get("/graph/blacklist")
@require_auth
async def list_graph_blacklist(request: Request) -> dict[str, Any]:
"""Return blacklisted graph node labels (hidden from the graph)."""
service = get_knowledge_service(request)
return {"items": await service.list_graph_blacklist()}
@router.post("/graph/blacklist")
@require_auth
async def add_graph_blacklist(body: GraphBlacklistAddRequest, request: Request) -> dict[str, Any]:
"""Blacklist node labels (entity names / note titles); they disappear from the graph."""
service = get_knowledge_service(request)
added = await service.add_graph_blacklist(body.labels, created_by=get_effective_user_id())
return {"added": added, "items": await service.list_graph_blacklist()}
@router.delete("/graph/blacklist/{entry_id}")
@require_auth
async def remove_graph_blacklist(entry_id: str, request: Request) -> dict[str, Any]:
"""Remove a blacklist entry so the node shows up in the graph again."""
service = get_knowledge_service(request)
if not await service.remove_graph_blacklist(entry_id):
raise HTTPException(status_code=404, detail="Blacklist entry not found")
return {"ok": True}
@router.post("/export/graph")
@require_auth
async def export_graph(request: Request) -> dict[str, Any]:
@@ -173,6 +173,7 @@ class ThreadSearchRequest(BaseModel):
limit: int = Field(default=100, ge=1, le=1000, description="Maximum results")
offset: int = Field(default=0, ge=0, description="Pagination offset")
status: str | None = Field(default=None, description="Filter by thread status")
query: str | None = Field(default=None, description="Case-insensitive substring match on the thread title")
class ThreadStateResponse(BaseModel):
@@ -660,11 +661,19 @@ async def search_threads(body: ThreadSearchRequest, request: Request) -> list[Th
from app.gateway.deps import get_thread_store
repo = get_thread_store(request)
# System threads (scheduler runs, roundtable workers, …) carry
# ``metadata.system=true`` and are machine-created — hide them from the
# default conversation list so they don't crowd out real chats. A caller
# that explicitly filters on ``thread_type``/``system`` (e.g. the studio
# notebook list) opts out of the exclusion.
explicit_system_filter = bool(body.metadata) and ("thread_type" in body.metadata or "system" in body.metadata)
rows = await repo.search(
metadata=body.metadata or None,
status=body.status,
limit=body.limit,
offset=body.offset,
exclude_system=not explicit_system_filter,
query=body.query,
)
return [
ThreadResponse(