feat: add new letta error message stream response type (#6192)

This commit is contained in:
cthomas
2025-11-19 16:11:22 -08:00
committed by Caren Thomas
parent 1d71468ab2
commit 1be2f61f05
11 changed files with 204 additions and 69 deletions

View File

@@ -63,7 +63,7 @@ from letta.jobs.scheduler import start_scheduler_with_leader_election
from letta.log import get_logger
from letta.orm.errors import DatabaseTimeoutError, ForeignKeyConstraintViolationError, NoResultFound, UniqueConstraintViolationError
from letta.otel.tracing import get_trace_id
from letta.schemas.letta_message import create_letta_message_union_schema, create_letta_ping_schema
from letta.schemas.letta_message import create_letta_error_message_schema, create_letta_message_union_schema, create_letta_ping_schema
from letta.schemas.letta_message_content import (
create_letta_assistant_message_content_union_schema,
create_letta_message_content_union_schema,
@@ -110,6 +110,7 @@ def generate_openapi_schema(app: FastAPI):
letta_docs["components"]["schemas"]["LettaAssistantMessageContentUnion"] = create_letta_assistant_message_content_union_schema()
letta_docs["components"]["schemas"]["LettaUserMessageContentUnion"] = create_letta_user_message_content_union_schema()
letta_docs["components"]["schemas"]["LettaPing"] = create_letta_ping_schema()
letta_docs["components"]["schemas"]["LettaErrorMessage"] = create_letta_error_message_schema()
# Update the app's schema with our modified version
app.openapi_schema = letta_docs

View File

@@ -9,7 +9,8 @@ from typing import AsyncIterator, Dict, List, Optional
from letta.data_sources.redis_client import AsyncRedisClient
from letta.log import get_logger
from letta.schemas.enums import RunStatus
from letta.schemas.letta_stop_reason import StopReasonType
from letta.schemas.letta_message import LettaErrorMessage
from letta.schemas.letta_stop_reason import LettaStopReason, StopReasonType
from letta.schemas.run import RunUpdate
from letta.schemas.user import User
from letta.server.rest_api.streaming_response import RunCancelledException
@@ -266,8 +267,14 @@ async def create_background_stream_processor(
saw_done = True
else:
# No stop_reason and no terminal - this is an error condition
error_chunk = {"error": "Stream ended unexpectedly without stop_reason", "code": "STREAM_INCOMPLETE"}
await writer.write_chunk(run_id=run_id, data=f"event: error\ndata: {json.dumps(error_chunk)}\n\n", is_complete=False)
error_message = LettaErrorMessage(
run_id=run_id,
error_type="stream_incomplete",
message="Stream ended unexpectedly without stop_reason.",
detail=None,
)
yield f"data: {LettaStopReason(stop_reason=StopReasonType.error).model_dump_json()}\n\n"
yield f"event: error\ndata: {error_message.model_dump_json()}\n\n"
await writer.write_chunk(run_id=run_id, data="data: [DONE]\n\n", is_complete=True)
saw_error = True
saw_done = True
@@ -284,8 +291,17 @@ async def create_background_stream_processor(
except Exception as e:
logger.error(f"Error processing stream for run {run_id}: {e}")
# Write error chunk
error_chunk = {"error": str(e), "code": "INTERNAL_SERVER_ERROR"}
await writer.write_chunk(run_id=run_id, data=f"event: error\ndata: {json.dumps(error_chunk)}\n\n", is_complete=False)
stop_reason = StopReasonType.error.value
error_message = LettaErrorMessage(
run_id=run_id,
error_type="internal_error",
message="An unknown error occurred with the LLM streaming request.",
detail=str(e),
)
await writer.write_chunk(
run_id=run_id, data=f"data: {LettaStopReason(stop_reason=stop_reason).model_dump_json()}\n\n", is_complete=False
)
await writer.write_chunk(run_id=run_id, data=f"event: error\ndata: {error_message.model_dump_json()}\n\n", is_complete=False)
await writer.write_chunk(run_id=run_id, data="data: [DONE]\n\n", is_complete=True)
saw_error = True
saw_done = True

View File

@@ -282,6 +282,7 @@ async def delete_run(
{"$ref": "#/components/schemas/ApprovalRequestMessage"},
{"$ref": "#/components/schemas/ApprovalResponseMessage"},
{"$ref": "#/components/schemas/LettaPing"},
{"$ref": "#/components/schemas/LettaErrorMessage"},
{"$ref": "#/components/schemas/LettaStopReason"},
{"$ref": "#/components/schemas/LettaUsageStatistics"},
]