```
refactor(core,ai): 调整模块导入路径并移除废弃文件 - 修复 scheduler.py 中的导入路径错误,将 reports.service 改为 reports.services - 移除废弃的 app/core/background/task_queue.py 文件 - 移除废弃的 app/modules/ai_agent/adapters.py 文件 - 修复 ai_memory/service.py 中的导入路径错误,将 events.service 改为 events.services ```
This commit is contained in:
85
app/modules/ai_agent/adapters/hermes.py
Normal file
85
app/modules/ai_agent/adapters/hermes.py
Normal file
@@ -0,0 +1,85 @@
|
||||
from typing import Any
|
||||
|
||||
from fastapi import HTTPException, status
|
||||
|
||||
from app.core.config import Settings
|
||||
from app.modules.ai_agent.adapters import httpx
|
||||
from app.modules.ai_agent.adapters.base import AIAdapter
|
||||
from app.modules.ai_agent.adapters.common import (
|
||||
_chat_completion_payload,
|
||||
_chat_messages,
|
||||
_response_payload,
|
||||
_service_root,
|
||||
)
|
||||
from app.modules.ai_agent.constants import (
|
||||
AUTHORIZATION_BEARER_TEMPLATE,
|
||||
UNEXPECTED_HERMES_RESPONSE,
|
||||
AIErrorKey,
|
||||
AIHttpHeader,
|
||||
AIHttpPath,
|
||||
AIHttpPayloadKey,
|
||||
AIProviderName,
|
||||
AIResponseKey,
|
||||
)
|
||||
|
||||
|
||||
class HermesAdapter(AIAdapter):
|
||||
"""Adapter for the Hermes OpenAI-compatible agent endpoint."""
|
||||
|
||||
provider_name = AIProviderName.HERMES
|
||||
|
||||
def __init__(self, settings: Settings):
|
||||
self.settings = settings
|
||||
|
||||
def ask(self, prompt: str, context: dict[str, Any] | None = None) -> dict[str, Any]:
|
||||
url = f"{self.settings.hermes_base_url.rstrip('/')}{AIHttpPath.CHAT_COMPLETIONS}"
|
||||
headers = {}
|
||||
if self.settings.hermes_api_key:
|
||||
headers[AIHttpHeader.AUTHORIZATION] = AUTHORIZATION_BEARER_TEMPLATE.format(
|
||||
token=self.settings.hermes_api_key
|
||||
)
|
||||
if self.settings.hermes_session_id:
|
||||
headers[AIHttpHeader.HERMES_SESSION_ID] = self.settings.hermes_session_id
|
||||
payload = {
|
||||
AIHttpPayloadKey.MODEL: self.settings.hermes_model,
|
||||
AIHttpPayloadKey.MESSAGES: _chat_messages(prompt, context),
|
||||
AIHttpPayloadKey.STREAM: False,
|
||||
}
|
||||
with httpx.Client(timeout=300, trust_env=False) as client:
|
||||
response = client.post(url, json=payload, headers=headers)
|
||||
if response.status_code >= status.HTTP_400_BAD_REQUEST:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_502_BAD_GATEWAY,
|
||||
detail={AIErrorKey.HERMES: response.text},
|
||||
)
|
||||
data = _chat_completion_payload(response, AIErrorKey.HERMES)
|
||||
try:
|
||||
answer = data[AIHttpPayloadKey.CHOICES][0][AIHttpPayloadKey.MESSAGE][
|
||||
AIHttpPayloadKey.CONTENT
|
||||
]
|
||||
except (KeyError, IndexError, TypeError) as exc:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_502_BAD_GATEWAY,
|
||||
detail={
|
||||
AIErrorKey.HERMES: UNEXPECTED_HERMES_RESPONSE,
|
||||
AIResponseKey.RAW: data,
|
||||
},
|
||||
) from exc
|
||||
return {AIResponseKey.ANSWER: answer, AIResponseKey.RAW: data}
|
||||
|
||||
def health(self) -> dict[str, Any]:
|
||||
"""Check Hermes Agent health without triggering a chat completion."""
|
||||
|
||||
url = f"{_service_root(self.settings.hermes_base_url, AIHttpPath.V1)}{AIHttpPath.HEALTH}"
|
||||
headers = {}
|
||||
if self.settings.hermes_api_key:
|
||||
headers[AIHttpHeader.AUTHORIZATION] = AUTHORIZATION_BEARER_TEMPLATE.format(
|
||||
token=self.settings.hermes_api_key
|
||||
)
|
||||
with httpx.Client(timeout=5, trust_env=False) as client:
|
||||
response = client.get(url, headers=headers)
|
||||
return {
|
||||
AIResponseKey.OK: response.status_code < status.HTTP_400_BAD_REQUEST,
|
||||
AIResponseKey.BASE_URL: self.settings.hermes_base_url.rstrip("/"),
|
||||
AIResponseKey.HEALTH: _response_payload(response),
|
||||
}
|
||||
Reference in New Issue
Block a user