Add conversation API deprecation notices (#12303)

Co-authored-by: Saurya <saurya@openhands.dev>
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: Tim O'Farrell <tofarr@gmail.com>
This commit is contained in:
Saurya Velagapudi
2026-01-12 05:26:33 -08:00
committed by GitHub
parent b7b76c7a30
commit 3c6d2ff1d6
2 changed files with 60 additions and 12 deletions

View File

@@ -147,7 +147,7 @@ async def get_remote_runtime_config(
return JSONResponse(content=config)
@app.get('/vscode-url')
@app.get('/vscode-url', deprecated=True)
async def get_vscode_url(
conversation: ServerConversation = Depends(get_conversation),
) -> JSONResponse:
@@ -160,6 +160,9 @@ async def get_vscode_url(
Returns:
JSONResponse: A JSON response indicating the success of the operation.
For V1 conversations, the VSCode URL is available in the sandbox's ``exposed_urls``
field. Use ``GET /api/v1/sandboxes?id={sandbox_id}`` to retrieve sandbox information and use the name VSCODE.
"""
try:
runtime: Runtime = conversation.runtime
@@ -179,7 +182,7 @@ async def get_vscode_url(
)
@app.get('/web-hosts')
@app.get('/web-hosts', deprecated=True)
async def get_hosts(
conversation: ServerConversation = Depends(get_conversation),
) -> JSONResponse:
@@ -192,6 +195,9 @@ async def get_hosts(
Returns:
JSONResponse: A JSON response indicating the success of the operation.
For V1 conversations, web hosts are available in the sandbox's ``exposed_urls``
field. Use ``GET /api/v1/sandboxes?id={sandbox_id}`` to retrieve sandbox information and use the name AGENT_SERVER.
"""
try:
runtime: Runtime = conversation.runtime
@@ -209,7 +215,7 @@ async def get_hosts(
)
@app.get('/events')
@app.get('/events', deprecated=True)
async def search_events(
conversation_id: str,
start_id: int = 0,
@@ -239,6 +245,10 @@ async def search_events(
Raises:
HTTPException: If conversation is not found or access is denied
ValueError: If limit is less than 1 or greater than 100
Use the V1 endpoint ``GET /api/v1/events/search?conversation_id__eq={conversation_id}``
instead, which provides enhanced filtering by event kind, timestamp ranges,
and improved pagination.
"""
if limit < 0 or limit > 100:
raise HTTPException(
@@ -275,10 +285,15 @@ async def search_events(
}
@app.post('/events')
@app.post('/events', deprecated=True)
async def add_event(
request: Request, conversation: ServerConversation = Depends(get_conversation)
):
"""Add an event to a conversation.
For V1 conversations, events are managed through the sandbox webhook system.
Use ``POST /api/v1/webhooks/events/{conversation_id}`` for event callbacks.
"""
data = await request.json()
await conversation_manager.send_event_to_conversation(conversation.sid, data)
return JSONResponse({'success': True})
@@ -342,7 +357,7 @@ class MicroagentResponse(BaseModel):
tools: list[str] = []
@app.get('/microagents')
@app.get('/microagents', deprecated=True)
async def get_microagents(
conversation: ServerConversation = Depends(get_conversation),
) -> JSONResponse:
@@ -352,6 +367,9 @@ async def get_microagents(
Returns:
JSONResponse: A JSON response containing the list of microagents.
Use the V1 endpoint ``GET /api/v1/app-conversations/{conversation_id}/skills`` instead,
which provides skill information including triggers and content for V1 conversations.
"""
try:
# Get the agent session for this conversation

View File

@@ -229,7 +229,7 @@ class ProvidersSetModel(BaseModel):
providers_set: list[ProviderType] | None = None
@app.post('/conversations')
@app.post('/conversations', deprecated=True)
async def new_conversation(
data: InitSessionRequest,
user_id: str = Depends(get_user_id),
@@ -241,6 +241,9 @@ async def new_conversation(
After successful initialization, the client should connect to the WebSocket
using the returned conversation ID.
Use the V1 endpoint ``POST /api/v1/app-conversations`` instead, which provides
improved conversation management with sandbox lifecycle support.
"""
logger.info(f'initializing_new_conversation:{data}')
repository = data.repository
@@ -318,7 +321,7 @@ async def new_conversation(
)
@app.get('/conversations')
@app.get('/conversations', deprecated=True)
async def search_conversations(
page_id: str | None = None,
limit: int = 20,
@@ -333,6 +336,11 @@ async def search_conversations(
conversation_store: ConversationStore = Depends(get_conversation_store),
app_conversation_service: AppConversationService = app_conversation_service_dependency,
) -> ConversationInfoResultSet:
"""Search and list conversations with pagination support.
Use the V1 endpoint ``GET /api/v1/app-conversations/search`` instead, which provides
enhanced filtering, sorting, and pagination capabilities.
"""
# Parse combined page_id to extract separate page_ids for each source
v0_page_id = None
v1_page_id = None
@@ -457,12 +465,17 @@ async def search_conversations(
return ConversationInfoResultSet(results=final_results, next_page_id=next_page_id)
@app.get('/conversations/{conversation_id}')
@app.get('/conversations/{conversation_id}', deprecated=True)
async def get_conversation(
conversation_id: str = Depends(validate_conversation_id),
conversation_store: ConversationStore = Depends(get_conversation_store),
app_conversation_service: AppConversationService = app_conversation_service_dependency,
) -> ConversationInfo | None:
"""Get a single conversation by ID.
Use the V1 endpoint ``GET /api/v1/app-conversations?ids={conversation_id}`` instead,
which supports batch retrieval of conversations by their IDs.
"""
try:
# Shim to add V1 conversations
try:
@@ -492,7 +505,7 @@ async def get_conversation(
return None
@app.delete('/conversations/{conversation_id}')
@app.delete('/conversations/{conversation_id}', deprecated=True)
async def delete_conversation(
request: Request,
conversation_id: str = Depends(validate_conversation_id),
@@ -503,6 +516,11 @@ async def delete_conversation(
db_session: AsyncSession = db_session_dependency,
httpx_client: httpx.AsyncClient = httpx_client_dependency,
) -> bool:
"""Delete a conversation by ID.
For V1 conversations, use ``DELETE /api/v1/sandboxes/{sandbox_id}`` to delete the
associated sandbox, which will clean up the conversation resources.
"""
set_db_session_keep_open(request.state, True)
set_httpx_client_keep_open(request.state, True)
@@ -715,7 +733,7 @@ async def _get_conversation_info(
return None
@app.post('/conversations/{conversation_id}/start')
@app.post('/conversations/{conversation_id}/start', deprecated=True)
async def start_conversation(
providers_set: ProvidersSetModel,
conversation_id: str = Depends(validate_conversation_id),
@@ -729,6 +747,10 @@ async def start_conversation(
This endpoint calls the conversation_manager's maybe_start_agent_loop method
to start a conversation. If the conversation is already running, it will
return the existing agent loop info.
Use the V1 endpoint ``POST /api/v1/app-conversations`` instead, which combines
conversation creation and starting into a single operation with integrated
sandbox lifecycle management.
"""
logger.info(
f'Starting conversation: {conversation_id}',
@@ -792,7 +814,7 @@ async def start_conversation(
)
@app.post('/conversations/{conversation_id}/stop')
@app.post('/conversations/{conversation_id}/stop', deprecated=True)
async def stop_conversation(
conversation_id: str = Depends(validate_conversation_id),
user_id: str = Depends(get_user_id),
@@ -801,6 +823,10 @@ async def stop_conversation(
This endpoint calls the conversation_manager's close_session method
to stop a conversation.
Use the V1 endpoint ``POST /api/v1/sandboxes/{sandbox_id}/pause`` instead to pause
the sandbox execution, or ``DELETE /api/v1/sandboxes/{sandbox_id}`` to fully stop
and remove the sandbox.
"""
logger.info(f'Stopping conversation: {conversation_id}')
@@ -1070,7 +1096,7 @@ async def _update_v0_conversation(
return True
@app.patch('/conversations/{conversation_id}')
@app.patch('/conversations/{conversation_id}', deprecated=True)
async def update_conversation(
data: UpdateConversationRequest,
conversation_id: str = Depends(validate_conversation_id),
@@ -1098,6 +1124,10 @@ async def update_conversation(
Raises:
HTTPException: If conversation is not found or user lacks permission
This endpoint is part of the legacy V0 API and will be removed in a future release.
Use the V1 endpoint ``PATCH /api/v1/app-conversations/{conversation_id}`` instead,
which provides the same functionality for updating conversation metadata.
"""
logger.info(
f'Updating conversation {conversation_id} with title: {data.title}',