diff --git a/enterprise/saas_server.py b/enterprise/saas_server.py index 96e19a9815..4eaf4a6439 100644 --- a/enterprise/saas_server.py +++ b/enterprise/saas_server.py @@ -37,6 +37,8 @@ from server.routes.mcp_patch import patch_mcp_server # noqa: E402 from server.routes.oauth_device import oauth_device_router # noqa: E402 from server.routes.readiness import readiness_router # noqa: E402 from server.routes.user import saas_user_router # noqa: E402 +from server.sharing.shared_conversation_router import router as shared_conversation_router # noqa: E402 +from server.sharing.shared_event_router import router as shared_event_router # noqa: E402 from openhands.server.app import app as base_app # noqa: E402 from openhands.server.listen_socket import sio # noqa: E402 @@ -66,6 +68,8 @@ base_app.include_router(saas_user_router) # Add additional route SAAS user call base_app.include_router( billing_router ) # Add routes for credit management and Stripe payment integration +base_app.include_router(shared_conversation_router) +base_app.include_router(shared_event_router) # Add GitHub integration router only if GITHUB_APP_CLIENT_ID is set if GITHUB_APP_CLIENT_ID: @@ -99,6 +103,7 @@ base_app.include_router( event_webhook_router ) # Add routes for Events in nested runtimes + base_app.add_middleware( CORSMiddleware, allow_origins=PERMITTED_CORS_ORIGINS, diff --git a/openhands/app_server/sharing/README.md b/enterprise/server/sharing/README.md similarity index 100% rename from openhands/app_server/sharing/README.md rename to enterprise/server/sharing/README.md diff --git a/openhands/app_server/sharing/filesystem_shared_event_service.py b/enterprise/server/sharing/filesystem_shared_event_service.py similarity index 97% rename from openhands/app_server/sharing/filesystem_shared_event_service.py rename to enterprise/server/sharing/filesystem_shared_event_service.py index 556ebca1a5..2042d40c97 100644 --- a/openhands/app_server/sharing/filesystem_shared_event_service.py +++ b/enterprise/server/sharing/filesystem_shared_event_service.py @@ -20,10 +20,10 @@ from openhands.agent_server.models import EventPage, EventSortOrder from openhands.app_server.event.event_service import EventService from openhands.app_server.event_callback.event_callback_models import EventKind from openhands.app_server.services.injector import InjectorState -from openhands.app_server.sharing.shared_conversation_info_service import ( +from server.sharing.shared_conversation_info_service import ( SharedConversationInfoService, ) -from openhands.app_server.sharing.shared_event_service import ( +from server.sharing.shared_event_service import ( SharedEventService, SharedEventServiceInjector, ) diff --git a/openhands/app_server/sharing/shared_conversation_info_service.py b/enterprise/server/sharing/shared_conversation_info_service.py similarity index 96% rename from openhands/app_server/sharing/shared_conversation_info_service.py rename to enterprise/server/sharing/shared_conversation_info_service.py index 62a836301f..bd2842fcff 100644 --- a/openhands/app_server/sharing/shared_conversation_info_service.py +++ b/enterprise/server/sharing/shared_conversation_info_service.py @@ -4,7 +4,7 @@ from datetime import datetime from uuid import UUID from openhands.app_server.services.injector import Injector -from openhands.app_server.sharing.shared_conversation_models import ( +from server.sharing.shared_conversation_models import ( SharedConversation, SharedConversationPage, SharedConversationSortOrder, diff --git a/openhands/app_server/sharing/shared_conversation_models.py b/enterprise/server/sharing/shared_conversation_models.py similarity index 100% rename from openhands/app_server/sharing/shared_conversation_models.py rename to enterprise/server/sharing/shared_conversation_models.py diff --git a/openhands/app_server/sharing/shared_conversation_router.py b/enterprise/server/sharing/shared_conversation_router.py similarity index 87% rename from openhands/app_server/sharing/shared_conversation_router.py rename to enterprise/server/sharing/shared_conversation_router.py index 3d6e80c212..7ad941f94b 100644 --- a/openhands/app_server/sharing/shared_conversation_router.py +++ b/enterprise/server/sharing/shared_conversation_router.py @@ -4,21 +4,22 @@ from datetime import datetime from typing import Annotated from uuid import UUID -from fastapi import APIRouter, Query +from fastapi import APIRouter, Depends, Query -from openhands.app_server.config import depends_shared_conversation_info_service -from openhands.app_server.sharing.shared_conversation_info_service import ( +from enterprise.server.sharing.sql_shared_conversation_info_service import SQLSharedConversationInfoServiceInjector +from server.sharing.shared_conversation_info_service import ( SharedConversationInfoService, ) -from openhands.app_server.sharing.shared_conversation_models import ( +from server.sharing.shared_conversation_models import ( SharedConversation, SharedConversationPage, SharedConversationSortOrder, ) -router = APIRouter(prefix='/shared-conversations', tags=['Sharing']) -shared_conversation_service_dependency = depends_shared_conversation_info_service() - +router = APIRouter(prefix='/api/shared-conversations', tags=['Sharing']) +shared_conversation_info_service_dependency = Depends( + SQLSharedConversationInfoServiceInjector().depends +) # Read methods @@ -67,7 +68,7 @@ async def search_shared_conversations( title='If True, include sub-conversations in the results. If False (default), exclude all sub-conversations.' ), ] = False, - shared_conversation_service: SharedConversationInfoService = shared_conversation_service_dependency, + shared_conversation_service: SharedConversationInfoService = shared_conversation_info_service_dependency, ) -> SharedConversationPage: """Search / List shared conversations.""" assert limit > 0 @@ -107,7 +108,7 @@ async def count_shared_conversations( datetime | None, Query(title='Filter by updated_at less than this datetime'), ] = None, - shared_conversation_service: SharedConversationInfoService = shared_conversation_service_dependency, + shared_conversation_service: SharedConversationInfoService = shared_conversation_info_service_dependency, ) -> int: """Count shared conversations matching the given filters.""" return await shared_conversation_service.count_shared_conversation_info( @@ -122,7 +123,7 @@ async def count_shared_conversations( @router.get('') async def batch_get_shared_conversations( ids: Annotated[list[str], Query()], - shared_conversation_service: SharedConversationInfoService = shared_conversation_service_dependency, + shared_conversation_service: SharedConversationInfoService = shared_conversation_info_service_dependency, ) -> list[SharedConversation | None]: """Get a batch of shared conversations given their ids. Return None for any missing or non-shared.""" assert len(ids) <= 100 diff --git a/openhands/app_server/sharing/shared_event_router.py b/enterprise/server/sharing/shared_event_router.py similarity index 91% rename from openhands/app_server/sharing/shared_event_router.py rename to enterprise/server/sharing/shared_event_router.py index 9daf01893e..c2179b6920 100644 --- a/openhands/app_server/sharing/shared_event_router.py +++ b/enterprise/server/sharing/shared_event_router.py @@ -4,16 +4,18 @@ from datetime import datetime from typing import Annotated from uuid import UUID -from fastapi import APIRouter, Query +from fastapi import APIRouter, Depends, Query from openhands.agent_server.models import EventPage, EventSortOrder -from openhands.app_server.config import depends_shared_event_service +from enterprise.server.sharing.filesystem_shared_event_service import SharedEventServiceImplInjector from openhands.app_server.event_callback.event_callback_models import EventKind -from openhands.app_server.sharing.shared_event_service import SharedEventService +from server.sharing.shared_event_service import SharedEventService from openhands.sdk import Event -router = APIRouter(prefix='/shared-events', tags=['Sharing']) -shared_event_service_dependency = depends_shared_event_service() +router = APIRouter(prefix='/api/shared-events', tags=['Sharing']) +shared_event_service_dependency = Depends( + SharedEventServiceImplInjector().depends +) # Read methods diff --git a/openhands/app_server/sharing/shared_event_service.py b/enterprise/server/sharing/shared_event_service.py similarity index 100% rename from openhands/app_server/sharing/shared_event_service.py rename to enterprise/server/sharing/shared_event_service.py diff --git a/openhands/app_server/sharing/sql_shared_conversation_info_service.py b/enterprise/server/sharing/sql_shared_conversation_info_service.py similarity index 98% rename from openhands/app_server/sharing/sql_shared_conversation_info_service.py rename to enterprise/server/sharing/sql_shared_conversation_info_service.py index b4c6d78109..6de2f4c60c 100644 --- a/openhands/app_server/sharing/sql_shared_conversation_info_service.py +++ b/enterprise/server/sharing/sql_shared_conversation_info_service.py @@ -22,11 +22,11 @@ from openhands.app_server.app_conversation.sql_app_conversation_info_service imp StoredConversationMetadata, ) from openhands.app_server.services.injector import InjectorState -from openhands.app_server.sharing.shared_conversation_info_service import ( +from server.sharing.shared_conversation_info_service import ( SharedConversationInfoService, SharedConversationInfoServiceInjector, ) -from openhands.app_server.sharing.shared_conversation_models import ( +from server.sharing.shared_conversation_models import ( SharedConversation, SharedConversationPage, SharedConversationSortOrder, diff --git a/openhands/app_server/app_lifespan/alembic/versions/004.py b/openhands/app_server/app_lifespan/alembic/versions/004.py deleted file mode 100644 index 2d5ef07f41..0000000000 --- a/openhands/app_server/app_lifespan/alembic/versions/004.py +++ /dev/null @@ -1,41 +0,0 @@ -"""add public column to conversation_metadata - -Revision ID: 004 -Revises: 003 -Create Date: 2025-01-27 00:00:00.000000 - -""" - -from typing import Sequence, Union - -import sqlalchemy as sa -from alembic import op - -# revision identifiers, used by Alembic. -revision: str = '004' -down_revision: Union[str, None] = '003' -branch_labels: Union[str, Sequence[str], None] = None -depends_on: Union[str, Sequence[str], None] = None - - -def upgrade() -> None: - """Upgrade schema.""" - op.add_column( - 'conversation_metadata', - sa.Column('public', sa.Boolean(), nullable=True), - ) - op.create_index( - op.f('ix_conversation_metadata_public'), - 'conversation_metadata', - ['public'], - unique=False, - ) - - -def downgrade() -> None: - """Downgrade schema.""" - op.drop_index( - op.f('ix_conversation_metadata_public'), - table_name='conversation_metadata', - ) - op.drop_column('conversation_metadata', 'public') diff --git a/openhands/app_server/config.py b/openhands/app_server/config.py index 5cd5972c13..3c40806af0 100644 --- a/openhands/app_server/config.py +++ b/openhands/app_server/config.py @@ -47,14 +47,6 @@ from openhands.app_server.services.db_session_injector import ( from openhands.app_server.services.httpx_client_injector import HttpxClientInjector from openhands.app_server.services.injector import InjectorState from openhands.app_server.services.jwt_service import JwtService, JwtServiceInjector -from openhands.app_server.sharing.shared_conversation_info_service import ( - SharedConversationInfoService, - SharedConversationInfoServiceInjector, -) -from openhands.app_server.sharing.shared_event_service import ( - SharedEventService, - SharedEventServiceInjector, -) from openhands.app_server.user.user_context import UserContext, UserContextInjector from openhands.sdk.utils.models import OpenHandsModel @@ -113,8 +105,6 @@ class AppServerConfig(OpenHandsModel): app_conversation_info: AppConversationInfoServiceInjector | None = None app_conversation_start_task: AppConversationStartTaskServiceInjector | None = None app_conversation: AppConversationServiceInjector | None = None - shared_conversation_info: SharedConversationInfoServiceInjector | None = None - shared_event: SharedEventServiceInjector | None = None user: UserContextInjector | None = None jwt: JwtServiceInjector | None = None httpx: HttpxClientInjector = Field(default_factory=HttpxClientInjector) @@ -212,20 +202,6 @@ def config_from_env() -> AppServerConfig: tavily_api_key=tavily_api_key ) - if config.shared_conversation_info is None: - from openhands.app_server.sharing.sql_shared_conversation_info_service import ( - SQLSharedConversationInfoServiceInjector, - ) - - config.shared_conversation_info = SQLSharedConversationInfoServiceInjector() - - if config.shared_event is None: - from openhands.app_server.sharing.filesystem_shared_event_service import ( - SharedEventServiceImplInjector, - ) - - config.shared_event = SharedEventServiceImplInjector() - if config.user is None: config.user = AuthUserContextInjector() @@ -397,31 +373,3 @@ def depends_jwt_service(): def depends_db_session(): return Depends(get_global_config().db_session.depends) - - -def depends_shared_conversation_info_service(): - injector = get_global_config().shared_conversation_info - assert injector is not None - return Depends(injector.depends) - - -def depends_shared_event_service(): - injector = get_global_config().shared_event - assert injector is not None - return Depends(injector.depends) - - -def get_shared_conversation_info_service( - state: InjectorState, request: Request | None = None -) -> AsyncContextManager[SharedConversationInfoService]: - injector = get_global_config().shared_conversation_info - assert injector is not None - return injector.context(state, request) - - -def get_shared_event_service( - state: InjectorState, request: Request | None = None -) -> AsyncContextManager[SharedEventService]: - injector = get_global_config().shared_event - assert injector is not None - return injector.context(state, request) diff --git a/openhands/app_server/v1_router.py b/openhands/app_server/v1_router.py index 4e49c963a5..f99ef68a6b 100644 --- a/openhands/app_server/v1_router.py +++ b/openhands/app_server/v1_router.py @@ -6,7 +6,6 @@ from openhands.app_server.event_callback import ( webhook_router, ) from openhands.app_server.sandbox import sandbox_router, sandbox_spec_router -from openhands.app_server.sharing import shared_conversation_router, shared_event_router from openhands.app_server.user import user_router # Include routers @@ -15,7 +14,5 @@ router.include_router(event_router.router) router.include_router(app_conversation_router.router) router.include_router(sandbox_router.router) router.include_router(sandbox_spec_router.router) -router.include_router(shared_conversation_router.router) -router.include_router(shared_event_router.router) router.include_router(user_router.router) router.include_router(webhook_router.router)