mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-06-26 21:39:43 +02:00
chore; linting
This commit is contained in:
parent
70686a1eb2
commit
d198c8b89d
16 changed files with 228 additions and 167 deletions
|
|
@ -12,7 +12,12 @@ import asyncio
|
|||
import logging
|
||||
import os
|
||||
|
||||
from daytona import CreateSandboxFromSnapshotParams, Daytona, DaytonaConfig, SandboxState
|
||||
from daytona import (
|
||||
CreateSandboxFromSnapshotParams,
|
||||
Daytona,
|
||||
DaytonaConfig,
|
||||
SandboxState,
|
||||
)
|
||||
from deepagents.backends.protocol import ExecuteResponse
|
||||
from langchain_daytona import DaytonaSandbox
|
||||
|
||||
|
|
@ -38,9 +43,12 @@ class _TimeoutAwareSandbox(DaytonaSandbox):
|
|||
truncated=False,
|
||||
)
|
||||
|
||||
async def aexecute(self, command: str, *, timeout: int | None = None) -> ExecuteResponse: # type: ignore[override]
|
||||
async def aexecute(
|
||||
self, command: str, *, timeout: int | None = None
|
||||
) -> ExecuteResponse: # type: ignore[override]
|
||||
return await asyncio.to_thread(self.execute, command, timeout=timeout)
|
||||
|
||||
|
||||
_daytona_client: Daytona | None = None
|
||||
THREAD_LABEL_KEY = "surfsense_thread"
|
||||
|
||||
|
|
@ -72,9 +80,7 @@ def _find_or_create(thread_id: str) -> _TimeoutAwareSandbox:
|
|||
|
||||
try:
|
||||
sandbox = client.find_one(labels=labels)
|
||||
logger.info(
|
||||
"Found existing sandbox %s (state=%s)", sandbox.id, sandbox.state
|
||||
)
|
||||
logger.info("Found existing sandbox %s (state=%s)", sandbox.id, sandbox.state)
|
||||
|
||||
if sandbox.state in (
|
||||
SandboxState.STOPPED,
|
||||
|
|
@ -84,7 +90,11 @@ def _find_or_create(thread_id: str) -> _TimeoutAwareSandbox:
|
|||
logger.info("Starting stopped sandbox %s …", sandbox.id)
|
||||
sandbox.start(timeout=60)
|
||||
logger.info("Sandbox %s is now started", sandbox.id)
|
||||
elif sandbox.state in (SandboxState.ERROR, SandboxState.BUILD_FAILED, SandboxState.DESTROYED):
|
||||
elif sandbox.state in (
|
||||
SandboxState.ERROR,
|
||||
SandboxState.BUILD_FAILED,
|
||||
SandboxState.DESTROYED,
|
||||
):
|
||||
logger.warning(
|
||||
"Sandbox %s in unrecoverable state %s — creating a new one",
|
||||
sandbox.id,
|
||||
|
|
|
|||
|
|
@ -782,7 +782,12 @@ def build_surfsense_system_prompt(
|
|||
tools_instructions = _get_tools_instructions(visibility)
|
||||
citation_instructions = SURFSENSE_CITATION_INSTRUCTIONS
|
||||
sandbox_instructions = SANDBOX_EXECUTION_INSTRUCTIONS if sandbox_enabled else ""
|
||||
return system_instructions + tools_instructions + citation_instructions + sandbox_instructions
|
||||
return (
|
||||
system_instructions
|
||||
+ tools_instructions
|
||||
+ citation_instructions
|
||||
+ sandbox_instructions
|
||||
)
|
||||
|
||||
|
||||
def build_configurable_system_prompt(
|
||||
|
|
@ -842,7 +847,12 @@ def build_configurable_system_prompt(
|
|||
|
||||
sandbox_instructions = SANDBOX_EXECUTION_INSTRUCTIONS if sandbox_enabled else ""
|
||||
|
||||
return system_instructions + tools_instructions + citation_instructions + sandbox_instructions
|
||||
return (
|
||||
system_instructions
|
||||
+ tools_instructions
|
||||
+ citation_instructions
|
||||
+ sandbox_instructions
|
||||
)
|
||||
|
||||
|
||||
def get_default_system_instructions() -> str:
|
||||
|
|
|
|||
|
|
@ -58,7 +58,9 @@ def create_create_google_drive_file_tool(
|
|||
- "Create a Google Doc called 'Meeting Notes'"
|
||||
- "Create a spreadsheet named 'Budget 2026' with some sample data"
|
||||
"""
|
||||
logger.info(f"create_google_drive_file called: name='{name}', type='{file_type}'")
|
||||
logger.info(
|
||||
f"create_google_drive_file called: name='{name}', type='{file_type}'"
|
||||
)
|
||||
|
||||
if db_session is None or search_space_id is None or user_id is None:
|
||||
return {
|
||||
|
|
@ -74,7 +76,9 @@ def create_create_google_drive_file_tool(
|
|||
|
||||
try:
|
||||
metadata_service = GoogleDriveToolMetadataService(db_session)
|
||||
context = await metadata_service.get_creation_context(search_space_id, user_id)
|
||||
context = await metadata_service.get_creation_context(
|
||||
search_space_id, user_id
|
||||
)
|
||||
|
||||
if "error" in context:
|
||||
logger.error(f"Failed to fetch creation context: {context['error']}")
|
||||
|
|
@ -100,8 +104,12 @@ def create_create_google_drive_file_tool(
|
|||
}
|
||||
)
|
||||
|
||||
decisions_raw = approval.get("decisions", []) if isinstance(approval, dict) else []
|
||||
decisions = decisions_raw if isinstance(decisions_raw, list) else [decisions_raw]
|
||||
decisions_raw = (
|
||||
approval.get("decisions", []) if isinstance(approval, dict) else []
|
||||
)
|
||||
decisions = (
|
||||
decisions_raw if isinstance(decisions_raw, list) else [decisions_raw]
|
||||
)
|
||||
decisions = [d for d in decisions if isinstance(d, dict)]
|
||||
if not decisions:
|
||||
logger.warning("No approval decision received")
|
||||
|
|
@ -183,7 +191,9 @@ def create_create_google_drive_file_tool(
|
|||
logger.info(
|
||||
f"Creating Google Drive file: name='{final_name}', type='{final_file_type}', connector={actual_connector_id}"
|
||||
)
|
||||
client = GoogleDriveClient(session=db_session, connector_id=actual_connector_id)
|
||||
client = GoogleDriveClient(
|
||||
session=db_session, connector_id=actual_connector_id
|
||||
)
|
||||
try:
|
||||
created = await client.create_file(
|
||||
name=final_name,
|
||||
|
|
@ -203,7 +213,9 @@ def create_create_google_drive_file_tool(
|
|||
}
|
||||
raise
|
||||
|
||||
logger.info(f"Google Drive file created: id={created.get('id')}, name={created.get('name')}")
|
||||
logger.info(
|
||||
f"Google Drive file created: id={created.get('id')}, name={created.get('name')}"
|
||||
)
|
||||
return {
|
||||
"status": "success",
|
||||
"file_id": created.get("id"),
|
||||
|
|
|
|||
|
|
@ -52,7 +52,9 @@ def create_delete_google_drive_file_tool(
|
|||
- "Delete the 'Meeting Notes' file from Google Drive"
|
||||
- "Trash the 'Old Budget' spreadsheet"
|
||||
"""
|
||||
logger.info(f"delete_google_drive_file called: file_name='{file_name}', delete_from_kb={delete_from_kb}")
|
||||
logger.info(
|
||||
f"delete_google_drive_file called: file_name='{file_name}', delete_from_kb={delete_from_kb}"
|
||||
)
|
||||
|
||||
if db_session is None or search_space_id is None or user_id is None:
|
||||
return {
|
||||
|
|
@ -103,8 +105,12 @@ def create_delete_google_drive_file_tool(
|
|||
}
|
||||
)
|
||||
|
||||
decisions_raw = approval.get("decisions", []) if isinstance(approval, dict) else []
|
||||
decisions = decisions_raw if isinstance(decisions_raw, list) else [decisions_raw]
|
||||
decisions_raw = (
|
||||
approval.get("decisions", []) if isinstance(approval, dict) else []
|
||||
)
|
||||
decisions = (
|
||||
decisions_raw if isinstance(decisions_raw, list) else [decisions_raw]
|
||||
)
|
||||
decisions = [d for d in decisions if isinstance(d, dict)]
|
||||
if not decisions:
|
||||
logger.warning("No approval decision received")
|
||||
|
|
@ -130,11 +136,16 @@ def create_delete_google_drive_file_tool(
|
|||
final_params = decision["args"]
|
||||
|
||||
final_file_id = final_params.get("file_id", file_id)
|
||||
final_connector_id = final_params.get("connector_id", connector_id_from_context)
|
||||
final_connector_id = final_params.get(
|
||||
"connector_id", connector_id_from_context
|
||||
)
|
||||
final_delete_from_kb = final_params.get("delete_from_kb", delete_from_kb)
|
||||
|
||||
if not final_connector_id:
|
||||
return {"status": "error", "message": "No connector found for this file."}
|
||||
return {
|
||||
"status": "error",
|
||||
"message": "No connector found for this file.",
|
||||
}
|
||||
|
||||
from sqlalchemy.future import select
|
||||
|
||||
|
|
@ -174,7 +185,9 @@ def create_delete_google_drive_file_tool(
|
|||
}
|
||||
raise
|
||||
|
||||
logger.info(f"Google Drive file deleted (moved to trash): file_id={final_file_id}")
|
||||
logger.info(
|
||||
f"Google Drive file deleted (moved to trash): file_id={final_file_id}"
|
||||
)
|
||||
|
||||
trash_result: dict[str, Any] = {
|
||||
"status": "success",
|
||||
|
|
@ -195,7 +208,9 @@ def create_delete_google_drive_file_tool(
|
|||
await db_session.delete(document)
|
||||
await db_session.commit()
|
||||
deleted_from_kb = True
|
||||
logger.info(f"Deleted document {document_id} from knowledge base")
|
||||
logger.info(
|
||||
f"Deleted document {document_id} from knowledge base"
|
||||
)
|
||||
else:
|
||||
logger.warning(f"Document {document_id} not found in KB")
|
||||
except Exception as e:
|
||||
|
|
|
|||
|
|
@ -47,6 +47,10 @@ from app.db import ChatVisibility
|
|||
|
||||
from .display_image import create_display_image_tool
|
||||
from .generate_image import create_generate_image_tool
|
||||
from .google_drive import (
|
||||
create_create_google_drive_file_tool,
|
||||
create_delete_google_drive_file_tool,
|
||||
)
|
||||
from .knowledge_base import create_search_knowledge_base_tool
|
||||
from .linear import (
|
||||
create_create_linear_issue_tool,
|
||||
|
|
@ -55,10 +59,6 @@ from .linear import (
|
|||
)
|
||||
from .link_preview import create_link_preview_tool
|
||||
from .mcp_tool import load_mcp_tools
|
||||
from .google_drive import (
|
||||
create_create_google_drive_file_tool,
|
||||
create_delete_google_drive_file_tool,
|
||||
)
|
||||
from .notion import (
|
||||
create_create_notion_page_tool,
|
||||
create_delete_notion_page_tool,
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ async def download_sandbox_file(
|
|||
|
||||
try:
|
||||
sandbox = await get_or_create_sandbox(thread_id)
|
||||
raw_sandbox = sandbox._sandbox # noqa: SLF001
|
||||
raw_sandbox = sandbox._sandbox
|
||||
content: bytes = await asyncio.to_thread(raw_sandbox.fs.download_file, path)
|
||||
except Exception as exc:
|
||||
logger.warning("Sandbox file download failed for %s: %s", path, exc)
|
||||
|
|
|
|||
|
|
@ -10,14 +10,13 @@ Supports loading LLM configurations from:
|
|||
"""
|
||||
|
||||
import json
|
||||
import logging
|
||||
import re
|
||||
from collections.abc import AsyncGenerator
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
from uuid import UUID
|
||||
|
||||
import logging
|
||||
|
||||
from langchain_core.messages import HumanMessage
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.future import select
|
||||
|
|
@ -31,7 +30,13 @@ from app.agents.new_chat.llm_config import (
|
|||
load_agent_config,
|
||||
load_llm_config_from_yaml,
|
||||
)
|
||||
from app.db import ChatVisibility, Document, Report, SurfsenseDocsDocument, async_session_maker
|
||||
from app.db import (
|
||||
ChatVisibility,
|
||||
Document,
|
||||
Report,
|
||||
SurfsenseDocsDocument,
|
||||
async_session_maker,
|
||||
)
|
||||
from app.prompts import TITLE_GENERATION_PROMPT_TEMPLATE
|
||||
from app.services.chat_session_state_service import (
|
||||
clear_ai_responding,
|
||||
|
|
@ -645,9 +650,15 @@ async def _stream_agent_events(
|
|||
m = re.match(r"^Exit code:\s*(\d+)", raw_text)
|
||||
exit_code_val = int(m.group(1)) if m else None
|
||||
if exit_code_val is not None and exit_code_val == 0:
|
||||
completed_items = [*last_active_step_items, "Completed successfully"]
|
||||
completed_items = [
|
||||
*last_active_step_items,
|
||||
"Completed successfully",
|
||||
]
|
||||
elif exit_code_val is not None:
|
||||
completed_items = [*last_active_step_items, f"Exit code: {exit_code_val}"]
|
||||
completed_items = [
|
||||
*last_active_step_items,
|
||||
f"Exit code: {exit_code_val}",
|
||||
]
|
||||
else:
|
||||
completed_items = [*last_active_step_items, "Finished"]
|
||||
yield streaming_service.format_thinking_step(
|
||||
|
|
@ -1037,13 +1048,18 @@ async def stream_new_chat(
|
|||
|
||||
# Optionally provision a sandboxed code execution environment
|
||||
sandbox_backend = None
|
||||
from app.agents.new_chat.sandbox import is_sandbox_enabled, get_or_create_sandbox
|
||||
from app.agents.new_chat.sandbox import (
|
||||
get_or_create_sandbox,
|
||||
is_sandbox_enabled,
|
||||
)
|
||||
|
||||
if is_sandbox_enabled():
|
||||
try:
|
||||
sandbox_backend = await get_or_create_sandbox(chat_id)
|
||||
except Exception as sandbox_err:
|
||||
logging.getLogger(__name__).warning(
|
||||
"Sandbox creation failed, continuing without execute tool: %s", sandbox_err
|
||||
"Sandbox creation failed, continuing without execute tool: %s",
|
||||
sandbox_err,
|
||||
)
|
||||
|
||||
visibility = thread_visibility or ChatVisibility.PRIVATE
|
||||
|
|
@ -1426,13 +1442,18 @@ async def stream_resume_chat(
|
|||
checkpointer = await get_checkpointer()
|
||||
|
||||
sandbox_backend = None
|
||||
from app.agents.new_chat.sandbox import is_sandbox_enabled, get_or_create_sandbox
|
||||
from app.agents.new_chat.sandbox import (
|
||||
get_or_create_sandbox,
|
||||
is_sandbox_enabled,
|
||||
)
|
||||
|
||||
if is_sandbox_enabled():
|
||||
try:
|
||||
sandbox_backend = await get_or_create_sandbox(chat_id)
|
||||
except Exception as sandbox_err:
|
||||
logging.getLogger(__name__).warning(
|
||||
"Sandbox creation failed, continuing without execute tool: %s", sandbox_err
|
||||
"Sandbox creation failed, continuing without execute tool: %s",
|
||||
sandbox_err,
|
||||
)
|
||||
|
||||
visibility = thread_visibility or ChatVisibility.PRIVATE
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue