Skip to content

fix(channel-test): responses fallback + better upstream error messages - #2501

Closed
FlowerRealm wants to merge 5 commits into
QuantumNous:mainfrom
FlowerRealm:fix/channel-test-responses-fallback
Closed

fix(channel-test): responses fallback + better upstream error messages#2501
FlowerRealm wants to merge 5 commits into
QuantumNous:mainfrom
FlowerRealm:fix/channel-test-responses-fallback

Conversation

@FlowerRealm

@FlowerRealm FlowerRealm commented Dec 23, 2025

Copy link
Copy Markdown
Contributor

Problem:

  • Some upstreams are responses-only (reject chat.completions 'messages'), so channel test fails even though the channel works via /v1/responses.
  • Some upstream error payloads have no error.message (or only a 'detail' field), leading to empty UI messages like '模型 xxx:'.

Fix:

  • Parse GeneralErrorResponse.detail and fallback to raw error JSON when message is missing.
  • Ensure RelayErrorHandler returns a non-empty error even on nil/failed body reads.
  • In auto-detect mode, retry via Responses API when chat.completions reports 'Unsupported parameter: messages'.
  • Make Responses test request use stream=true with valid input.

Tests:

  • Add unit tests for error parsing and RelayErrorHandler / NewAPIError.Error() fallbacks.

Summary by CodeRabbit

  • New Features

    • Default routing and playground/tools now use the Responses (/v1/responses) API path and payload format.
    • UI and endpoint options updated to reflect the Responses endpoint.
  • Bug Fixes

    • Improved error-message extraction with a new detail fallback.
    • Safer handling when upstream response bodies are nil or unreadable.
    • Validation relaxed to allow Responses requests without an Input field.
  • Tests

    • Added tests for error parsing, nil/unreadable bodies, and request validation.

✏️ Tip: You can customize this high-level summary in your review settings.

- Parse upstream errors with detail/object fallback to avoid empty UI messages\n- Auto fallback from chat.completions to responses when messages unsupported\n- Add unit tests for error parsing and relay error handler
@coderabbitai

coderabbitai Bot commented Dec 23, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Switches channel testing and many UI/defaults from the chat/completions path to the responses path; expands OpenAIResponses request construction and relay format routing; relaxes Responses request validation (allows nil Input); improves error-message fallbacks and nil-body handling; adds unit tests across these behaviors.

Changes

