Skip to content

Conversation

@jordanrfrazier
Copy link
Collaborator

@jordanrfrazier jordanrfrazier commented Oct 28, 2025

Ported over from release branch - #10216

Summary by CodeRabbit

  • New Features
    • Added support for multimodal inputs combining text and images in agent interactions
    • Enhanced streaming to deliver individual tokens separately with proper message tracking and ID preservation
    • Implemented filtering of empty content during streaming for cleaner message handling
    • Improved partial message state accumulation for more robust message reconstruction

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 28, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This PR adds streaming support and multimodal input handling to the agent framework. It refactors event handling to use callback-based workflows, introduces token streaming via callbacks, adds helper methods for message conversion with empty-text skipping, and includes tests for streaming behavior and multimodal content extraction.

Changes

Cohort / File(s) Summary
Agent Event Tests
src/backend/tests/unit/components/agents/test_agent_events.py
Updates event handler test calls to pass None instead of 0.0 and adds four new streaming tests: verifying individual chunk streaming, streaming without event manager, empty chunk skipping, and message ID preservation across token events.
Multimodal Agent Tests
src/backend/tests/unit/components/agents/test_multimodal_agent.py
Introduces MockAgentComponent and four tests for multimodal input handling: text extraction from mixed content, image-only content, simple text inputs, and empty/whitespace filtering.
Frontend Message Store
src/frontend/src/stores/messagesStore.ts
Updates message addition logic to accumulate text for partial messages via updateMessageText while preserving other fields; adds text safety initialization for undefined message text.
Agent Core Implementation
src/lfx/src/lfx/base/agents/agent.py
Adds _data_to_messages_skip_empty helper, refactors run_agent to explicitly handle Message-type inputs with multimodal content extraction (images/text), integrates OnTokenFunctionType callback for token streaming, and improves input text robustness with fallback prompts.
Event Handling Refactor
src/lfx/src/lfx/base/agents/events.py
Replaces direct method calls with send_message_callback and optional send_token_callback; adds had_streaming and message_id parameters to handlers; strengthens streaming via token callbacks; expands _extract_output_text to handle more dict formats; updates process_agent_events to initialize and propagate message IDs.

Sequence Diagram(s)

sequenceDiagram
    participant Agent as Agent (agent.py)
    participant EventMgr as Event Manager
    participant Events as Event Handler (events.py)
    participant TokenCB as Token Callback
    participant MsgCB as Message Callback

    Agent->>EventMgr: get on_token_callback()
    Agent->>Events: process_agent_events(..., send_message_callback, send_token_callback)
    
    Note over Events: Initialize message_id
    Events->>Events: detect streaming
    
    alt Streaming Path
        Events->>Events: on_chain_stream event
        rect rgb(200, 240, 255)
            Note over Events: Stream tokens
            loop Each token chunk
                Events->>TokenCB: send_token_callback(chunk, message_id)
            end
        end
        Events->>MsgCB: send_message_callback(final_message)
    else Non-Streaming Path
        Events->>Events: on_chain_end event
        Events->>MsgCB: send_message_callback(message)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45–60 minutes

Areas requiring extra attention:

  • Callback-based event handling refactor (src/lfx/src/lfx/base/agents/events.py): Core logic change replacing method-based dispatch; verify token streaming and message finalization flow consistency across all handlers.
  • Multimodal content extraction (src/lfx/src/lfx/base/agents/agent.py): Logic for extracting images and text from lc_message.content; ensure all content types are correctly handled.
  • Message state accumulation (src/frontend/src/stores/messagesStore.ts): Verify partial message text accumulation doesn't cause duplicate or lost text segments.
  • Streaming integration between frontend and backend: Token callbacks must propagate message IDs correctly and handle concurrent streams.

Suggested labels

enhancement, size:L

Suggested reviewers

  • rjordanfrazier

Pre-merge checks and finishing touches

