Skip to content

Conversation

@kcze
Copy link
Contributor

@kcze kcze commented Nov 26, 2025

Preserve user searches in the new builder and cache search results for more efficiency.
Search is saved, so the user can see their previous searches.

Changes 🏗️

  • Add BuilderSearch column&migration to save user search (with all filters)
  • Builder db.py now caches all search results using @cached and returns paginated results, so following pages are returned much quicker
  • Score and sort results
  • Update models&routes
  • Update frontend, so it works properly with modified endpoints
  • Frontend: store serachId and use it for subsequent searches, so we don't save partial searches (e.g. "b", "bl", ..., "block"). Search id is reset when user clears the search field.
  • Add clickable chips to the Suggestions builder tab
  • Add HorizontalScroll component (chips use it)

Checklist 📋

For code changes:

  • I have clearly listed my changes in the PR description
  • I have made a test plan
  • I have tested my changes according to the test plan:
    • Search works and is cached
    • Search sorts results
    • Searches are preserved properly

@netlify
Copy link

netlify bot commented Nov 26, 2025

Deploy Preview for auto-gpt-docs-dev canceled.

Name Link
🔨 Latest commit dc5d4ce
🔍 Latest deploy log https://app.netlify.com/projects/auto-gpt-docs-dev/deploys/6939812c9c858300081b5d37

@coderabbitai
Copy link

coderabbitai bot commented Nov 26, 2025

Important

Review skipped

Auto 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.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch kpczerwinski/secrt-1731-builder-search-history

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.

@netlify
Copy link

netlify bot commented Nov 26, 2025

Deploy Preview for auto-gpt-docs canceled.

Name Link
🔨 Latest commit dc5d4ce
🔍 Latest deploy log https://app.netlify.com/projects/auto-gpt-docs/deploys/6939812cce928f0008147a13

@deepsource-io
Copy link

deepsource-io bot commented Nov 26, 2025

Here's the code health analysis summary for commits 979d7c3..dc5d4ce. View details on DeepSource ↗.

Analysis Summary

AnalyzerStatusSummaryLink
DeepSource JavaScript LogoJavaScript✅ Success
❗ 5 occurences introduced
View Check ↗
DeepSource Python LogoPython✅ Success
🎯 3 occurences resolved
View Check ↗

💡 If you’re a repository administrator, you can configure the quality gates from the settings.

@AutoGPT-Agent
Copy link

Thank you for your PR! Before we can proceed with merging, there are a few issues that need to be addressed:

  1. Your PR description is missing information about the changes you've made. Please fill in the 'Changes' section to describe what your builder search history implementation does.

  2. None of the items in the checklist have been checked off. Please complete the checklist by checking the boxes for items you've completed. At minimum:

    • Confirm you've clearly listed your changes
    • Indicate you've made a test plan
    • Note that you've tested your changes according to that plan (and include the test plan)
  3. The diff appears to be empty in this review - if you've made code changes, please ensure they're properly committed and showing in the PR.

Once you've updated these items, we can proceed with a more thorough review of your implementation. The PR title looks good with the proper conventional commit format.

@github-actions github-actions bot added the platform/frontend AutoGPT Platform - Front end label Nov 26, 2025
@AutoGPT-Agent
Copy link

Thank you for your contribution! There are a few items that need to be addressed before this PR can be merged:

  1. The PR title mentions "feat(backend): Builder search history" but the changes are to a frontend wallet component. Please update your PR title to accurately reflect your changes (perhaps something like "fix(frontend): Wallet component condition check").

  2. The PR description is empty. Please explain:

    • What issue this PR is solving
    • What specific changes you've made
  3. The checklist needs to be completed - either check off the items or remove the checklist if the changes are not material (this appears to be a small bugfix).

Once these issues are addressed, we can proceed with the review. The code change itself looks straightforward, but we need proper documentation to understand its purpose.

@kcze kcze force-pushed the kpczerwinski/secrt-1731-builder-search-history branch from 987baa9 to b3c3f9c Compare November 27, 2025 02:27
@AutoGPT-Agent
Copy link

Thank you for your PR contribution. Before this can be merged, please update the following:

  1. Ensure your PR title and labels are consistent. Your title mentions backend changes, but the PR is labeled as frontend.

  2. Complete the PR description to explain the purpose of these changes and what they accomplish.

  3. Fill out the checklist completely.

  4. Ensure your PR includes the actual code changes (the diff is currently empty).

Once you've addressed these points, please request another review.

@github-actions github-actions bot added platform/backend AutoGPT Platform - Back end size/l and removed platform/frontend AutoGPT Platform - Front end labels Dec 1, 2025
@AutoGPT-Agent
Copy link

Thank you for implementing the builder search history functionality! The code implementation looks good, but there are a few things that need to be addressed before this can be merged:

  1. PR Description: Please complete the PR description by:

    • Explaining why these changes are needed (the purpose of the builder search history feature)
    • Listing the specific changes you've made (e.g., adding BuilderSearch model, implementing search history tracking and retrieval)
  2. Checklist: The checklist in your PR description needs to be completed:

    • Check the box confirming you've listed your changes
    • Check the box confirming you've made a test plan
    • Fill out and check off a test plan with specific steps you've taken to test the functionality

The implementation itself looks solid - you've properly:

  • Created a new Prisma model for BuilderSearch
  • Added the migration script
  • Implemented functions to update and retrieve search history
  • Updated the suggestions endpoint to use real search history
  • Properly used user_id in security-sensitive functions

Please update the PR description and checklist, and this should be ready for review again.

@github-actions github-actions bot added platform/frontend AutoGPT Platform - Front end size/xl labels Dec 10, 2025
@AutoGPT-Agent
Copy link

Thank you for your PR implementing builder search history. The code looks well-structured and focused on the stated purpose, but there are a few issues to address before this can be approved:

Missing Items

  1. Your PR description is missing an explanation of the changes and purpose of this PR. Please add a clear description of what this feature does and why it's needed.

  2. The checklist in the PR description is incomplete. Please fill out the checklist including your test plan. Since this adds new functionality, a thorough test plan is essential.

Code Review

The code itself looks good overall:

  • You've added a new BuilderSearch model to Prisma with appropriate migration
  • The search history implementation with caching strategy seems well thought out
  • Pagination handling is improved in both backend and frontend
  • You've added user_id checks appropriately to secure routes

Please update your PR description with:

  1. A clear explanation of the feature and its benefits
  2. A complete checklist including your test plan

Once these are addressed, the PR should be ready for approval.

@AutoGPT-Agent
Copy link

Thank you for your PR implementing the builder search history feature. Before this can be merged, please update the PR description with the following:

  1. Add a clear explanation of why these changes are needed
  2. List the specific changes you've made in the PR
  3. Complete the checklist by checking off the relevant items
  4. Add a test plan explaining how you've verified the functionality

The code implementation looks good and matches the scope stated in the title. I can see you've:

  • Added a new BuilderSearch model in Prisma with appropriate relationships
  • Created migration for the new database table
  • Implemented functions to track and retrieve search history
  • Updated the search endpoint to work with persistent search history
  • Modified frontend components to utilize the search history features

Once you update the PR description with the missing information, we can proceed with the review process.

@kcze kcze marked this pull request as ready for review December 10, 2025 03:11
@kcze kcze requested a review from a team as a code owner December 10, 2025 03:11
@kcze kcze requested review from Abhi1992002, Bentlybro and majdyz and removed request for a team and Bentlybro December 10, 2025 03:11
@qodo-code-review
Copy link

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 4 🔵🔵🔵🔵⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Caching Key/Invalidation

The cached search results function _build_cached_search_results uses user_id, search_query, filters, and by_creator as keys, but pagination is applied outside the cache in the route. Verify that cache invalidation occurs correctly when underlying data (new agents, updated agent names/descriptions, blocks changes) changes, and that large result sets don't cause memory pressure since full lists are cached for 5 minutes per unique key.

@cached(ttl_seconds=300, shared_cache=True)
async def _build_cached_search_results(
    user_id: str,
    search_query: str,
    filters: tuple[FilterType, ...],
    by_creator: tuple[str, ...],
) -> _SearchCacheEntry:
    normalized_query = (search_query or "").strip().lower()

    include_blocks = "blocks" in filters
    include_integrations = "integrations" in filters
    include_library_agents = "my_agents" in filters
    include_marketplace_agents = "marketplace_agents" in filters

    scored_items: list[_ScoredItem] = []
    total_items: dict[FilterType, int] = {
        "blocks": 0,
        "integrations": 0,
        "marketplace_agents": 0,
        "my_agents": 0,
    }

    block_results, block_total, integration_total = _collect_block_results(
        normalized_query=normalized_query,
        include_blocks=include_blocks,
        include_integrations=include_integrations,
    )
    scored_items.extend(block_results)
    total_items["blocks"] = block_total
    total_items["integrations"] = integration_total

    if include_library_agents:
        library_response = await library_db.list_library_agents(
            user_id=user_id,
            search_term=search_query or None,
            page=1,
            page_size=MAX_LIBRARY_AGENT_RESULTS,
        )
        total_items["my_agents"] = library_response.pagination.total_items
        scored_items.extend(
            _build_library_items(
                agents=library_response.agents,
                normalized_query=normalized_query,
            )
        )

    if include_marketplace_agents:
        marketplace_response = await store_db.get_store_agents(
            creators=list(by_creator) or None,
            search_query=search_query or None,
            page=1,
            page_size=MAX_MARKETPLACE_AGENT_RESULTS,
        )
        total_items["marketplace_agents"] = marketplace_response.pagination.total_items
        scored_items.extend(
            _build_marketplace_items(
                agents=marketplace_response.agents,
                normalized_query=normalized_query,
            )
        )

    sorted_items = sorted(
        scored_items,
        key=lambda entry: (-entry.score, entry.sort_key, entry.filter_type),
    )

    return _SearchCacheEntry(
        items=[entry.item for entry in sorted_items],
        total_items=total_items,
    )
