feat(agent): 接入 Skill Plugin 与知识库工具

This commit is contained in:
2026-08-27 23:53:04 +08:00
parent e045b9ce8b
commit cc17070e9e
6 changed files with 465 additions and 58 deletions
+152 -18
View File
@@ -1,7 +1,9 @@
from pydantic import BaseModel, ConfigDict
from pydantic import BaseModel, ConfigDict, Field
from app.agent.tools import ToolExecutionContext, ToolRegistry
from app.contracts import ToolDefinition
from app.contracts import SearchMode, SearchRequest, ToolDefinition
from app.retrieval.engine import engine
from app.services import note_service
class ToolArguments(BaseModel):
@@ -17,6 +19,41 @@ class AddArguments(ToolArguments):
right: float
class NoteSearchArguments(ToolArguments):
query: str = Field(min_length=1)
mode: SearchMode = SearchMode.hybrid
folders: list[str] = Field(default_factory=list)
note_ids: list[str] = Field(default_factory=list)
tags: list[str] = Field(default_factory=list)
limit: int = Field(default=10, ge=1, le=100)
offset: int = Field(default=0, ge=0)
class NoteReadArguments(ToolArguments):
note_id: str = Field(min_length=1)
class NoteCreateArguments(ToolArguments):
title: str = Field(min_length=1)
markdown: str = ""
folder: str | None = None
tags: list[str] = Field(default_factory=list)
class NoteUpdateArguments(ToolArguments):
note_id: str = Field(min_length=1)
title: str | None = None
markdown: str | None = None
tags: list[str] | None = None
class NoteListArguments(ToolArguments):
limit: int = Field(default=50, ge=1, le=100)
offset: int = Field(default=0, ge=0)
folder: str | None = None
tag: str | None = None
async def echo(arguments: EchoArguments, _: ToolExecutionContext) -> dict[str, str]:
return {"text": arguments.text}
@@ -25,22 +62,119 @@ async def add(arguments: AddArguments, _: ToolExecutionContext) -> dict[str, flo
return {"value": arguments.left + arguments.right}
async def search_notes(arguments: NoteSearchArguments, _: ToolExecutionContext) -> dict:
request = SearchRequest(**arguments.model_dump(), include_snippet=True)
return (await engine.search(request)).model_dump(mode="json")
async def read_note(arguments: NoteReadArguments, _: ToolExecutionContext) -> dict:
note = await note_service.get_note(arguments.note_id)
if note is None:
raise LookupError(f"Note does not exist: {arguments.note_id}")
return note.model_dump(mode="json")
async def create_note(arguments: NoteCreateArguments, _: ToolExecutionContext) -> dict:
note = await note_service.create_note(**arguments.model_dump())
return note.model_dump(mode="json")
async def update_note(arguments: NoteUpdateArguments, _: ToolExecutionContext) -> dict:
values = arguments.model_dump()
note_id = values.pop("note_id")
note = await note_service.update_note(note_id, **values)
return note.model_dump(mode="json")
def list_notes(arguments: NoteListArguments, _: ToolExecutionContext) -> dict:
items, total = note_service.list_notes(**arguments.model_dump())
return {
"items": [item.model_dump(mode="json") for item in items],
"page": {"total": total, "limit": arguments.limit, "offset": arguments.offset},
}
def _register(
registry: ToolRegistry,
*,
name: str,
description: str,
arguments_model: type[BaseModel],
executor,
permission: str | None = None,
) -> None:
registry.register(
ToolDefinition(
name=name,
description=description,
parameters=arguments_model.model_json_schema(),
permission=permission,
),
arguments_model,
executor,
)
def register_builtin_tools(registry: ToolRegistry) -> None:
registry.register(
ToolDefinition(
name="system.echo",
description="Echo text for local Agent integration testing.",
parameters=EchoArguments.model_json_schema(),
),
EchoArguments,
echo,
_register(
registry,
name="system.echo",
description="Echo text for local Agent integration testing.",
arguments_model=EchoArguments,
executor=echo,
)
registry.register(
ToolDefinition(
name="math.add",
description="Add two numbers without external side effects.",
parameters=AddArguments.model_json_schema(),
),
AddArguments,
add,
_register(
registry,
name="math.add",
description="Add two numbers without external side effects.",
arguments_model=AddArguments,
executor=add,
)
_register(
registry,
name="notes.search",
description="Search indexed notes and return snippets with citations.",
arguments_model=NoteSearchArguments,
executor=search_notes,
permission="notes.search",
)
_register(
registry,
name="rag.search",
description="Retrieve relevant note blocks for Agent context with citations.",
arguments_model=NoteSearchArguments,
executor=search_notes,
permission="notes.search",
)
_register(
registry,
name="notes.read",
description="Read a note and its parsed blocks by note_id.",
arguments_model=NoteReadArguments,
executor=read_note,
permission="notes.read",
)
_register(
registry,
name="notes.create",
description="Create a Markdown note in the current Vault.",
arguments_model=NoteCreateArguments,
executor=create_note,
permission="notes.write",
)
_register(
registry,
name="notes.update",
description="Update an existing Markdown note.",
arguments_model=NoteUpdateArguments,
executor=update_note,
permission="notes.write",
)
_register(
registry,
name="notes.list",
description="List note summaries with folder and tag filters.",
arguments_model=NoteListArguments,
executor=list_notes,
permission="notes.read",
)