❌ Failed checks (1 error, 3 warnings)
Check name Status Explanation Resolution
Test Coverage For New Implementations ❌ Error The PR includes test coverage for new implementations: backend tests in test_agent_events.py (four new async streaming tests) and test_multimodal_agent.py (four new multimodal tests), and a frontend test file exists at src/frontend/src/stores/tests/messagesStore.test.ts with 752 lines. However, the frontend test "should call updateMessagePartial for existing message" does NOT test the new specific behavior introduced in this PR. The messagesStore.ts implementation contains new code (lines 21-26) that checks if (message.properties?.state === "partial") to accumulate text via updateMessageText, but the existing test does not set properties.state to "partial", so it never exercises this new branch. Additionally, critical infrastructure issues in the backend tests remain unfixed: the import statement is incorrect, four async tests lack @pytest.mark.asyncio decorators, MockAgentComponent lacks the abstract build_agent method, test_multimodal_agent.py lacks a trailing newline, and multiple code logic errors in production files remain unresolved. To pass this check, apply all review comment fixes to resolve backend infrastructure issues: correct the import in test_agent_events.py line 7, add @pytest.mark.asyncio to all four async tests, implement build_agent in MockAgentComponent, add trailing newline to test_multimodal_agent.py, and fix production code in agent.py and events.py. Additionally, add a new frontend test to messagesStore.test.ts that explicitly tests the NEW partial state accumulation behavior: create a test that adds a message with properties.state === "partial", verifies text is accumulated (not replaced), and verifies other properties are updated while preserving accumulated text.
Docstring Coverage ⚠️ Warning Docstring coverage is 46.34% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Test Quality And Coverage ⚠️ Warning The tests demonstrate solid quality with comprehensive coverage of new functionality—they are not smoke tests but include meaningful assertions validating specific behaviors like token streaming without accumulation, empty chunk filtering, message ID preservation across streams, and multimodal content extraction. However, critical infrastructure issues prevent proper execution. The four new async streaming tests in test_agent_events.py lack the required @pytest.mark.asyncio decorator (lines 735, 808, 851, 906), which pytest-asyncio requires even with asyncio_mode = "auto" configured. Additionally, line 7 incorrectly imports process_agent_events from lfx.base.agents.agent instead of lfx.base.agents.events. The test_multimodal_agent.py file instantiates the abstract MockAgentComponent class without implementing the required abstract build_agent() method, causing instantiation failures. These infrastructure defects prevent test execution entirely, meaning the meaningful test logic cannot run to validate the new streaming and multimodal functionality. Apply the following corrections to enable test execution: (1) Add @pytest.mark.asyncio decorator to all four new async test functions in test_agent_events.py (test_agent_streaming_no_text_accumulation at line 735, test_agent_streaming_without_event_manager at line 808, test_agent_streaming_skips_empty_chunks at line 851, and test_agent_streaming_preserves_message_id at line 906). (2) Fix the import on line 7 of test_agent_events.py from from lfx.base.agents.agent import process_agent_events to from lfx.base.agents.events import process_agent_events. (3) Add a stub implementation of the abstract build_agent() method to MockAgentComponent in test_multimodal_agent.py that raises NotImplementedError. (4) Add a trailing newline to the end of test_multimodal_agent.py to satisfy Ruff W292 linting requirement.
Test File Naming And Structure ⚠️ Warning
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "fix: stream tokens in agent instead of accumulated responses" directly aligns with the primary objective demonstrated across all modified files. The backend refactoring in events.py replaces direct method calls with callback-based streaming to send individual token chunks, the frontend messagesStore.ts updates message handling to accumulate text while supporting partial state, and the new tests explicitly verify that individual streaming chunks are sent separately without accumulation. The title is concise, clear, and accurately captures the core change without unnecessary detail or vague terminology.
Excessive Mock Usage Warning ✅ Passed The mock usage in this PR is appropriate and not excessive. The new streaming tests in test_agent_events.py (4 tests, 223 lines total) use simple function stubs (mock_send_message, mock_token_callback) rather than Mock objects—these are test doubles that capture behavior for verification, not complex mocks that assert on call interactions. The core system under test (process_agent_events and its handlers) runs with real implementations and real Message/ContentBlock objects, ensuring actual business logic is validated. In test_multimodal_agent.py, MagicMock is used minimally for external library objects (langchain message structures) and for the log attribute in MockAgentComponent, which is appropriate for isolating external dependencies. The MockAgentComponent itself exists only to satisfy abstract base class requirements, not to mock business logic. Overall, mocks are properly scoped to external boundaries while core streaming behavior is tested directly.

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.