Scoring Threshold

_should_include_item drops items when score < MIN_SCORE_FOR_FILTERED_RESULTS (10.0). With short queries (e.g., 1-2 chars) this may filter out too aggressively or conversely include too much when empty query returns 0 score but is allowed. Validate UX: empty query returns everything unsorted (score 0), but then sorted comparator uses -score first—ensure desired ordering for empty search and that short queries still surface expected items.

def _should_include_item(score: float, normalized_query: str) -> bool:
    if not normalized_query:
        return True
    return score >= MIN_SCORE_FOR_FILTERED_RESULTS


def _get_item_name(item: SearchResultItem) -> str:
    if isinstance(item, BlockInfo):
        return item.name.lower()
Backward Compatibility

The SearchResponse shape changed (added search_id, pagination; removed page and more_pages). Confirm all frontend consumers are updated. Also, the filter query now uses typed values; ensure OpenAPI clients and existing callers pass correct enums.

    "/search",
    summary="Builder search",
    tags=["store", "private"],
    response_model=builder_model.SearchResponse,
)
async def search(
    user_id: Annotated[str, fastapi.Security(get_user_id)],
    search_query: Annotated[str | None, fastapi.Query()] = None,
    filter: Annotated[list[builder_model.FilterType] | None, fastapi.Query()] = None,
    search_id: Annotated[str | None, fastapi.Query()] = None,
    by_creator: Annotated[list[str] | None, fastapi.Query()] = None,
    page: Annotated[int, fastapi.Query()] = 1,
    page_size: Annotated[int, fastapi.Query()] = 50,
) -> builder_model.SearchResponse:
    """
    Search for blocks (including integrations), marketplace agents, and user library agents.
    """
    # If no filters are provided, then we will return all types
    if not filter:
        filter = [
            "blocks",
            "integrations",
            "marketplace_agents",
            "my_agents",
        ]
    search_query = sanitize_query(search_query)

    # Get all possible results
    cached_results = await builder_db.get_sorted_search_results(
        user_id=user_id,
        search_query=search_query,
        filters=filter,
        by_creator=by_creator,
    )

    # Paginate results
    total_combined_items = len(cached_results.items)
    pagination = Pagination(
        total_items=total_combined_items,
        total_pages=(total_combined_items + page_size - 1) // page_size,
        current_page=page,
        page_size=page_size,
    )

    start_idx = (page - 1) * page_size
    end_idx = start_idx + page_size
    paginated_items = cached_results.items[start_idx:end_idx]

    # Update the search entry by id
    search_id = await builder_db.update_search(
        user_id,
        builder_model.SearchEntry(
            search_query=search_query,
            filter=filter,
            by_creator=by_creator,
            search_id=search_id,
        ),
    )

    return builder_model.SearchResponse(
        items=paginated_items,
        search_id=search_id,
        total_items=cached_results.total_items,
        pagination=pagination,
    )

Copy link
Contributor Author

@kcze kcze left a comment

Choose a reason for hiding this comment

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

comments

SearchResultItem = BlockInfo | library_model.LibraryAgent | store_model.StoreAgent


@dataclass
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I used private @dataclass because are more lightweight than pydantic model as this goes to cache

Copy link
Member

Choose a reason for hiding this comment

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

Sure, but any idea how much more lightweight and how this affects performance?

return False


def _score_block(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Scoring uses magic numbers for priorities - this need to be refined over time, so search works as best as possible.

@kcze kcze changed the title feat(backend): Builder search history feat(platform): Builder search history Dec 10, 2025
@kcze kcze requested a review from 0ubbe December 10, 2025 11:23
@kcze kcze requested review from Pwuts and ntindle December 10, 2025 14:12
Copy link
Member

@ntindle ntindle left a comment

Choose a reason for hiding this comment

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

Backend looks fine, have another eval front end

@github-project-automation github-project-automation bot moved this from 🆕 Needs initial review to 👍🏼 Mergeable in AutoGPT development kanban Dec 10, 2025
@@ -0,0 +1,15 @@
-- CreateTable
CREATE TABLE "BuilderSearch" (
Copy link
Member

Choose a reason for hiding this comment

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

can be more specific:
BuilderSearchHistory

CREATE TABLE "BuilderSearch" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
Copy link
Member

Choose a reason for hiding this comment

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

are these records ever updated?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: 👍🏼 Mergeable
Status: No status

Development

Successfully merging this pull request may close these issues.

6 participants