mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-07-17 01:46:07 +00:00
fix(agent-runner): close sandbox skill authoring flow
This commit is contained in:
@@ -169,7 +169,7 @@ class MonitoringService:
|
||||
)
|
||||
row = result.first()
|
||||
if row:
|
||||
return row[0]
|
||||
return row
|
||||
|
||||
if not session_id:
|
||||
return None
|
||||
@@ -188,7 +188,7 @@ class MonitoringService:
|
||||
result = await self.ap.persistence_mgr.execute_async(user_query)
|
||||
row = result.first()
|
||||
if row:
|
||||
return row[0]
|
||||
return row
|
||||
|
||||
any_query = (
|
||||
sqlalchemy.select(persistence_monitoring.MonitoringMessage)
|
||||
@@ -198,7 +198,7 @@ class MonitoringService:
|
||||
)
|
||||
result = await self.ap.persistence_mgr.execute_async(any_query)
|
||||
row = result.first()
|
||||
return row[0] if row else None
|
||||
return row
|
||||
|
||||
# ========== Recording Methods ==========
|
||||
|
||||
|
||||
@@ -574,9 +574,13 @@ else:
|
||||
)
|
||||
if self._should_use_box_workspace_files(selected_skill):
|
||||
return await self._write_workspace_via_box(path, content, parameters, query)
|
||||
os.makedirs(os.path.dirname(host_path), exist_ok=True)
|
||||
try:
|
||||
os.makedirs(os.path.dirname(host_path), exist_ok=True)
|
||||
self._write_host_file(host_path, content, parameters)
|
||||
except PermissionError:
|
||||
if selected_skill is None and hasattr(self.ap.box_service, 'execute_tool'):
|
||||
return await self._write_workspace_via_box(path, content, parameters, query)
|
||||
raise
|
||||
except ValueError as exc:
|
||||
return {'ok': False, 'error': str(exc)}
|
||||
self._refresh_skill_from_disk(selected_skill)
|
||||
@@ -625,18 +629,23 @@ else:
|
||||
)
|
||||
if self._should_use_box_workspace_files(selected_skill):
|
||||
return await self._edit_workspace_via_box(path, old_string, new_string, query)
|
||||
if not os.path.isfile(host_path):
|
||||
return {'ok': False, 'error': f'File not found: {path}'}
|
||||
with open(host_path, 'r', encoding='utf-8', errors='replace') as f:
|
||||
content = f.read()
|
||||
count = content.count(old_string)
|
||||
if count == 0:
|
||||
return {'ok': False, 'error': 'old_string not found in file.'}
|
||||
if count > 1:
|
||||
return {'ok': False, 'error': f'old_string matches {count} locations; provide a more unique string.'}
|
||||
new_content = content.replace(old_string, new_string, 1)
|
||||
with open(host_path, 'w', encoding='utf-8') as f:
|
||||
f.write(new_content)
|
||||
try:
|
||||
if not os.path.isfile(host_path):
|
||||
return {'ok': False, 'error': f'File not found: {path}'}
|
||||
with open(host_path, 'r', encoding='utf-8', errors='replace') as f:
|
||||
content = f.read()
|
||||
count = content.count(old_string)
|
||||
if count == 0:
|
||||
return {'ok': False, 'error': 'old_string not found in file.'}
|
||||
if count > 1:
|
||||
return {'ok': False, 'error': f'old_string matches {count} locations; provide a more unique string.'}
|
||||
new_content = content.replace(old_string, new_string, 1)
|
||||
with open(host_path, 'w', encoding='utf-8') as f:
|
||||
f.write(new_content)
|
||||
except PermissionError:
|
||||
if selected_skill is None and hasattr(self.ap.box_service, 'execute_tool'):
|
||||
return await self._edit_workspace_via_box(path, old_string, new_string, query)
|
||||
raise
|
||||
self._refresh_skill_from_disk(selected_skill)
|
||||
return {'ok': True, 'path': path}
|
||||
|
||||
|
||||
@@ -49,6 +49,18 @@ def get_visible_skill(ap: app.Application, query: pipeline_query.Query, skill_na
|
||||
return get_visible_skills(ap, query).get(skill_name)
|
||||
|
||||
|
||||
def register_created_skill_visibility(query: pipeline_query.Query, skill_name: str) -> None:
|
||||
"""Make a newly registered skill visible for the current Query only."""
|
||||
if not skill_name:
|
||||
return
|
||||
if getattr(query, 'variables', None) is None:
|
||||
query.variables = {}
|
||||
|
||||
bound_skills = query.variables.get(PIPELINE_BOUND_SKILLS_KEY)
|
||||
if isinstance(bound_skills, list) and skill_name not in bound_skills:
|
||||
bound_skills.append(skill_name)
|
||||
|
||||
|
||||
def get_activated_skills(query: pipeline_query.Query) -> dict[str, dict]:
|
||||
if query.variables is None:
|
||||
return {}
|
||||
|
||||
@@ -67,7 +67,7 @@ class SkillToolLoader(loader.ToolLoader):
|
||||
if name == ACTIVATE_SKILL_TOOL_NAME:
|
||||
return await self._invoke_activate_skill(parameters, query)
|
||||
if name == REGISTER_SKILL_TOOL_NAME:
|
||||
return await self._invoke_register_skill(parameters)
|
||||
return await self._invoke_register_skill(parameters, query)
|
||||
raise ValueError(f'Unknown skill tool: {name}')
|
||||
|
||||
async def shutdown(self):
|
||||
@@ -121,8 +121,10 @@ class SkillToolLoader(loader.ToolLoader):
|
||||
'content': result_content,
|
||||
}
|
||||
|
||||
async def _invoke_register_skill(self, parameters: dict) -> typing.Any:
|
||||
async def _invoke_register_skill(self, parameters: dict, query) -> typing.Any:
|
||||
"""Register a skill from sandbox directory to data/skills/."""
|
||||
from . import skill as skill_loader
|
||||
|
||||
sandbox_path = str(parameters.get('path', '') or '').strip()
|
||||
if not sandbox_path:
|
||||
raise ValueError('path is required')
|
||||
@@ -153,6 +155,7 @@ class SkillToolLoader(loader.ToolLoader):
|
||||
'package_root': host_path,
|
||||
}
|
||||
)
|
||||
skill_loader.register_created_skill_visibility(query, skill_name)
|
||||
|
||||
return {
|
||||
'registered': True,
|
||||
|
||||
Reference in New Issue
Block a user