@jordanrfrazier jordanrfrazier changed the title fix: agent streaming functionality; avoids accumulating responses fix: stream tokens in agent instead of accumulated responses Oct 28, 2025
@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Oct 28, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Oct 28, 2025

Frontend Unit Test Coverage Report

Coverage Summary

Lines Statements Branches Functions
Coverage: 12%
12.56% (3357/26710) 5.77% (1176/20377) 7.69% (450/5848)

Unit Test Results

Tests Skipped Failures Errors Time
1319 0 💤 0 ❌ 0 🔥 15.255s ⏱️

@codecov
Copy link

codecov bot commented Oct 28, 2025

Codecov Report

❌ Patch coverage is 10.29412% with 61 lines in your changes missing coverage. Please review.
✅ Project coverage is 30.63%. Comparing base (1d16a2e) to head (f22b4a0).

Files with missing lines Patch % Lines
src/lfx/src/lfx/base/agents/agent.py 10.25% 35 Missing ⚠️
src/lfx/src/lfx/base/agents/events.py 8.69% 21 Missing ⚠️
src/frontend/src/stores/messagesStore.ts 16.66% 3 Missing and 2 partials ⚠️

❌ Your patch check has failed because the patch coverage (10.29%) is below the target coverage (40.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main   #10425      +/-   ##
==========================================
- Coverage   30.64%   30.63%   -0.01%     
==========================================
  Files        1318     1318              
  Lines       59710    59734      +24     
  Branches     8926     8934       +8     
==========================================
+ Hits        18298    18300       +2     
- Misses      40565    40584      +19     
- Partials      847      850       +3     
Flag Coverage Δ
frontend 11.56% <16.66%> (-0.01%) ⬇️
lfx 39.38% <9.67%> (-0.03%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/frontend/src/stores/messagesStore.ts 87.23% <16.66%> (-10.39%) ⬇️
src/lfx/src/lfx/base/agents/events.py 16.58% <8.69%> (+0.17%) ⬆️
src/lfx/src/lfx/base/agents/agent.py 27.38% <10.25%> (-1.49%) ⬇️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Oct 28, 2025
@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Oct 28, 2025
@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Oct 28, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 12

Caution

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

⚠️ Outside diff range comments (1)
src/lfx/src/lfx/base/agents/events.py (1)

75-79: BaseMessage handling uses non-existent .text(); extract content safely.

Use .content and normalize to string.

Apply:

@@
-            if isinstance(input_message, BaseMessage):
-                input_message = input_message.text()
+            if isinstance(input_message, BaseMessage):
+                content = getattr(input_message, "content", "")
+                if isinstance(content, list):
+                    parts = [
+                        it.get("text", "")
+                        for it in content
+                        if isinstance(it, dict) and it.get("type") == "text" and (it.get("text") or "").strip()
+                    ]
+                    input_message = " ".join(parts)
+                else:
+                    input_message = str(content)
🧹 Nitpick comments (4)
src/backend/tests/unit/components/agents/test_multimodal_agent.py (1)

31-62: Avoid duplicating production parsing logic in tests.

These tests reimplement run_agent’s multimodal parsing. Extract a small helper (e.g., _extract_text_and_images) in LCAgentComponent and test that directly to prevent drift.

src/backend/tests/unit/components/agents/test_agent_events.py (2)

762-762: Prefer setting Message.id, not stuffing id into .data.

process_agent_events should read message.id; update the test accordingly.

Apply:

@@
-    agent_message.data["id"] = "test-message-id"
+    agent_message.id = "test-message-id"

Do the same in other tests that set the id.


458-458: Remove stray no-op f-string.

This expression has no effect.

Apply:

-    f"{end_event['name']}_{end_event['run_id']}"
+    # tool_key = f"{end_event['name']}_{end_event['run_id']}"  # not needed; relying on updated content lookup
src/lfx/src/lfx/base/agents/events.py (1)

333-341: Tighten tool handler Protocol typing.

Use ToolContent to match actual handlers and map.

Apply:

@@
-class ToolEventHandler(Protocol):
+class ToolEventHandler(Protocol):
     async def __call__(
         self,
         event: dict[str, Any],
         agent_message: Message,
-        tool_blocks_map: dict[str, ContentBlock],
+        tool_blocks_map: dict[str, ToolContent],
         send_message_callback: SendMessageFunctionType,
         start_time: float,
     ) -> tuple[Message, float]: ...
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d707176 and a6f3c19.

📒 Files selected for processing (5)
  • src/backend/tests/unit/components/agents/test_agent_events.py (10 hunks)
  • src/backend/tests/unit/components/agents/test_multimodal_agent.py (1 hunks)
  • src/frontend/src/stores/messagesStore.ts (2 hunks)
  • src/lfx/src/lfx/base/agents/agent.py (6 hunks)
  • src/lfx/src/lfx/base/agents/events.py (16 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
src/frontend/src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/frontend_development.mdc)

src/frontend/src/**/*.{ts,tsx,js,jsx}: All frontend TypeScript and JavaScript code should be located under src/frontend/src/ and organized into components, pages, icons, stores, types, utils, hooks, services, and assets directories as per the specified directory layout.
Use React 18 with TypeScript for all UI components in the frontend.
Format all TypeScript and JavaScript code using the make format_frontend command.
Lint all TypeScript and JavaScript code using the make lint command.

Files:

  • src/frontend/src/stores/messagesStore.ts
src/frontend/src/stores/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/frontend_development.mdc)

Use Zustand for state management in frontend stores.

Files:

  • src/frontend/src/stores/messagesStore.ts
src/backend/tests/unit/components/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)

