Skip to content

Add GraphScope-based agent filtering and refactor billing configs#595

Merged
jfrench9 merged 4 commits intomainfrom
feature/graph-scoped-agents
Apr 5, 2026
Merged

Add GraphScope-based agent filtering and refactor billing configs#595
jfrench9 merged 4 commits intomainfrom
feature/graph-scoped-agents

Conversation

@jfrench9
Copy link
Copy Markdown
Member

@jfrench9 jfrench9 commented Apr 5, 2026

Summary

Introduces a GraphScope mechanism for filtering agents based on graph context, while also refactoring billing plan configurations and document tier limits for improved clarity and maintainability.

Key Changes

GraphScope Agent Filtering (Core Feature)

  • Added GraphScope abstraction and matches_graph_scope function to enable context-aware agent filtering
  • Updated the agent base class with graph scope support (37 new lines in base.py)
  • Extended agent_registry.py to incorporate graph scope awareness when resolving agents
  • Updated the orchestrator to leverage graph scope filtering when selecting agents for execution
  • Applied graph scope annotation to the mapping agent implementation as a first adopter

Billing & Tier Refactoring

  • Simplified billing plan configurations in core.py, reducing complexity (~49 lines changed with net reduction)
  • Removed an unused field from the billing offering API model
  • Refactored document tier limits and updated dependent functions in documents/service.py
  • Updated credit service logic in graph/credit_service.py to align with refactored billing structures
  • Adjusted offering router (routers/offering.py) with updated logic for plan presentation

Search Service Updates

  • Modified search service to align with the refactored billing/tier structure

Breaking Changes

  • Billing model change: Removed a field from offering.py API model — any consumers relying on this field will need to be updated
  • Billing plan configuration restructure: Internal billing configuration format has changed in core.py — downstream services or tools that directly parse these configurations may require updates
  • Document tier limit function signatures: Functions in documents/service.py have been updated, which may affect callers

Testing

  • New test suite: Added comprehensive tests for graph scope functionality (tests/operations/agents/test_graph_scope.py — 260 lines) covering scope matching, agent filtering, and edge cases
  • Updated existing tests: Adjusted billing model tests and document service tests to reflect the refactored structures
  • All existing test modifications are minimal, suggesting backward compatibility was maintained where possible

Infrastructure Considerations

  • No new dependencies or infrastructure requirements
  • Billing configuration changes are self-contained but should be validated in staging environments to ensure plan resolution behaves correctly
  • The graph scope feature is additive and opt-in per agent (only mapping agent is annotated so far), minimizing rollout risk

🤖 Generated with Claude Code

Branch Info:

  • Source: feature/graph-scoped-agents
  • Target: main
  • Type: feature

Co-Authored-By: Claude noreply@anthropic.com

jfrench9 added 3 commits April 5, 2026 00:10
- Introduced GraphScope class to define graph access restrictions for agents.
- Implemented matches_graph_scope function to validate agent eligibility based on graph context.
- Updated agent specifications to include graph_scope attribute.
- Enhanced agent registry to serialize graph_scope for API responses.
- Modified AgentOrchestrator to filter agents based on their graph_scope.
- Added comprehensive tests for graph scope matching and orchestrator filtering.
- Consolidated document section and connection limits into a single max_documents parameter across billing plans.
- Updated the get_tier_max_documents function to reflect the new structure.
- Modified DocumentService and SearchService to utilize the new max_documents limit, removing deprecated tier checks.
- Adjusted tests to align with the refactored limit checks, ensuring proper functionality.
- Removed max_queries_per_hour and infrastructure fields from billing plan definitions to streamline configuration.
- Updated CreditService to retrieve backup limits from GraphTierConfig, ensuring consistent backup retention handling.
- Adjusted offering retrieval logic to source infrastructure details and backup retention from a single configuration point.
- Modified tests to reflect the removal of max_queries_per_hour, ensuring alignment with the new billing model structure.
@jfrench9
Copy link
Copy Markdown
Member Author

jfrench9 commented Apr 5, 2026

@claude please review this PR

@claude
Copy link
Copy Markdown

claude Bot commented Apr 5, 2026

Claude finished @jfrench9's task in 2m 7s —— View job


PR Review: Add GraphScope-based agent filtering and refactor billing configs

Tasks:

  • Gather context and understand request
  • Read changed files
  • Analyze code quality, correctness, and patterns
  • Post full review

Overall Assessment

This is a solid PR. The GraphScope feature is well-designed and correctly implemented with good defense-in-depth. The billing refactoring successfully moves duplicated config toward a single source of truth (GraphTierConfig). I found one bug and a few items worth attention below.


Bug: upload_documents_bulk always returns empty results

File: robosystems/operations/search/service.py:244-248

The refactor dropped the results.append(result) call:

# After this PR — BROKEN: result is never appended
for i, request in enumerate(requests):
    try:
        self.upload_document(graph_id, request)   # return value discarded
    except Exception as e:
        errors.append(...)

return results, errors   # results is always []

The method now always returns ([], errors). The bulk upload router (routers/graphs/documents.py) doesn't call this method directly (it iterates via DocumentService), so no API endpoint is broken today — but SearchService.upload_documents_bulk is dead code that lies to its callers.

Fix this →


Issues

1. Fragile test — AgentMode accessed via dataclass internals

tests/operations/agents/test_graph_scope.py:200:

mode=AgentSpec.__dataclass_fields__["supported_modes"].default_factory()[0],

This is a roundabout way to get AgentMode.QUICK. Just use the enum directly:

from robosystems.operations.agents.base import AgentMode
mode=AgentMode.QUICK,

The current approach is fragile: it will silently break if the default ordering of supported_modes ever changes.

Fix this →

2. xlarge backup downloads limit changed silently

robosystems/config/billing/core.py:

# Before: "backup_downloads_per_month": 999  (effectively unlimited)
# After:  "backup_downloads_per_month": 40

This is a hard 98% reduction for the highest-tier plan. If this is intentional (aligning with a GraphTierConfig source of truth), the PR description should note it explicitly as a breaking change. If it's not intentional, it should be reverted.

3. Lazy imports inside matches_graph_scope

robosystems/operations/agents/base.py:76-80:

if scope.shared_repo is not None:
    from robosystems.config.shared_repositories import (
        is_shared_repository_or_subgraph,
        resolve_shared_repository_parent,
    )

The lazy imports avoid a circular dependency at module load time, which is fine. However this function can be called frequently during _get_all_agents. Consider moving these imports to a top-level TYPE_CHECKING block or restructuring to avoid the circular dependency more cleanly. Low priority — not a correctness issue.


Positive Notes

  • Defense in depth on scope enforcement: Both _get_all_agents (listing) and _route_to_specific_agent (direct invocation) check scope — good.
  • Per-instance caching of schema extensions (_schema_extensions: list[str] | None) avoids repeated lookups within a single orchestrator lifetime.
  • _serialize_scope returning None for empty scopes (when both fields are None) is clean and avoids sending {} to clients for unscoped agents.
  • Single source of truth for infra config: Moving backup_retention_days and infrastructure strings out of billing/core.py and into GraphTierConfig is the right call.
  • Test coverage is comprehensive: 260 lines covering matches_graph_scope, orchestrator filtering, direct-invocation rejection, and list_agents metadata — well done.

Minor

  • clear_registry is imported directly from agent_registry in the tests (not re-exported via __init__.py) — this is fine but worth being consistent with other test imports.
  • The infrastructure display string now shows only RAM (2 GB RAM) without vCPU count, whereas the old hardcoded strings included both (2 vCPU, 8 GB RAM). If the instance config in graph.yml doesn't carry a vCPU field, this is a cosmetic regression in the offerings API response.

Summary: Approve after addressing the upload_documents_bulk bug and confirming the xlarge backup download limit change is intentional.

- Updated SearchService to capture results from document uploads, improving error handling and response tracking.
- Modified offering retrieval to include vCPU count in infrastructure descriptions, providing clearer resource specifications.
@jfrench9 jfrench9 merged commit 9d52dd4 into main Apr 5, 2026
7 checks passed
@jfrench9 jfrench9 deleted the feature/graph-scoped-agents branch April 5, 2026 05:47
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