feat: qualify native Hermes research and private conversation exports
This commit is contained in:
1 parent
fb3178d34b
commit
e048793b02
5 files changed
+206
-6
No files matched your search
@@ -361,6 +361,36 @@ class FeatureProvider:
|
||||
raise HTTPException(503, 'Hermes not ready')
|
||||
return user
|
||||
|
||||
async def toolset_status(self, owner):
|
||||
user = await self._account(owner)
|
||||
try:
|
||||
response = await self.http.get(user['hermes_url'].rstrip('/') + '/v1/toolsets', headers={'Authorization': 'Bearer ' + user['hermes_api_key']})
|
||||
if response.status_code != 200:
|
||||
raise ValueError()
|
||||
body = response.json()
|
||||
if not isinstance(body, dict) or not isinstance(body.get('data'), list):
|
||||
raise ValueError()
|
||||
return [{'name': row['name'], 'enabled': row.get('enabled') is True, 'configured': row.get('configured') is True,
|
||||
'tools': [tool for tool in row.get('tools', []) if isinstance(tool, str)][:200]}
|
||||
for row in body['data'][:100] if isinstance(row, dict) and isinstance(row.get('name'), str) and isinstance(row.get('tools'), list)]
|
||||
except Exception:
|
||||
raise HTTPException(503, 'Hermes tool capability status unavailable') from None
|
||||
|
||||
async def research_status(self, owner):
|
||||
toolsets = await self.toolset_status(owner)
|
||||
available = any(row['name'] == 'web' and row['enabled'] and row['configured'] and
|
||||
{'web_search', 'web_extract'} <= set(row['tools']) for row in toolsets)
|
||||
return {'available': available, 'mode': 'hermes_tools' if available else None,
|
||||
'reason': None if available else 'Hermes web search and extraction must be enabled and configured'}
|
||||
|
||||
async def research_instruction(self, owner):
|
||||
status = await self.research_status(owner)
|
||||
if not status['available']:
|
||||
raise HTTPException(409, 'Research tools are unavailable for this account')
|
||||
return ('Research mode requested by the user. Use your Hermes web search and extraction tools to investigate the question. '
|
||||
'Prefer primary sources, corroborate material claims, distinguish evidence from uncertainty, and cite source URLs in the final answer. '
|
||||
'Do not claim sources were checked if tools failed or access was unavailable. Complete this research in this same Hermes run.')
|
||||
|
||||
async def feature_capabilities(self, owner):
|
||||
await self._account(owner)
|
||||
settings = await asyncio.to_thread(self.accounts.get_model_settings, owner)
|
||||
@@ -372,8 +402,12 @@ class FeatureProvider:
|
||||
return True
|
||||
except HTTPException:
|
||||
return False
|
||||
try:
|
||||
research = (await self.research_status(owner))['available']
|
||||
except HTTPException:
|
||||
research = False
|
||||
return {'scheduled_tasks': True, 'memory_controls': await asyncio.to_thread(memory_available),
|
||||
'image_input': settings['model'] == 'auto', 'connectors': False, 'research': False}
|
||||
'image_input': settings['model'] == 'auto', 'connectors': False, 'research': research}
|
||||
|
||||
async def feature_request(self, owner, method, path, *, json=None, params=None):
|
||||
user = await self._account(owner)
|
||||
@@ -712,12 +746,24 @@ def create_feature_router(store, provider=None):
|
||||
@router.get('/api/connectors')
|
||||
async def connectors(user=Depends(current_user)):
|
||||
# The pinned gateway has no connector management API. Do not invent one.
|
||||
return {'connectors': [], 'available': False, 'reason': 'Hermes connector management API is not qualified'}
|
||||
statuses = []
|
||||
if provider is not None and hasattr(provider, 'toolset_status'):
|
||||
try:
|
||||
statuses = await provider.toolset_status(user['id'])
|
||||
except HTTPException:
|
||||
pass
|
||||
return {'connectors': [], 'available': False, 'reason': 'Pinned Hermes has no connector credential/settings write API',
|
||||
'toolsets': [{'name': row['name'], 'enabled': row['enabled'], 'configured': row['configured']} for row in statuses]}
|
||||
|
||||
@router.get('/api/research')
|
||||
async def research(user=Depends(current_user)):
|
||||
# Research remains normal Hermes execution, never a Hope reasoning loop.
|
||||
return {'available': False, 'reason': 'Dedicated research mode is not qualified; normal Hermes tool use remains available'}
|
||||
if provider is not None and hasattr(provider, 'research_status'):
|
||||
try:
|
||||
return await provider.research_status(user['id'])
|
||||
except HTTPException:
|
||||
pass
|
||||
return {'available': False, 'mode': None, 'reason': 'Hermes research tool availability could not be qualified'}
|
||||
|
||||
return router
|
||||
|
||||
|
||||
Reference in new issue
Block a user