src/backend/tests/unit/components/**/*.py: Mirror the component directory structure for unit tests in src/backend/tests/unit/components/
Use ComponentTestBaseWithClient or ComponentTestBaseWithoutClient as base classes for component unit tests
Provide file_names_mapping for backward compatibility in component tests
Create comprehensive unit tests for all new components

Files:

  • src/backend/tests/unit/components/agents/test_multimodal_agent.py
  • src/backend/tests/unit/components/agents/test_agent_events.py
{src/backend/**/*.py,tests/**/*.py,Makefile}

📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)

{src/backend/**/*.py,tests/**/*.py,Makefile}: Run make format_backend to format Python code before linting or committing changes
Run make lint to perform linting checks on backend Python code

Files:

  • src/backend/tests/unit/components/agents/test_multimodal_agent.py
  • src/backend/tests/unit/components/agents/test_agent_events.py
src/backend/tests/unit/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)

Test component integration within flows using create_flow, build_flow, and get_build_events utilities

Files:

  • src/backend/tests/unit/components/agents/test_multimodal_agent.py
  • src/backend/tests/unit/components/agents/test_agent_events.py
src/backend/tests/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/testing.mdc)

src/backend/tests/**/*.py: Unit tests for backend code must be located in the 'src/backend/tests/' directory, with component tests organized by component subdirectory under 'src/backend/tests/unit/components/'.
Test files should use the same filename as the component under test, with an appropriate test prefix or suffix (e.g., 'my_component.py' → 'test_my_component.py').
Use the 'client' fixture (an async httpx.AsyncClient) for API tests in backend Python tests, as defined in 'src/backend/tests/conftest.py'.
When writing component tests, inherit from the appropriate base class in 'src/backend/tests/base.py' (ComponentTestBase, ComponentTestBaseWithClient, or ComponentTestBaseWithoutClient) and provide the required fixtures: 'component_class', 'default_kwargs', and 'file_names_mapping'.
Each test in backend Python test files should have a clear docstring explaining its purpose, and complex setups or mocks should be well-commented.
Test both sync and async code paths in backend Python tests, using '@pytest.mark.asyncio' for async tests.
Mock external dependencies appropriately in backend Python tests to isolate unit tests from external services.
Test error handling and edge cases in backend Python tests, including using 'pytest.raises' and asserting error messages.
Validate input/output behavior and test component initialization and configuration in backend Python tests.
Use the 'no_blockbuster' pytest marker to skip the blockbuster plugin in tests when necessary.
Be aware of ContextVar propagation in async tests; test both direct event loop execution and 'asyncio.to_thread' scenarios to ensure proper context isolation.
Test error handling by mocking internal functions using monkeypatch in backend Python tests.
Test resource cleanup in backend Python tests by using fixtures that ensure proper initialization and cleanup of resources.
Test timeout and performance constraints in backend Python tests using 'asyncio.wait_for' and timing assertions.
Test Langflow's Messag...