Cohort / File(s) Summary
Channel test & request construction
controller/channel-test.go
BuildTestRequest now accepts requestPath; channel test flow uses /v1/responses (OpenAIResponses) as the default/auto-detected relay format and retries tests on Responses path; request construction switches on requestPath (embeddings, images, responses).
Error DTO & tests
dto/error.go, dto/error_test.go
Added Detail string to GeneralErrorResponse; ToMessage gains fallbacks to raw JSON and Detail; unit tests cover these cases.
Relay error handling & tests
service/error.go, service/error_test.go
RelayErrorHandler guards nil response body and wraps read errors; tests added for nil body and failing Read.
API error fallback & tests
types/error.go, types/error_test.go
NewAPIError.Error() now returns the error code string when underlying error message is empty; added test validating fallback.
Responses validation & tests
relay/helper/valid_request.go, relay/helper/valid_request_test.go
Validation no longer requires Input for Responses requests (only Model); test verifies missing Input is allowed.
Routing / constants / defaults
router/relay-router.go, relay/constant/relay_mode.go, common/endpoint_defaults.go, middleware/distributor.go
Routes and path-to-mode mapping updated to prefer /v1/responses and /pg/responses; default OpenAI endpoint examples changed to /v1/responses.
Playground / token / relay format
controller/playground.go, middleware/distributor.go
Playground token generation and relay invocation switched to use OpenAIResponses format; playground path changed to /pg/responses.
Client tooling / scripts
bin/time_test.sh
Example/test script payloads and endpoint switched to /v1/responses and updated request shape (input/max_output_tokens).
Frontend endpoint mappings & playground hooks
web/src/constants/*, web/src/components/*, web/src/hooks/playground/useApiRequest.jsx, web/src/helpers/api.js
UI/default endpoint labels and templates changed from chat/completions to responses; payload mapping changed from messages to input and max_tokensmax_output_tokens; SSE handling updated to handle Responses event types and streaming deltas.
Docs / i18n
docs/openapi/relay.json, web/src/i18n/locales/*
OpenAPI removed chat/completions and completions paths; localized example URLs updated to /v1/responses.
Minor frontend formatting
web/src/components/table/channels/modals/EditChannelModal.jsx
Cosmetic formatting and whitespace changes only.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Controller as ChannelTestController
    participant Upstream as UpstreamAPI
    Note over Controller: buildTestRequest(model, endpointType, requestPath)

    Client->>Controller: POST /testChannel (model, requestPath=/v1/chat/completions)
    Controller->>Upstream: POST /v1/chat/completions (chat-format test payload)
    alt Upstream returns 200
        Upstream-->>Controller: 200 OK
        Controller-->>Client: success (report)
    else Upstream returns 4xx with unsupported-parameter or response-only error
        Upstream-->>Controller: 4xx error
        Controller->>Controller: preserve originTestModel
        Controller->>Upstream: POST /v1/responses (OpenAIResponsesRequest, structured input, max_output_tokens)
        alt Upstream returns 200
            Upstream-->>Controller: 200 OK
            Controller-->>Client: success (report)
        else Upstream returns error
            Upstream-->>Controller: error
            Controller-->>Client: error (wrapped)
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • creamlike1024
  • seefs001
  • Calcium-Ion

Poem

🐰 I swapped my hops from chat to Responses' shore,
I nudged errors to whisper the hidden lore,
I let inputs be absent and tests still cheer,
With tokens and retries, the path is clear! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(channel-test): responses fallback + better upstream error messages' directly summarizes the main changes: implementing responses API fallback for channel tests and improving error message handling for upstream responses.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

- Allow /v1/responses requests without input (spec allows model-only)\n- In channel test auto-detect, use /v1/responses for response-only models\n- Add unit test for responses request validation

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
relay/helper/valid_request_test.go (1)

15-15: Consider saving and restoring the global variable for test isolation.

Modifying constant.MaxRequestBodyMB without restoration could cause test interference if multiple tests in this package run in parallel and also modify this global variable.

🔎 Proposed fix for test isolation
 func TestGetAndValidateResponsesRequest_AllowsMissingInput(t *testing.T) {
+	// Save original value and restore after test
+	origMaxRequestBodyMB := constant.MaxRequestBodyMB
+	defer func() { constant.MaxRequestBodyMB = origMaxRequestBodyMB }()
+
 	constant.MaxRequestBodyMB = 20
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8320092 and 8f324a5.

📒 Files selected for processing (3)
  • controller/channel-test.go
  • relay/helper/valid_request.go
  • relay/helper/valid_request_test.go
💤 Files with no reviewable changes (1)
  • relay/helper/valid_request.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • controller/channel-test.go
🧰 Additional context used
🧬 Code graph analysis (1)
relay/helper/valid_request_test.go (4)
constant/env.go (1)
  • MaxRequestBodyMB (12-12)
dto/request_common.go (1)
  • Request (8-12)
relay/helper/valid_request.go (1)
  • GetAndValidateResponsesRequest (113-123)
dto/openai_request.go (1)
  • Input (901-905)
🔇 Additional comments (2)
relay/helper/valid_request_test.go (2)

1-13: LGTM! Clean test setup.

The imports are appropriate and well-organized for a Gin-based unit test.


14-41: Well-structured test that validates the spec-compliant behavior.

The test clearly demonstrates that GetAndValidateResponsesRequest now accepts model-only requests (without the Input field), which aligns with the PR objective to support responses-only upstreams.

@FlowerRealm

Copy link
Copy Markdown
Contributor Author

@coderabbitai generate docstrings

@coderabbitai

coderabbitai Bot commented Dec 23, 2025

Copy link
Copy Markdown
Contributor
✅ Actions performed

Initiated docstring generation; will generate only if new commits exist.

@coderabbitai

coderabbitai Bot commented Dec 23, 2025

Copy link
Copy Markdown
Contributor

Note

Docstrings generation - SUCCESS
Generated docstrings for this pull request at #2505

coderabbitai Bot added a commit that referenced this pull request Dec 23, 2025
Docstrings generation was requested by @FlowerRealm.

* #2501 (comment)

The following files were modified:

* `controller/channel-test.go`
* `relay/helper/valid_request.go`
* `service/error.go`

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/src/hooks/playground/useApiRequest.jsx (1)

244-266: Potential issue: empty output leaves message in LOADING state.

If the API returns a valid response but with empty output_text/output, the if (outputText) check on line 244 will skip the message update, leaving the last message stuck in MESSAGE_STATUS.LOADING. This could confuse users.

Consider handling empty-but-valid responses:

🔎 Suggested fix
-        if (outputText) {
+        // Process response even if output is empty - still need to complete the message
+        {
           const processed = processThinkTags(outputText, '');

           setMessage((prevMessage) => {
             const newMessages = [...prevMessage];
             const lastMessage = newMessages[newMessages.length - 1];
             if (lastMessage?.status === MESSAGE_STATUS.LOADING) {
               const autoCollapseState = applyAutoCollapseLogic(
                 lastMessage,
                 true,
               );

               newMessages[newMessages.length - 1] = {
                 ...lastMessage,
-                content: processed.content,
+                content: processed.content || '',
                 reasoningContent: processed.reasoningContent,
                 status: MESSAGE_STATUS.COMPLETE,
                 ...autoCollapseState,
               };
             }
             return newMessages;
           });
         }
🧹 Nitpick comments (2)
docs/openapi/relay.json (1)

2514-2881: Consider removing unused endpoint schemas.

The removal of POST /v1/chat/completions and POST /v1/completions endpoints aligns with the PR's goal to consolidate on /v1/responses. However, the associated schemas (ChatCompletionRequest, ChatCompletionResponse, ChatCompletionStreamResponse, CompletionRequest, CompletionResponse) are still defined in the components section.

If these schemas are no longer referenced elsewhere in the API specification, consider removing them to keep the documentation clean and avoid confusion. If they're retained for backward compatibility documentation or are referenced by other parts of the system, this can be safely ignored.

</review_comment_end>

web/src/helpers/api.js (1)

257-259: Consider adding a comment or minimal logging for the swallowed error.

The empty catch block intentionally ignores logout failures during OAuth state preparation, which is reasonable since the logout is best-effort. However, silent error swallowing can make debugging harder.

🔎 Suggested improvement
     try {
       await API.get('/api/user/logout', { skipErrorHandler: true });
-    } catch (err) {}
+    } catch {
+      // Logout failure is non-critical during OAuth state preparation
+    }
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8f324a5 and 024b528.

📒 Files selected for processing (22)
  • bin/time_test.sh
  • common/endpoint_defaults.go
  • controller/channel-test.go
  • controller/playground.go
  • docs/openapi/relay.json
  • middleware/distributor.go
  • relay/constant/relay_mode.go
  • router/relay-router.go
  • web/src/components/table/channels/modals/EditChannelModal.jsx
  • web/src/components/table/channels/modals/ModelTestModal.jsx
  • web/src/components/table/models/modals/EditModelModal.jsx
  • web/src/components/table/models/modals/EditPrefillGroupModal.jsx
  • web/src/constants/common.constant.js
  • web/src/constants/playground.constants.js
  • web/src/helpers/api.js
  • web/src/hooks/playground/useApiRequest.jsx
  • web/src/i18n/locales/en.json
  • web/src/i18n/locales/fr.json
  • web/src/i18n/locales/ja.json
  • web/src/i18n/locales/ru.json
  • web/src/i18n/locales/vi.json
  • web/src/i18n/locales/zh.json
💤 Files with no reviewable changes (1)
  • web/src/constants/common.constant.js
✅ Files skipped from review due to trivial changes (1)
  • web/src/components/table/channels/modals/EditChannelModal.jsx
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-27T02:15:25.448Z
Learnt from: AAEE86
Repo: QuantumNous/new-api PR: 1658
File: web/src/components/table/channels/modals/EditChannelModal.jsx:555-569
Timestamp: 2025-08-27T02:15:25.448Z
Learning: In EditChannelModal.jsx, the applyModelMapping function transforms the models list by replacing original model names (mapping values) with display names (mapping keys). The database stores this transformed list containing mapped keys. On channel load, data.models contains these mapped display names, making the initialization filter if (data.models.includes(key)) correct.

Applied to files:

  • web/src/components/table/channels/modals/ModelTestModal.jsx
  • web/src/components/table/models/modals/EditModelModal.jsx
📚 Learning: 2025-08-27T02:15:25.448Z
Learnt from: AAEE86
Repo: QuantumNous/new-api PR: 1658
File: web/src/components/table/channels/modals/EditChannelModal.jsx:555-569
Timestamp: 2025-08-27T02:15:25.448Z
Learning: In EditChannelModal.jsx, the database stores mapped keys (display names) in the models field after applying model mapping transformations. When loading a channel, data.models contains the mapped keys, not the original model names. The filtering logic if (data.models.includes(key)) in the initialization is correct.

Applied to files:

  • web/src/components/table/channels/modals/ModelTestModal.jsx
🧬 Code graph analysis (5)
controller/channel-test.go (6)
types/relay_format.go (1)
  • RelayFormatOpenAIResponses (9-9)
dto/request_common.go (1)
  • Request (8-12)
constant/endpoint_type.go (4)
  • EndpointTypeOpenAIResponse (7-7)
  • EndpointTypeOpenAI (6-6)
  • EndpointTypeAnthropic (8-8)
  • EndpointTypeGemini (9-9)
dto/openai_request.go (2)
  • OpenAIResponsesRequest (792-817)
  • Input (901-905)
model/model_meta.go (1)
  • Model (23-44)
dto/embedding.go (1)
  • EmbeddingRequest (22-33)
router/relay-router.go (1)
controller/playground.go (1)
  • Playground (16-55)
middleware/distributor.go (1)
dto/request_common.go (1)
  • Request (8-12)
web/src/hooks/playground/useApiRequest.jsx (3)
web/src/constants/playground.constants.js (4)
  • API_ENDPOINTS (77-81)
  • API_ENDPOINTS (77-81)
  • DEBUG_TABS (70-74)
  • DEBUG_TABS (70-74)
web/src/constants/common.constant.js (2)
  • API_ENDPOINTS (26-38)
  • API_ENDPOINTS (26-38)
web/src/hooks/playground/usePlaygroundState.js (1)
  • sseSourceRef (110-110)
common/endpoint_defaults.go (1)
constant/endpoint_type.go (1)
  • EndpointTypeOpenAI (6-6)
🔇 Additional comments (33)
web/src/i18n/locales/vi.json (1)

2057-2057: LGTM! Localization updated to reflect new endpoint.

The URL example in the Vietnamese translation has been correctly updated from /v1/chat/completions to /v1/responses, consistent with the PR's migration to the Responses API. The translation quality is accurate and maintains consistency with other translations in the file.

bin/time_test.sh (2)

18-18: Endpoint migration looks good.

The switch to /v1/responses aligns with the PR's objective to migrate channel testing to the Responses API.


21-21: Verify the stream setting.

The payload structure correctly migrates to the Responses API format (input array, max_output_tokens). However, the PR description states "Make the Responses test request use stream=true," but this line sets "stream": false.

Is stream=false intentional for this timing script, or should it be aligned with the PR's stated objective?

web/src/components/table/channels/modals/ModelTestModal.jsx (1)

65-79: OpenAI endpoint label correctly aligned to /v1/responses

The updated label OpenAI (/v1/responses) matches the new default OpenAI path used across the PR and keeps the endpoint selector consistent with backend behavior. No issues from a UI or logic perspective.

common/endpoint_defaults.go (1)

11-27: Default OpenAI endpoint switched to /v1/responses consistently

Updating EndpointTypeOpenAI to use "/v1/responses" (and fixing the inline JSON example) aligns backend defaults with the new Responses-based flow and keeps it consistent with EndpointTypeOpenAIResponse. No functional or compatibility concerns apparent in this file.

web/src/i18n/locales/en.json (1)

1834-1834: English example URL updated to Responses endpoint

The placeholder now shows https://api.openai.com/v1/responses, which matches the new default OpenAI text endpoint and keeps UX guidance accurate.

web/src/components/table/models/modals/EditPrefillGroupModal.jsx (1)

42-49: Endpoint template and placeholder now match /v1/responses

ENDPOINT_TEMPLATE.openai and the JSON editor placeholder both use "/v1/responses" with POST, which is consistent with the updated backend defaults and other UI text. This keeps quick-fill and docs aligned.

Also applies to: 246-248

web/src/i18n/locales/ja.json (1)

1746-1746: Japanese placeholder URL aligned with /v1/responses

The Japanese translation now uses https://api.openai.com/v1/responses as the example URL, matching the new canonical endpoint and remaining consistent with other locales.

web/src/i18n/locales/zh.json (1)

1822-1822: LGTM - URL example updated to reflect responses endpoint migration.

The translation string correctly updates the example URL from the legacy /v1/chat/completions endpoint to the new /v1/responses endpoint, consistent with the PR's objective of migrating to the Responses API.

web/src/i18n/locales/fr.json (1)

1844-1844: LGTM - French translation updated consistently with endpoint migration.

The French localization string correctly mirrors the URL update from /v1/chat/completions to /v1/responses, maintaining consistency with other locale files and the PR's migration objectives.

web/src/i18n/locales/ru.json (1)

1855-1855: LGTM!

The Russian translation placeholder correctly reflects the updated endpoint path from /v1/chat/completions to /v1/responses, consistent with the broader API endpoint migration across the codebase.

relay/constant/relay_mode.go (1)

57-59: LGTM!

The path detection for RelayModeResponses is correctly prioritized before chat/completions. Both /v1/responses and /pg/responses prefixes are properly handled, and there's no conflict with other paths since prefix matching is used consistently.

router/relay-router.go (2)

61-61: LGTM!

The playground route correctly updated from /pg/chat/completions to /pg/responses, aligning with the controller.Playground implementation that now uses RelayFormatOpenAIResponses.


84-88: Routes /v1/chat/completions and /v1/completions are removed but migration path is undocumented.

The POST routes for /chat/completions and /completions have been intentionally removed from the router, confirming the breaking change. However, the relay mode detection logic in relay/constant/relay_mode.go still contains path checks for these routes, and multiple channel adaptors (moonshot, baidu_v2, cloudflare, minimax, volcengine) continue to support RelayModeChatCompletions mode. This incomplete removal leaves orphaned code and provides no guidance for clients migrating from these endpoints. Either complete the refactor by removing the orphaned detection logic, or document the replacement endpoint strategy.

middleware/distributor.go (2)

83-84: LGTM!

The path check correctly updated to match the new playground route /pg/responses. The logic for handling playground requests with group validation remains intact.


293-294: LGTM!

The playground path detection in getModelRequest is consistent with the earlier check in Distribute(), correctly handling the /pg/responses endpoint for model extraction.

controller/playground.go (2)

34-37: LGTM!

The fallback logic for usingGroup is correct—first attempting ContextKeyUsingGroup, then falling back to ContextKeyUserGroup if empty. This ensures a valid group is always available for the temporary token.


47-54: LGTM!

The temporary token construction and relay invocation are correct:

  • Token name clearly identifies the playground context with the group
  • RelayFormatOpenAIResponses aligns with the new endpoint strategy
controller/channel-test.go (4)

78-78: LGTM!

The default request path correctly updated to /v1/responses to align with the new OpenAIResponses pathway.


140-141: Consider using consistent relay format for OpenAI endpoint type.

When endpointType is EndpointTypeOpenAI, the code sets relayFormat to RelayFormatOpenAIResponses. This is consistent with the PR's migration strategy, but the original EndpointTypeOpenAI semantically implies the legacy chat completions format. If this is intentional to force all "openai" endpoint tests through the responses pathway, consider documenting this behavior.


418-425: LGTM!

The OpenAIResponsesRequest construction for both EndpointTypeOpenAIResponse and EndpointTypeOpenAI is correct:

  • Uses structured Input with proper JSON format
  • Sets reasonable MaxOutputTokens and Stream values for testing

392-467: LGTM!

The buildTestRequest function correctly handles the new requestPath parameter:

  • Endpoint-specific branches correctly return appropriate request types
  • Auto-detection falls back to OpenAIResponsesRequest for the default path
  • Embedding and image generation paths are properly handled
web/src/components/table/models/modals/EditModelModal.jsx (2)

45-45: LGTM!

The ENDPOINT_TEMPLATE correctly updated to reflect the new /v1/responses path for the OpenAI endpoint type.


451-451: LGTM!

The JSON placeholder correctly demonstrates the new endpoint format, providing users with an accurate example.

web/src/constants/playground.constants.js (1)

78-78: LGTM!

The API endpoint constant correctly updated from CHAT_COMPLETIONS to RESPONSES, matching the backend route changes. Verification confirms no lingering references to the old constant in JavaScript code, and the backend maintains the old endpoint path for backward compatibility.

web/src/helpers/api.js (3)

117-135: LGTM - Clean content transformation helper.

The toResponsesContent function correctly transforms chat completions content format to the Responses API format (textinput_text, image_urlinput_image). The null checks and filtering are appropriate.

One minor observation: if item.text is undefined, line 125 will produce { type: 'input_text', text: '' } - this may be intentional for graceful degradation, but verify this is the desired behavior for malformed input.


140-143: LGTM - Payload restructured for Responses API.

The mapping correctly transforms messages into the input array format expected by the Responses API, applying content normalization via toResponsesContent.


148-162: LGTM - Parameter mapping correctly updated.

The change from inputs[param] to inputs[key] on line 156 is correct: the value is read using the original key (e.g., max_tokens) from inputs, then assigned to the payload using the mapped parameter name (e.g., max_output_tokens). This properly handles the Responses API naming convention.

web/src/hooks/playground/useApiRequest.jsx (5)

188-195: LGTM - Endpoint correctly updated to Responses API.

The non-stream request now uses API_ENDPOINTS.RESPONSES (which is /pg/responses per the constants), aligning with the PR's migration to the Responses API.


231-242: LGTM - Robust output extraction with appropriate fallbacks.

The extraction logic correctly handles both:

  1. Direct output_text string (preferred path)
  2. Structured output array with nested content items

The flatMapfiltermapjoin chain is well-structured. The fallback to empty string ensures graceful degradation for unexpected response shapes.


325-417: LGTM - Well-structured unified SSE event handler.

The consolidated handleStreamEvent function improves maintainability by centralizing event processing. Key observations:

  1. Legacy [DONE] fallback is preserved for backward compatibility
  2. Event-type-specific handling is clean and readable
  3. Error events (response.failed, response.incomplete) properly close the stream and update UI

Minor note: The response.output_text.delta handler silently returns if data.delta is not a string (lines 362-367). This is acceptable defensive coding but could mask malformed events during debugging.


419-434: LGTM - Comprehensive SSE event registration.

The explicit list of responseEventTypes clearly documents the expected SSE contract from the Responses API. Registering each type individually with the same handler, plus a generic message fallback, ensures robust event capture.


504-504: LGTM - Dependency array correctly reflects actual usage.

The handleSSE callback's dependencies are correctly listed. Unlike the summary's mention of dropping applyAutoCollapseLogic, this is correct because handleSSE doesn't call it directly—it's used internally by streamMessageUpdate and completeMessage, which are properly included.

@FlowerRealm FlowerRealm closed this by deleting the head repository Dec 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant