Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions infra/scripts/post-provision/seed_knowledge_bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
- The caller needs "Search Service Contributor" role on the search service.
"""

import json
import os
import sys
from pathlib import Path
Expand All @@ -37,9 +36,12 @@
SEARCH_ENDPOINT = os.environ.get("AZURE_AI_SEARCH_ENDPOINT", "").rstrip("/")
AI_SERVICES_ENDPOINT = os.environ.get("AZURE_OPENAI_ENDPOINT", "").rstrip("/")

if not SEARCH_ENDPOINT:
print("ERROR: AZURE_AI_SEARCH_ENDPOINT must be set.")
sys.exit(1)

def _validate_required_env() -> None:
"""Validate required environment variables; exit(1) if missing."""
if not SEARCH_ENDPOINT:
print("ERROR: AZURE_AI_SEARCH_ENDPOINT must be set.")
sys.exit(1)

_SEARCH_SCOPE = "https://search.azure.com/.default"

Expand Down Expand Up @@ -384,6 +386,7 @@ def _parse_only_filter() -> set[str] | None:

def main() -> None:
"""Provision all knowledge bases."""
_validate_required_env()
print(f"Search endpoint: {SEARCH_ENDPOINT}")
print(f"AI services endpoint: {AI_SERVICES_ENDPOINT or '(not set — KB will have no model)'}")

Expand Down
11 changes: 9 additions & 2 deletions src/backend/api/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,13 @@ async def _heartbeat() -> None:
heartbeat_task.cancel()
try:
await heartbeat_task
except (asyncio.CancelledError, Exception):
except asyncio.CancelledError:
# Expected: we just cancelled the heartbeat task above.
pass
except Exception as e:
logging.debug(
f"Unexpected error awaiting cancelled heartbeat task for user {user_id}: {e}"
)
await connection_config.close_connection(process_id=process_id)


Expand Down Expand Up @@ -428,7 +433,9 @@ async def run_orchestration_task():
# Give the cancelled task a chance to clean up
await asyncio.sleep(0)
except Exception:
pass
logger.exception(
"Failed to cancel prior orchestration task for user '%s'", user_id
)
orchestration_config.active_tasks.pop(user_id, None)

# Schedule new task and register it so subsequent requests can cancel it
Expand Down
9 changes: 6 additions & 3 deletions src/backend/orchestration/orchestration_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -736,8 +736,12 @@ def _get_team_agent_names(workflow) -> list[str]:
]
if names:
return names
except Exception:
pass
except Exception as exc:
OrchestrationManager.logger.debug(
"Failed to read executor names from workflow; falling back to team config: %s",
exc,
exc_info=True,
)

team_config = getattr(workflow, "_team_config", None)
return [
Expand Down Expand Up @@ -914,7 +918,6 @@ async def _handle_tool_approvals(
Returns:
A ``{request_id: approval_response}`` dict.
"""
import json
import threading

from tools.clarification_tool import store_answer
Expand Down
1 change: 0 additions & 1 deletion src/backend/orchestration/plan_review_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ def get_magentic_prompt_kwargs(
"is INVALID — regenerate it\nuntil every listed agent appears as a step.\n"
)


scope_policy = """

TEAM SCOPE POLICY (CRITICAL — EVALUATE THIS FIRST, BEFORE ANY OTHER RULE):
Expand Down
1 change: 0 additions & 1 deletion src/tests/agents/test_agent_template_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
from pathlib import Path

import pytest
import pytest_asyncio

# ---------------------------------------------------------------------------
# Make sure 'src/backend' is on the path (covers running from repo root and
Expand Down
2 changes: 1 addition & 1 deletion src/tests/backend/agents/test_agent_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import logging
import sys
from types import SimpleNamespace
from unittest.mock import AsyncMock, Mock, patch
from unittest.mock import AsyncMock, Mock

import pytest

Expand Down
2 changes: 1 addition & 1 deletion src/tests/backend/common/database/test_database_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import os
import sys
from typing import Any, Dict, List, Optional, Type
from unittest.mock import AsyncMock, Mock, patch
from unittest.mock import Mock

import pytest

Expand Down
4 changes: 1 addition & 3 deletions src/tests/backend/common/utils/test_agent_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,8 @@
sys.modules['common.models'] = Mock()
sys.modules['common.models.messages'] = Mock()

import pytest

from backend.common.database.database_base import DatabaseBase
from backend.common.models.messages import (CurrentTeamAgent, DataType,
from backend.common.models.messages import (CurrentTeamAgent,
TeamConfiguration)
from backend.common.utils.agent_utils import (generate_assistant_id,
get_database_team_agent_id)
Expand Down
2 changes: 1 addition & 1 deletion src/tests/backend/common/utils/test_event_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import os
import sys
from pathlib import Path
from unittest.mock import MagicMock, Mock, patch
from unittest.mock import Mock, patch

import pytest

Expand Down
4 changes: 1 addition & 3 deletions src/tests/backend/middleware/test_health_check.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
"""Unit tests for backend.middleware.health_check module."""
import asyncio
import logging
from unittest.mock import AsyncMock, MagicMock, Mock, patch
from unittest.mock import AsyncMock, Mock, patch

import pytest

Expand Down
4 changes: 1 addition & 3 deletions src/tests/backend/models/test_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
import os
import sys

import pytest

# backend/models/messages.py has internal imports from common.models.messages
# and models.plan_models using paths relative to src/backend/. Add src/backend/
# to sys.path so those internal imports resolve when we load backend.models.messages.
Expand All @@ -24,7 +22,7 @@
ReplanApprovalResponse,
UserClarificationRequest,
UserClarificationResponse)
from backend.models.plan_models import MPlan, MStep, PlanStatus
from backend.models.plan_models import MPlan, PlanStatus


class TestAgentMessage:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@
- _process_event_stream() — event dispatch
"""

import asyncio
import logging
import os
import sys
from unittest.mock import AsyncMock, MagicMock, Mock, patch
from unittest.mock import AsyncMock, Mock, patch

import pytest

Expand Down
2 changes: 1 addition & 1 deletion src/tests/backend/services/test_mcp_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import os
import sys
from unittest.mock import AsyncMock, MagicMock, patch
from unittest.mock import MagicMock, patch

import pytest
from aiohttp import ClientError
Expand Down
3 changes: 1 addition & 2 deletions src/tests/backend/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import pytest
import sys
import os
from unittest.mock import Mock, AsyncMock, MagicMock, patch, NonCallableMock
from unittest.mock import Mock, AsyncMock, MagicMock, patch

# Environment variables are set by conftest.py, but ensure they're available
os.environ.setdefault("APPLICATIONINSIGHTS_CONNECTION_STRING", "InstrumentationKey=test-key-12345")
Expand Down Expand Up @@ -47,7 +47,6 @@
del sys.modules[_ma_key]

# Mock external dependencies that may not be installed in test environment
from fastapi import APIRouter

# Mock azure.monitor.opentelemetry module
mock_azure_monitor_module = ModuleType('configure_azure_monitor')
Expand Down
3 changes: 2 additions & 1 deletion test_mcp_tools.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Quick test to list MCP tools on /hr/mcp."""
import json
import sys

import httpx

Expand Down Expand Up @@ -31,7 +32,7 @@

if not sid:
print("No session ID, aborting")
exit(1)
sys.exit(1)

# 2. List tools
HEADERS["mcp-session-id"] = sid
Expand Down