Files:

  • src/backend/tests/unit/components/agents/test_multimodal_agent.py
  • src/backend/tests/unit/components/agents/test_agent_events.py
src/backend/**/components/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/icons.mdc)

In your Python component class, set the icon attribute to a string matching the frontend icon mapping exactly (case-sensitive).

Files:

  • src/backend/tests/unit/components/agents/test_multimodal_agent.py
  • src/backend/tests/unit/components/agents/test_agent_events.py
**/{test_*.py,*.test.ts,*.test.tsx}

📄 CodeRabbit inference engine (coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt)

**/{test_*.py,*.test.ts,*.test.tsx}: Check if tests have too many mock objects that obscure what’s actually being tested
Warn when mocks are used instead of testing real behavior and interactions
Suggest using real objects or simpler test doubles when mocks become excessive
Ensure mocks are used only for external dependencies, not core business logic
Recommend integration tests when unit tests become overly mocked
Check that test files follow the project’s naming conventions (backend: test_*.py; frontend: *.test.ts/tsx)
Verify that tests actually exercise the new or changed functionality, not placeholder assertions
Test files should have descriptive test function names explaining what is being tested
Organize tests logically with proper setup and teardown
Include edge cases and error conditions for comprehensive coverage
Verify tests cover both positive (success) and negative (failure) scenarios
Ensure tests are not mere smoke tests; they should validate behavior thoroughly
Ensure tests follow the project’s testing frameworks (pytest for backend, Playwright for frontend)

Files:

  • src/backend/tests/unit/components/agents/test_multimodal_agent.py
  • src/backend/tests/unit/components/agents/test_agent_events.py
**/test_*.py

📄 CodeRabbit inference engine (coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt)

**/test_*.py: Backend tests must be named test_*.py and use proper pytest structure (fixtures, assertions)
For async backend code, use proper pytest async patterns (e.g., pytest-asyncio)
For API endpoints, include tests for both success and error responses

Files:

  • src/backend/tests/unit/components/agents/test_multimodal_agent.py
  • src/backend/tests/unit/components/agents/test_agent_events.py
🧬 Code graph analysis (4)
src/backend/tests/unit/components/agents/test_multimodal_agent.py (2)
src/lfx/src/lfx/base/agents/agent.py (1)
  • LCAgentComponent (35-278)
src/lfx/src/lfx/schema/message.py (1)
  • Message (34-299)
src/lfx/src/lfx/base/agents/events.py (2)
src/lfx/src/lfx/schema/log.py (2)
  • OnTokenFunctionType (41-44)
  • SendMessageFunctionType (22-38)
src/lfx/src/lfx/schema/message.py (1)
  • Message (34-299)
src/backend/tests/unit/components/agents/test_agent_events.py (3)
src/lfx/src/lfx/base/agents/events.py (4)
  • handle_on_chain_start (56-93)
  • handle_on_chain_end (150-182)
  • handle_on_chain_stream (292-329)
  • process_agent_events (374-428)
src/backend/tests/unit/components/agents/test_multimodal_agent.py (1)
  • send_message (24-25)
src/lfx/src/lfx/custom/custom_component/component.py (1)
  • send_message (1552-1603)
src/lfx/src/lfx/base/agents/agent.py (4)
src/backend/base/langflow/memory.py (1)
  • messages (340-345)
src/lfx/src/lfx/custom/custom_component/component.py (1)
  • log (1480-1497)
src/lfx/src/lfx/schema/message.py (1)
  • Message (34-299)
src/lfx/src/lfx/schema/data.py (1)
  • Data (26-288)
🪛 GitHub Actions: Ruff Style Check
src/backend/tests/unit/components/agents/test_multimodal_agent.py

[error] 119-119: Ruff: W292 No newline at end of file.

🪛 GitHub Check: Ruff Style Check (3.13)
src/backend/tests/unit/components/agents/test_multimodal_agent.py

[failure] 119-119: Ruff (W292)
src/backend/tests/unit/components/agents/test_multimodal_agent.py:119:39: W292 No newline at end of file

src/lfx/src/lfx/base/agents/events.py

[failure] 123-123: Ruff (E501)
src/lfx/src/lfx/base/agents/events.py:123:121: E501 Line too long (129 > 120)


[failure] 117-117: Ruff (W293)
src/lfx/src/lfx/base/agents/events.py:117:1: W293 Blank line contains whitespace

src/lfx/src/lfx/base/agents/agent.py

[failure] 28-28: Ruff (I001)
src/lfx/src/lfx/base/agents/agent.py:28:5: I001 Import block is un-sorted or un-formatted


[failure] 195-195: Ruff (F821)
src/lfx/src/lfx/base/agents/agent.py:195:52: F821 Undefined name input_text


[failure] 195-195: Ruff (F821)
src/lfx/src/lfx/base/agents/agent.py:195:27: F821 Undefined name input_text


[failure] 178-178: Ruff (W291)
src/lfx/src/lfx/base/agents/agent.py:178:97: W291 Trailing whitespace


[failure] 175-175: Ruff (W293)
src/lfx/src/lfx/base/agents/agent.py:175:1: W293 Blank line contains whitespace


[failure] 167-167: Ruff (W293)
src/lfx/src/lfx/base/agents/agent.py:167:1: W293 Blank line contains whitespace

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 4
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 2
  • GitHub Check: Test Docker Images / Test docker images
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 5
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 3
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 1
  • GitHub Check: Run Backend Tests / Integration Tests - Python 3.10
  • GitHub Check: Test Starter Templates
🔇 Additional comments (5)
src/frontend/src/stores/messagesStore.ts (2)

72-72: LGTM: Safe text concatenation.

The nullish coalescing ensures that text concatenation works even when the current text is undefined or null, preventing potential runtime errors during streaming updates.


21-31: Frontend streaming logic is correct; verify backend integration to confirm final messages include complete text.

Based on verification of the codebase:

The updateMessagePartial method uses spread operators ({ ...updatedMessages[i], ...message }) which correctly allow the final message to overwrite accumulated properties. The backend ensures that when state transitions from "partial" to "complete", the final message includes the complete accumulated text extracted via _extract_output_text() before sending (see events.py lines 161–165 and 302–307).

The frontend logic correctly:

  • Accumulates partial message text incrementally (line 24: get().updateMessageText(...))
  • Removes the text property from partials before updating other fields (line 26: const { text, ...messageWithoutText })
  • Replaces the entire message on completion (line 29: get().updateMessagePartial(message) with full object)

This design pattern properly mirrors the backend's behavior where streaming chunks are processed incrementally, then a complete final message containing the full accumulated output replaces all previous state.

src/backend/tests/unit/components/agents/test_multimodal_agent.py (1)

1-29: Consider adding a flow-level integration test.

Per guidelines, include at least one create_flow/build_flow/get_build_events-based test that exercises multimodal input end-to-end through the agent.

src/lfx/src/lfx/base/agents/agent.py (2)

167-179: Clean up whitespace-only lines at 167, 175, and 178 (verified Ruff W293 violations detected).

Run make format_backend to resolve.


22-29: Remove duplicate OnTokenFunctionType from TYPE_CHECKING block.

OnTokenFunctionType is correctly imported at runtime on line 22 but incorrectly duplicated in the TYPE_CHECKING block on line 28. Since it's used at runtime (lines 234–236), it belongs only in the runtime import. The TYPE_CHECKING block should contain only SendMessageFunctionType.

The proposed diff correctly removes the duplicate:

-if TYPE_CHECKING:
-    from lfx.schema.log import SendMessageFunctionType, OnTokenFunctionType
+if TYPE_CHECKING:
+    from lfx.schema.log import SendMessageFunctionType

@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Oct 30, 2025
@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Oct 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants