Skip to content

Inter-Browser Communication and Coordination#2

Open
ngoiyaeric wants to merge 2 commits intomainfrom
feature/inter-browser-communication-15229832897328717329
Open

Inter-Browser Communication and Coordination#2
ngoiyaeric wants to merge 2 commits intomainfrom
feature/inter-browser-communication-15229832897328717329

Conversation

@ngoiyaeric
Copy link
Copy Markdown
Owner

@ngoiyaeric ngoiyaeric commented Jan 31, 2026

User description

Implemented inter-browser communication by extending the Scheduler to act as a data hub and updating the ResourceManager to prioritize tasks in the same communication channel. Added new tools for agents to share and retrieve data within these channels, and ensured subtasks inherit their parent's channel for seamless coordination.


PR created automatically by Jules for task 15229832897328717329 started by @ngoiyaeric


PR Type

Enhancement


Description

  • Implement inter-browser communication via communication channels

    • Extended TaskState with communication_channel and shared_data fields
    • Added share_data and get_shared_data tools for agents
  • Prioritize tasks by channel density in ResourceManager

    • New _prioritize_tasks_by_channel method sorts tasks by channel population
    • Integrated into task allocation logic for optimized execution
  • Enable automatic channel inheritance for subtasks

    • Subtasks inherit parent task's communication channel
  • Add comprehensive test coverage for new functionality


Diagram Walkthrough

flowchart LR
  TaskState["TaskState<br/>+ communication_channel<br/>+ shared_data"]
  Scheduler["Scheduler<br/>priority_sort adds<br/>channel group"]
  ResourceManager["ResourceManager<br/>_prioritize_tasks_by_channel"]
  Tools["Tools<br/>+ share_data<br/>+ get_shared_data"]
  Subtask["Subtask Creation<br/>inherits channel"]
  
  TaskState -->|extends| Scheduler
  Scheduler -->|uses| ResourceManager
  Tools -->|accesses| TaskState
  Subtask -->|inherits from| TaskState
  ResourceManager -->|optimizes| Tools
Loading

File Walkthrough

Relevant files
Enhancement
scheduler.py
Add communication channel support to task scheduling         

blastai/scheduler.py

  • Added communication_channel and shared_data fields to TaskState
    dataclass
  • Updated schedule_task and schedule_subtask methods to accept
    communication_channel parameter
  • Modified priority_sort to include new "channel" priority group (Group
    3)
  • Channel tasks are now prioritized between subtasks and paused executor
    tasks
+26/-4   
resource_manager.py
Add channel-aware task prioritization logic                           

blastai/resource_manager.py

  • Implemented _prioritize_tasks_by_channel method to sort tasks by
    channel density
  • Channels with more tasks are prioritized; tasks without channels come
    last
  • Integrated channel prioritization into task allocation logic
  • Applied sorting before selecting tasks to allocate to new executors
+31/-1   
tools.py
Add inter-browser communication tools and channel inheritance

blastai/tools.py

  • Added communication_channel attribute to Tools class
  • Inherited communication_channel from parent task during initialization
  • Implemented share_data tool for broadcasting data to related browsers
  • Implemented get_shared_data tool for retrieving shared data from
    channel
  • Updated launch_subtask to pass communication_channel to subtasks
+48/-1   
Tests
test_browser_communication.py
Add comprehensive tests for inter-browser communication   

tests/test_browser_communication.py

  • Added test_inter_browser_communication covering full communication
    workflow
  • Tests channel assignment, priority sorting, and channel density
    prioritization
  • Tests share_data and get_shared_data tool functionality
  • Tests channel isolation between different communication channels
  • Added test_share_data_with_targets for selective data sharing
  • Added test_channel_inheritance for subtask channel inheritance
+110/-0 

Summary by CodeRabbit

New Features

  • Introduced task communication channels for coordinated multi-task execution
  • Added data sharing tools enabling tasks to broadcast and retrieve data within their communication channel
  • Enhanced task allocation to prioritize channels by density for improved execution efficiency
  • Subtasks automatically inherit their parent task's communication channel

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

…ization

This change enables isolated browser instances to share data and coordinate tasks
through the Scheduler. Key changes include:
- Extended TaskState to support communication channels and shared data.
- Added share_data and get_shared_data tools for agents.
- Implemented channel density prioritization in ResourceManager to optimize
  concurrent execution of related tasks.
- Added automatic channel inheritance for subtasks.
- Included comprehensive tests for the new functionality.

Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jan 31, 2026

📝 Walkthrough

Walkthrough

This PR introduces a channel-based task communication system. It adds communication_channel metadata to tasks, prioritizes executor allocation by channel density, provides inter-task data sharing utilities, and includes comprehensive integration tests for the new orchestration capabilities.

Changes

Cohort / File(s) Summary
Channel-Aware Task Prioritization
blastai/resource_manager.py
New private method _prioritize_tasks_by_channel() groups tasks by channel and orders them by density (descending). Updated allocation flow to prioritize high-density channels when assigning new executors to a group.
Task Communication Metadata
blastai/scheduler.py
Added communication_channel and shared_data attributes to TaskState. Expanded schedule_task() and schedule_subtask() signatures to accept and propagate communication_channel. Restructured priority sorting logic to process channel-grouped tasks before paused-executor groups.
Data Sharing Tools
blastai/tools.py
Added communication_channel attribute to Tools class, auto-initialized from parent task. Introduced share_data() and get_shared_data() methods for broadcasting/retrieving data across tasks within the same channel. Updated subtask scheduling to propagate communication_channel to children.
Integration Tests
tests/test_browser_communication.py
New comprehensive test module validating channel-based task scheduling, executor priority grouping, data sharing across task boundaries, channel inheritance in subtasks, and isolation of data within channels.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Scheduler
    participant ResourceMgr
    participant Tools
    participant Task as Task (with channel)
    
    Client->>Scheduler: schedule_task(communication_channel='ch1')
    Scheduler->>Scheduler: create TaskState with channel
    Scheduler->>Scheduler: group by channel priority
    
    Client->>ResourceMgr: allocate_executors()
    ResourceMgr->>ResourceMgr: _prioritize_tasks_by_channel()
    ResourceMgr->>ResourceMgr: order channels by density
    ResourceMgr->>Scheduler: fetch prioritized task_ids
    
    Task->>Tools: share_data('ch1', data)
    Tools->>Scheduler: find all tasks with channel='ch1'
    Scheduler->>Scheduler: update shared_data on each task
    Tools-->>Task: success
    
    Task->>Tools: get_shared_data('ch1')
    Tools->>Scheduler: aggregate shared_data from channel
    Tools-->>Task: combined_data
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 Channels bloom where tasks align,
Density guides the way,
Data flows through shared lines,
Rabbit hops from bay to bay! 🌾✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Inter-Browser Communication and Coordination' accurately summarizes the main objective of the PR, which implements inter-browser communication features across multiple files (scheduler, resource manager, tools, and tests).
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/inter-browser-communication-15229832897328717329

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.

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review bot commented Jan 31, 2026

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
Unauthorized data access

Description: The new share_data/get_shared_data actions allow any caller to specify an arbitrary
channel and read/write shared data for all tasks in that channel without verifying that
the calling task belongs to that channel (or is authorized), enabling cross-task data
exfiltration or tampering if an agent can guess/learn channel IDs (e.g., calling
get_shared_data(channel="channel_1") from a task in channel_2).
tools.py [152-195]

Referred Code
@self.controller.action("Share data with related browsers")
async def share_data(channel: str, data: str, target_task_ids: Optional[str] = None) -> ActionResult:
    """Share data across browsers in the same problem space.

    Args:
        channel: Communication channel ID
        data: Data to share (string)
        target_task_ids: Optional comma-separated list of task IDs to share with.
                       If not provided, shares with all tasks in the channel.
    """
    # Get all tasks in the same communication channel
    related_tasks = [
        task
        for task in scheduler.tasks.values()
        if task.communication_channel == channel and task.id != self.task_id
    ]

    # Filter by target_task_ids if provided
    if target_task_ids:
        targets = [tid.strip() for tid in target_task_ids.split(",")]
        related_tasks = [task for task in related_tasks if task.id in targets]


 ... (clipped 23 lines)
Resource exhaustion

Description: The new channel-wide sharing stores attacker-controlled data strings into task.shared_data
for potentially many tasks and returns aggregated json.dumps(shared_data) without size
limits or eviction, which can be exploited to cause unbounded memory growth and/or very
large serialized responses (denial of service) by repeatedly sharing large payloads across
many tasks.
tools.py [152-195]

Referred Code
@self.controller.action("Share data with related browsers")
async def share_data(channel: str, data: str, target_task_ids: Optional[str] = None) -> ActionResult:
    """Share data across browsers in the same problem space.

    Args:
        channel: Communication channel ID
        data: Data to share (string)
        target_task_ids: Optional comma-separated list of task IDs to share with.
                       If not provided, shares with all tasks in the channel.
    """
    # Get all tasks in the same communication channel
    related_tasks = [
        task
        for task in scheduler.tasks.values()
        if task.communication_channel == channel and task.id != self.task_id
    ]

    # Filter by target_task_ids if provided
    if target_task_ids:
        targets = [tid.strip() for tid in target_task_ids.split(",")]
        related_tasks = [task for task in related_tasks if task.id in targets]


 ... (clipped 23 lines)
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

🔴
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
Missing audit logs: The new share_data and get_shared_data actions modify and expose cross-task shared state
without any audit logging of who accessed/changed what, in which channel, and with what
outcome.

Referred Code
@self.controller.action("Share data with related browsers")
async def share_data(channel: str, data: str, target_task_ids: Optional[str] = None) -> ActionResult:
    """Share data across browsers in the same problem space.

    Args:
        channel: Communication channel ID
        data: Data to share (string)
        target_task_ids: Optional comma-separated list of task IDs to share with.
                       If not provided, shares with all tasks in the channel.
    """
    # Get all tasks in the same communication channel
    related_tasks = [
        task
        for task in scheduler.tasks.values()
        if task.communication_channel == channel and task.id != self.task_id
    ]

    # Filter by target_task_ids if provided
    if target_task_ids:
        targets = [tid.strip() for tid in target_task_ids.split(",")]
        related_tasks = [task for task in related_tasks if task.id in targets]


 ... (clipped 23 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
No access controls: get_shared_data and share_data accept an arbitrary channel string and return/broadcast all
matching shared_data without authentication/authorization checks or validation that the
caller belongs to that channel.

Referred Code
@self.controller.action("Share data with related browsers")
async def share_data(channel: str, data: str, target_task_ids: Optional[str] = None) -> ActionResult:
    """Share data across browsers in the same problem space.

    Args:
        channel: Communication channel ID
        data: Data to share (string)
        target_task_ids: Optional comma-separated list of task IDs to share with.
                       If not provided, shares with all tasks in the channel.
    """
    # Get all tasks in the same communication channel
    related_tasks = [
        task
        for task in scheduler.tasks.values()
        if task.communication_channel == channel and task.id != self.task_id
    ]

    # Filter by target_task_ids if provided
    if target_task_ids:
        targets = [tid.strip() for tid in target_task_ids.split(",")]
        related_tasks = [task for task in related_tasks if task.id in targets]


 ... (clipped 23 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Potential KeyError: _prioritize_tasks_by_channel indexes self.scheduler.tasks[tid] without guarding for
missing/invalid task IDs, which can raise and disrupt allocation if group.task_ids
contains stale IDs.

Referred Code
def _prioritize_tasks_by_channel(self, task_ids: List[str]) -> List[str]:
    """Sort tasks by communication channel density.

    Channels with more tasks in the given list are prioritized.
    Tasks without a channel come last.
    """
    channel_groups = {}
    no_channel_tasks = []
    for tid in task_ids:
        task = self.scheduler.tasks[tid]
        channel = task.communication_channel
        if channel:
            if channel not in channel_groups:
                channel_groups[channel] = []
            channel_groups[channel].append(tid)
        else:
            no_channel_tasks.append(tid)

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review bot commented Jan 31, 2026

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Prevent race conditions during updates

Use an asyncio.Lock when modifying a task's shared_data in the share_data
function to prevent potential race conditions from concurrent access.

blastai/tools.py [174-178]

 # Update shared data for all related tasks
 for task in related_tasks:
-    if not task.shared_data:
-        task.shared_data = {}
-    task.shared_data[self.task_id] = data
+    async with task.data_lock:  # Assuming data_lock is on TaskState
+        if not task.shared_data:
+            task.shared_data = {}
+        task.shared_data[self.task_id] = data
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a potential race condition when modifying shared_data concurrently and proposes a valid solution using asyncio.Lock to ensure thread safety, which is critical for system stability.

Medium
Security
Check sharing channel validity

In the share_data tool, add a validation check to ensure the calling task
belongs to the specified channel before proceeding to share data.

blastai/tools.py [153-167]

 async def share_data(channel: str, data: str, target_task_ids: Optional[str] = None) -> ActionResult:
     """Share data across browsers in the same problem space.
     ...
     """
+    # Prevent sharing on a channel this task doesn’t belong to
+    if channel != self.communication_channel:
+        return ActionResult(success=False, error="Unauthorized channel")
     # Get all tasks in the same communication channel
     related_tasks = [
         task
         for task in scheduler.tasks.values()
         if task.communication_channel == channel and task.id != self.task_id
     ]

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 8

__

Why: This suggestion adds a crucial security check to prevent a task from sharing data on a channel it doesn't belong to, which is a valid and important improvement for data integrity and security.

Medium
General
Avoid hardcoding implementation-dependent test values

In test_channel_inheritance, dynamically find the subtask by its parent_id
instead of using the hardcoded and implementation-dependent ID "B".

tests/test_browser_communication.py [107-110]

 # Check if subtask inherited channel
-subtask_id = "B" # Next ID after Parent (A)
-assert subtask_id in scheduler.tasks
-assert scheduler.tasks[subtask_id].communication_channel == "inherited_ch"
+subtask = next((t for t in scheduler.tasks.values() if t.parent_task_id == parent_id), None)
+assert subtask is not None
+assert subtask.communication_channel == "inherited_ch"
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly points out that hardcoding the subtask ID B makes the test fragile and proposes a more robust way to identify the subtask, improving test reliability.

Medium
  • Update

Copy link
Copy Markdown

@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: 2

Caution

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

⚠️ Outside diff range comments (1)
blastai/scheduler.py (1)

244-278: ⚠️ Potential issue | 🟠 Major

Subtasks don’t automatically inherit the parent channel when callers omit the parameter.
Direct schedule_subtask(...) calls will pass None even if the parent has a channel, which breaks the “automatic inheritance” guarantee.

🛠️ Suggested fix: default to parent channel when omitted
     def schedule_subtask(
         self,
         description: str,
         parent_task_id: str,
         cache_control: str = "",
         interactive_queues: Optional[Dict[str, asyncio.Queue]] = None,
         initial_url: Optional[str] = None,
         communication_channel: Optional[str] = None,
     ) -> str:
         """Schedule a subtask of an existing task.
@@
         if parent_task_id not in self.tasks:
             raise ValueError(f"Parent task {parent_task_id} not found")
+        if communication_channel is None:
+            communication_channel = self.tasks[parent_task_id].communication_channel
@@
         task_id = self.schedule_task(
             description=description,
             parent_task_id=parent_task_id,
             prerequisite_task_id=None,  # Explicitly set no prerequisite
             cache_control=cache_control,
             interactive_queues=interactive_queues,
             initial_url=initial_url,
             communication_channel=communication_channel,
         )
🤖 Fix all issues with AI agents
In `@blastai/tools.py`:
- Around line 152-195: The share_data and get_shared_data handlers allow any
task to access any channel by accepting an arbitrary channel string; to enforce
channel isolation, look up the caller task via self.task_id in scheduler.tasks
and verify its communication_channel matches the provided channel, and if not
reject the request (e.g., return an error ActionResult or raise) before
proceeding; apply this check at the start of both share_data and
get_shared_data, keeping existing logic (target filtering, updating
task.shared_data, and json.dumps) only after the authorization check.

In `@tests/test_browser_communication.py`:
- Around line 72-90: The test should stub the cache manager's get_result and
get_plan to return falsy values to prevent implicit cache hits that let
schedule_task auto-complete; locate the cache manager used in the test setup
(the MagicMock passed into Scheduler) and set its get_result and get_plan to
return None (or AsyncMock returning None if awaited) before calling
scheduler.schedule_task in test_share_data_with_targets, and apply the same
stubbing to the other test block referenced (lines 92-110) so tasks do not
auto-complete due to truthy MagicMock defaults.

Comment thread blastai/tools.py
Comment on lines +152 to +195
@self.controller.action("Share data with related browsers")
async def share_data(channel: str, data: str, target_task_ids: Optional[str] = None) -> ActionResult:
"""Share data across browsers in the same problem space.

Args:
channel: Communication channel ID
data: Data to share (string)
target_task_ids: Optional comma-separated list of task IDs to share with.
If not provided, shares with all tasks in the channel.
"""
# Get all tasks in the same communication channel
related_tasks = [
task
for task in scheduler.tasks.values()
if task.communication_channel == channel and task.id != self.task_id
]

# Filter by target_task_ids if provided
if target_task_ids:
targets = [tid.strip() for tid in target_task_ids.split(",")]
related_tasks = [task for task in related_tasks if task.id in targets]

# Update shared data for all related tasks
for task in related_tasks:
if not task.shared_data:
task.shared_data = {}
task.shared_data[self.task_id] = data

return ActionResult(extracted_content=f"Data shared with {len(related_tasks)} browsers")

@self.controller.action("Get shared data from problem space")
async def get_shared_data(channel: str) -> ActionResult:
"""Retrieve data shared by other browsers in the problem space.

Args:
channel: Communication channel ID
"""
shared_data = {}
for task in scheduler.tasks.values():
if task.communication_channel == channel and task.shared_data:
shared_data.update(task.shared_data)

return ActionResult(extracted_content=f"Shared data: {json.dumps(shared_data)}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Enforce channel isolation in share_data/get_shared_data.
Right now any task can read/write any channel by passing a channel string, which bypasses boundaries.

🔒 Suggested fix: reject cross-channel access
         `@self.controller.action`("Share data with related browsers")
         async def share_data(channel: str, data: str, target_task_ids: Optional[str] = None) -> ActionResult:
             """Share data across browsers in the same problem space.
@@
-            # Get all tasks in the same communication channel
+            if self.communication_channel is None:
+                return ActionResult(success=False, error="Task is not in a communication channel")
+            if channel != self.communication_channel:
+                return ActionResult(success=False, error="Channel mismatch")
+
+            # Get all tasks in the same communication channel
             related_tasks = [
                 task
                 for task in scheduler.tasks.values()
                 if task.communication_channel == channel and task.id != self.task_id
             ]
@@
         `@self.controller.action`("Get shared data from problem space")
         async def get_shared_data(channel: str) -> ActionResult:
             """Retrieve data shared by other browsers in the problem space.
@@
-            shared_data = {}
+            if self.communication_channel is None:
+                return ActionResult(success=False, error="Task is not in a communication channel")
+            if channel != self.communication_channel:
+                return ActionResult(success=False, error="Channel mismatch")
+
+            shared_data = {}
             for task in scheduler.tasks.values():
                 if task.communication_channel == channel and task.shared_data:
                     shared_data.update(task.shared_data)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@self.controller.action("Share data with related browsers")
async def share_data(channel: str, data: str, target_task_ids: Optional[str] = None) -> ActionResult:
"""Share data across browsers in the same problem space.
Args:
channel: Communication channel ID
data: Data to share (string)
target_task_ids: Optional comma-separated list of task IDs to share with.
If not provided, shares with all tasks in the channel.
"""
# Get all tasks in the same communication channel
related_tasks = [
task
for task in scheduler.tasks.values()
if task.communication_channel == channel and task.id != self.task_id
]
# Filter by target_task_ids if provided
if target_task_ids:
targets = [tid.strip() for tid in target_task_ids.split(",")]
related_tasks = [task for task in related_tasks if task.id in targets]
# Update shared data for all related tasks
for task in related_tasks:
if not task.shared_data:
task.shared_data = {}
task.shared_data[self.task_id] = data
return ActionResult(extracted_content=f"Data shared with {len(related_tasks)} browsers")
@self.controller.action("Get shared data from problem space")
async def get_shared_data(channel: str) -> ActionResult:
"""Retrieve data shared by other browsers in the problem space.
Args:
channel: Communication channel ID
"""
shared_data = {}
for task in scheduler.tasks.values():
if task.communication_channel == channel and task.shared_data:
shared_data.update(task.shared_data)
return ActionResult(extracted_content=f"Shared data: {json.dumps(shared_data)}")
`@self.controller.action`("Share data with related browsers")
async def share_data(channel: str, data: str, target_task_ids: Optional[str] = None) -> ActionResult:
"""Share data across browsers in the same problem space.
Args:
channel: Communication channel ID
data: Data to share (string)
target_task_ids: Optional comma-separated list of task IDs to share with.
If not provided, shares with all tasks in the channel.
"""
if self.communication_channel is None:
return ActionResult(success=False, error="Task is not in a communication channel")
if channel != self.communication_channel:
return ActionResult(success=False, error="Channel mismatch")
# Get all tasks in the same communication channel
related_tasks = [
task
for task in scheduler.tasks.values()
if task.communication_channel == channel and task.id != self.task_id
]
# Filter by target_task_ids if provided
if target_task_ids:
targets = [tid.strip() for tid in target_task_ids.split(",")]
related_tasks = [task for task in related_tasks if task.id in targets]
# Update shared data for all related tasks
for task in related_tasks:
if not task.shared_data:
task.shared_data = {}
task.shared_data[self.task_id] = data
return ActionResult(extracted_content=f"Data shared with {len(related_tasks)} browsers")
`@self.controller.action`("Get shared data from problem space")
async def get_shared_data(channel: str) -> ActionResult:
"""Retrieve data shared by other browsers in the problem space.
Args:
channel: Communication channel ID
"""
if self.communication_channel is None:
return ActionResult(success=False, error="Task is not in a communication channel")
if channel != self.communication_channel:
return ActionResult(success=False, error="Channel mismatch")
shared_data = {}
for task in scheduler.tasks.values():
if task.communication_channel == channel and task.shared_data:
shared_data.update(task.shared_data)
return ActionResult(extracted_content=f"Shared data: {json.dumps(shared_data)}")
🤖 Prompt for AI Agents
In `@blastai/tools.py` around lines 152 - 195, The share_data and get_shared_data
handlers allow any task to access any channel by accepting an arbitrary channel
string; to enforce channel isolation, look up the caller task via self.task_id
in scheduler.tasks and verify its communication_channel matches the provided
channel, and if not reject the request (e.g., return an error ActionResult or
raise) before proceeding; apply this check at the start of both share_data and
get_shared_data, keeping existing logic (target filtering, updating
task.shared_data, and json.dumps) only after the authorization check.

Comment on lines +72 to +90
async def test_share_data_with_targets():
constraints = Constraints()
scheduler = Scheduler(constraints, MagicMock(), MagicMock())
resource_manager = MagicMock()

tid_1 = scheduler.schedule_task("T1", communication_channel="ch")
tid_2 = scheduler.schedule_task("T2", communication_channel="ch")
tid_3 = scheduler.schedule_task("T3", communication_channel="ch")

tools_1 = Tools(scheduler=scheduler, task_id=tid_1, resource_manager=resource_manager)

# Share only with tid_2
await tools_1.controller.registry.registry.actions["share_data"].function(
channel="ch", data="secret", target_task_ids=tid_2
)

assert scheduler.tasks[tid_2].shared_data[tid_1] == "secret"
assert scheduler.tasks[tid_3].shared_data is None or tid_1 not in scheduler.tasks[tid_3].shared_data

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Stub cache_manager.get_result/get_plan to avoid implicit cache hits.
MagicMock is truthy by default, so schedule_task can auto-complete tasks and mask future regressions.

🧪 Suggested test hardening
 async def test_share_data_with_targets():
     constraints = Constraints()
-    scheduler = Scheduler(constraints, MagicMock(), MagicMock())
+    cache_manager = MagicMock()
+    cache_manager.get_result.return_value = None
+    cache_manager.get_plan.return_value = None
+    scheduler = Scheduler(constraints, cache_manager, MagicMock())
     resource_manager = MagicMock()
@@
 async def test_channel_inheritance():
     constraints = Constraints()
-    scheduler = Scheduler(constraints, MagicMock(), MagicMock())
+    cache_manager = MagicMock()
+    cache_manager.get_result.return_value = None
+    cache_manager.get_plan.return_value = None
+    scheduler = Scheduler(constraints, cache_manager, MagicMock())
     resource_manager = MagicMock()

Also applies to: 92-110

🤖 Prompt for AI Agents
In `@tests/test_browser_communication.py` around lines 72 - 90, The test should
stub the cache manager's get_result and get_plan to return falsy values to
prevent implicit cache hits that let schedule_task auto-complete; locate the
cache manager used in the test setup (the MagicMock passed into Scheduler) and
set its get_result and get_plan to return None (or AsyncMock returning None if
awaited) before calling scheduler.schedule_task in test_share_data_with_targets,
and apply the same stubbing to the other test block referenced (lines 92-110) so
tasks do not auto-complete due to truthy MagicMock defaults.

…ution

- Extended TaskState with communication_channel and shared_data
- Added share_data and get_shared_data tools for cross-browser coordination
- Implemented density-based task prioritization in ResourceManager
- Added automatic communication channel inheritance for subtasks
- Added comprehensive unit tests for all new features
- Ensured GIL-safe concurrent access to shared scheduler state

Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant