Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
change
sglang
Commits
590bc4b7
Unverified
Commit
590bc4b7
authored
Oct 21, 2025
by
Chang Su
Committed by
GitHub
Oct 21, 2025
Browse files
[router][grpc] Fix background tasks stored with wrong id (#11945)
parent
63cfe1b0
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
30 additions
and
16 deletions
+30
-16
sgl-router/src/routers/grpc/responses/conversions.rs
sgl-router/src/routers/grpc/responses/conversions.rs
+3
-2
sgl-router/src/routers/grpc/responses/handlers.rs
sgl-router/src/routers/grpc/responses/handlers.rs
+15
-8
sgl-router/src/routers/grpc/responses/tool_loop.rs
sgl-router/src/routers/grpc/responses/tool_loop.rs
+12
-6
No files found.
sgl-router/src/routers/grpc/responses/conversions.rs
View file @
590bc4b7
...
...
@@ -187,7 +187,7 @@ fn extract_text_from_content(content: &[ResponseContentPart]) -> String {
/// Convert a ChatCompletionResponse to ResponsesResponse
///
/// # Conversion Logic
/// - `id` → `
id` (pass through)
/// - `id` → `
response_id_override` if provided, otherwise `chat_resp.id`
/// - `model` → `model` (pass through)
/// - `choices[0].message` → `output` array (convert to ResponseOutputItem::Message)
/// - `choices[0].finish_reason` → determines `status` (stop/length → Completed)
...
...
@@ -195,6 +195,7 @@ fn extract_text_from_content(content: &[ResponseContentPart]) -> String {
pub
fn
chat_to_responses
(
chat_resp
:
&
ChatCompletionResponse
,
original_req
:
&
ResponsesRequest
,
response_id_override
:
Option
<
String
>
,
)
->
Result
<
ResponsesResponse
,
String
>
{
// Extract the first choice (responses API doesn't support n>1)
let
choice
=
chat_resp
...
...
@@ -275,7 +276,7 @@ pub fn chat_to_responses(
// Generate response
Ok
(
ResponsesResponse
{
id
:
chat_resp
.id
.clone
(),
id
:
response_id_override
.unwrap_or_else
(||
chat_resp
.id
.clone
()
)
,
object
:
"response"
.to_string
(),
created_at
:
chat_resp
.created
as
i64
,
status
,
...
...
sgl-router/src/routers/grpc/responses/handlers.rs
View file @
590bc4b7
...
...
@@ -21,7 +21,7 @@ use futures_util::StreamExt;
use
serde_json
::
json
;
use
tokio
::
sync
::{
mpsc
,
RwLock
};
use
tokio_stream
::
wrappers
::
UnboundedReceiverStream
;
use
tracing
::{
debug
,
warn
};
use
tracing
::{
debug
,
error
,
warn
};
use
uuid
::
Uuid
;
use
super
::{
...
...
@@ -935,14 +935,14 @@ async fn execute_without_mcp(
headers
,
model_id
,
components
,
response_id
,
response_id
.clone
()
,
background_tasks
,
)
.await
.map_err
(|
e
|
format!
(
"Pipeline execution failed: {}"
,
e
))
?
;
// Convert ChatCompletionResponse → ResponsesResponse
conversions
::
chat_to_responses
(
&
chat_response
,
original_request
)
conversions
::
chat_to_responses
(
&
chat_response
,
original_request
,
response_id
)
.map_err
(|
e
|
format!
(
"Failed to convert to responses format: {}"
,
e
))
}
...
...
@@ -1207,13 +1207,20 @@ pub async fn cancel_response_impl(
)
.into_response
()
}
else
{
// Task handle not found (may have already completed)
// Task handle not found but status is queued/in_progress
// This can happen if: (1) task crashed, or (2) storage persistence failed
error!
(
"Response {} has status '{}' but task handle is missing. Task may have crashed or storage update failed."
,
response_id
,
current_status
);
(
StatusCode
::
OK
,
StatusCode
::
INTERNAL_SERVER_ERROR
,
axum
::
Json
(
json!
({
"id"
:
response_id
,
"status"
:
"completed_or_not_found"
,
"message"
:
"Task may have already completed before cancellation"
"error"
:
{
"message"
:
"Internal error: background task completed but failed to update status in storage"
,
"type"
:
"internal_error"
,
"code"
:
"status_update_failed"
}
})),
)
.into_response
()
...
...
sgl-router/src/routers/grpc/responses/tool_loop.rs
View file @
590bc4b7
...
...
@@ -365,9 +365,12 @@ pub(super) async fn execute_tool_loop(
);
// Convert chat response to responses format and mark as incomplete
let
mut
responses_response
=
conversions
::
chat_to_responses
(
&
chat_response
,
original_request
)
.map_err
(|
e
|
format!
(
"Failed to convert to responses format: {}"
,
e
))
?
;
let
mut
responses_response
=
conversions
::
chat_to_responses
(
&
chat_response
,
original_request
,
response_id
.clone
(),
)
.map_err
(|
e
|
format!
(
"Failed to convert to responses format: {}"
,
e
))
?
;
// Mark as completed but with incomplete details
responses_response
.status
=
ResponseStatus
::
Completed
;
...
...
@@ -461,9 +464,12 @@ pub(super) async fn execute_tool_loop(
);
// Convert final chat response to responses format
let
mut
responses_response
=
conversions
::
chat_to_responses
(
&
chat_response
,
original_request
)
.map_err
(|
e
|
format!
(
"Failed to convert to responses format: {}"
,
e
))
?
;
let
mut
responses_response
=
conversions
::
chat_to_responses
(
&
chat_response
,
original_request
,
response_id
.clone
(),
)
.map_err
(|
e
|
format!
(
"Failed to convert to responses format: {}"
,
e
))
?
;
// Inject MCP metadata into output
if
state
.total_calls
>
0
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment