Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions docs/docs/Components/bundles-bocha.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
title: Bocha
slug: /bundles-bocha
---

import Icon from "@site/src/components/icon";
import PartialParams from '@site/docs/_partial-hidden-params.mdx';

<Icon name="Blocks" aria-hidden="true" /> [**Bundles**](/components-bundle-components) contain custom components that support specific third-party integrations with Langflow.

This page describes the components that are available in the **Bocha** bundle.

For more information, see the [Bocha documentation](https://open.bochaai.com/).

## Bocha Web Search

This component calls the Bocha Web Search API and returns source-linked web results.

It returns search results as a [`Table`](/data-types#table). Each result includes the result title, URL, content summary, site name, and publication or crawl date when Bocha returns those fields.

### Bocha Web Search parameters

<PartialParams />

| Name | Type | Description |
|------|------|-------------|
| api_key | SecretString | Input parameter. The API key for authenticating with Bocha. |
| query | String | Input parameter. The search query to send to Bocha. |
| count | Integer | Input parameter. The maximum number of search results to return. Default: `10`. |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Document the maximum count limit.

The parameter table shows the default count is 10, but according to the review context, the result count is capped at 50. Users should be informed of this maximum limit to set appropriate expectations.

📝 Proposed fix to document the maximum limit
-| count | Integer | Input parameter. The maximum number of search results to return. Default: `10`. |
+| count | Integer | Input parameter. The maximum number of search results to return. Default: `10`. Maximum: `50`. |
📝 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
| count | Integer | Input parameter. The maximum number of search results to return. Default: `10`. |
| count | Integer | Input parameter. The maximum number of search results to return. Default: `10`. Maximum: `50`. |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/docs/Components/bundles-bocha.mdx` at line 29, Update the docs table row
for the count parameter (the "count" table cell) to mention the hard cap of 50
in addition to the default of 10—e.g., change the description to "Input
parameter. The maximum number of search results to return. Default: `10`.
Maximum: `50`." so users know the results are capped at 50.

| freshness | String | Input parameter. The freshness filter to send to Bocha. Default: `noLimit`. |
| summary | Boolean | Input parameter. Whether to ask Bocha to include generated result summaries when available. Default: `true`. |
| dataframe | Table | Output parameter. A table containing `title`, `url`, `snippet`, `summary`, `site_name`, `site_icon`, and `date_published` columns. |

## See also

* [**Web Search** component](/web-search)
* [**SearchApi** bundle](/bundles-searchapi)
* [**Serper** bundle](/bundles-serper)
1 change: 1 addition & 0 deletions docs/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,7 @@ module.exports = {
"Components/bundles-azure",
"Components/bundles-baidu",
"Components/bundles-bing",
"Components/bundles-bocha",
"Components/bundles-cassandra",
"Components/bundles-chroma",
"Components/bundles-cleanlab",
Expand Down
205 changes: 202 additions & 3 deletions src/lfx/src/lfx/_assets/component_index.json
Original file line number Diff line number Diff line change
Expand Up @@ -8715,6 +8715,205 @@
}
}
],
[
"bocha",
{
"BochaWebSearch": {
"base_classes": [
"Table"
],
"beta": false,
"conditional_paths": [],
"custom_fields": {},
"description": "Search the web using Bocha Web Search API.",
"display_name": "Bocha Web Search",
"documentation": "",
"edited": false,
"field_order": [
"api_key",
"query",
"summary",
"freshness",
"count"
],
"frozen": false,
"icon": "Search",
"legacy": false,
"metadata": {
"code_hash": "1f8bcc420abd",
"dependencies": {
"dependencies": [
{
"name": "httpx",
"version": "0.28.1"
},
{
"name": "lfx",
"version": "0.4.3"
}
],
"total_dependencies": 2
},
"module": "lfx.components.bocha.bocha_web_search.BochaSearchComponent"
},
"minimized": false,
"output_types": [],
"outputs": [
{
"allows_loop": false,
"cache": true,
"display_name": "Table",
"group_outputs": false,
"method": "fetch_content_dataframe",
"name": "dataframe",
"selected": "Table",
"tool_mode": true,
"types": [
"Table"
],
"value": "__UNDEFINED__"
}
],
"pinned": false,
"template": {
"_type": "Component",
"api_key": {
"_input_type": "SecretStrInput",
"advanced": false,
"display_name": "Bocha API Key",
"dynamic": false,
"info": "Your Bocha API Key from open.bochaai.com.",
"input_types": [],
"load_from_db": true,
"name": "api_key",
"override_skip": false,
"password": true,
"placeholder": "",
"required": true,
"show": true,
"title_case": false,
"track_in_telemetry": false,
"type": "str",
"value": ""
},
"code": {
"advanced": true,
"dynamic": true,
"fileTypes": [],
"file_path": "",
"info": "",
"list": false,
"load_from_db": false,
"multiline": true,
"name": "code",
"password": false,
"placeholder": "",
"required": true,
"show": true,
"title_case": false,
"type": "code",
"value": "import httpx\n\nfrom lfx.custom.custom_component.component import Component\nfrom lfx.inputs.inputs import BoolInput, DropdownInput, IntInput, MessageTextInput, SecretStrInput\nfrom lfx.log.logger import logger\nfrom lfx.schema.data import Data\nfrom lfx.schema.dataframe import DataFrame\nfrom lfx.template.field.base import Output\n\n\nclass BochaSearchComponent(Component):\n display_name = \"Bocha Web Search\"\n description = \"Search the web using Bocha Web Search API.\"\n icon = \"Search\"\n name = \"BochaWebSearch\"\n\n inputs = [\n SecretStrInput(\n name=\"api_key\",\n display_name=\"Bocha API Key\",\n required=True,\n info=\"Your Bocha API Key from open.bochaai.com.\",\n ),\n MessageTextInput(\n name=\"query\",\n display_name=\"Search Query\",\n tool_mode=True,\n required=True,\n ),\n BoolInput(\n name=\"summary\",\n display_name=\"Include Summary\",\n value=True,\n advanced=True,\n ),\n DropdownInput(\n name=\"freshness\",\n display_name=\"Freshness\",\n options=[\"noLimit\", \"oneYear\", \"oneMonth\", \"oneWeek\", \"oneDay\"],\n value=\"noLimit\",\n advanced=True,\n ),\n IntInput(\n name=\"count\",\n display_name=\"Number of Results\",\n value=10,\n required=True,\n advanced=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Table\", name=\"dataframe\", method=\"fetch_content_dataframe\"),\n ]\n\n def fetch_content(self) -> list[Data]:\n url = \"https://api.bochaai.com/v1/web-search\"\n headers = {\n \"Authorization\": f\"Bearer {self.api_key}\",\n \"Content-Type\": \"application/json\",\n }\n payload = {\n \"query\": self.query,\n \"summary\": self.summary,\n \"freshness\": self.freshness or \"noLimit\",\n \"count\": min(int(self.count), 50),\n }\n\n try:\n with httpx.Client(timeout=90.0) as client:\n response = client.post(url, json=payload, headers=headers)\n response.raise_for_status()\n\n result = response.json()\n web_pages = result.get(\"data\", {}).get(\"webPages\", {}).get(\"value\", [])\n\n data_results = []\n for item in web_pages:\n snippet = item.get(\"snippet\") or \"\"\n summary = item.get(\"summary\") or \"\"\n text = summary or snippet\n\n data_results.append(\n Data(\n text=text,\n data={\n \"title\": item.get(\"name\"),\n \"url\": item.get(\"url\"),\n \"snippet\": snippet,\n \"summary\": summary,\n \"site_name\": item.get(\"siteName\"),\n \"site_icon\": item.get(\"siteIcon\"),\n \"date_published\": item.get(\"datePublished\"),\n },\n )\n )\n\n except httpx.TimeoutException:\n msg = \"Bocha request timed out.\"\n except httpx.HTTPStatusError as exc:\n msg = f\"Bocha HTTP error: {exc.response.status_code} - {exc.response.text}\"\n except httpx.RequestError as exc:\n msg = f\"Bocha request failed: {exc}\"\n else:\n self.status = data_results\n return data_results\n\n logger.error(msg)\n return [Data(text=msg, data={\"error\": msg})]\n\n def fetch_content_dataframe(self) -> DataFrame:\n return DataFrame(self.fetch_content())\n"
},
"count": {
"_input_type": "IntInput",
"advanced": true,
"display_name": "Number of Results",
"dynamic": false,
"info": "",
"list": false,
"list_add_label": "Add More",
"name": "count",
"override_skip": false,
"placeholder": "",
"required": true,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_metadata": true,
"track_in_telemetry": true,
"type": "int",
"value": 10
},
"freshness": {
"_input_type": "DropdownInput",
"advanced": true,
"combobox": false,
"dialog_inputs": {},
"display_name": "Freshness",
"dynamic": false,
"external_options": {},
"info": "",
"name": "freshness",
"options": [
"noLimit",
"oneYear",
"oneMonth",
"oneWeek",
"oneDay"
],
"options_metadata": [],
"override_skip": false,
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"toggle": false,
"tool_mode": false,
"trace_as_metadata": true,
"track_in_telemetry": true,
"type": "str",
"value": "noLimit"
},
"query": {
"_input_type": "MessageTextInput",
"advanced": false,
"display_name": "Search Query",
"dynamic": false,
"info": "",
"input_types": [
"Message"
],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
"name": "query",
"override_skip": false,
"placeholder": "",
"required": true,
"show": true,
"title_case": false,
"tool_mode": true,
"trace_as_input": true,
"trace_as_metadata": true,
"track_in_telemetry": false,
"type": "str",
"value": ""
},
"summary": {
"_input_type": "BoolInput",
"advanced": true,
"display_name": "Include Summary",
"dynamic": false,
"info": "",
"list": false,
"list_add_label": "Add More",
"name": "summary",
"override_skip": false,
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_metadata": true,
"track_in_telemetry": true,
"type": "bool",
"value": true
}
},
"tool_mode": false
}
}
],
[
"cassandra",
{
Expand Down Expand Up @@ -117839,9 +118038,9 @@
]
],
"metadata": {
"num_components": 354,
"num_modules": 97
"num_components": 355,
"num_modules": 98
},
"sha256": "47116c50950cf730a947b450bbf4ba8088154d9a96dd42aa33fc0dfb94915252",
"sha256": "1cc2e993e186a1e2afa43d6b111cc9a2060270d71547aa1211f7bbeec3324bb3",
"version": "0.4.3"
}
3 changes: 3 additions & 0 deletions src/lfx/src/lfx/components/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
azure,
baidu,
bing,
bocha,
cassandra,
chains,
chroma,
Expand Down Expand Up @@ -123,6 +124,7 @@
"azure": "__module__",
"baidu": "__module__",
"bing": "__module__",
"bocha": "__module__",
"cassandra": "__module__",
"chains": "__module__",
"chroma": "__module__",
Expand Down Expand Up @@ -256,6 +258,7 @@ def _discover_components_from_module(module_name):
"azure",
"baidu",
"bing",
"bocha",
"cassandra",
"chains",
"chroma",
Expand Down
3 changes: 3 additions & 0 deletions src/lfx/src/lfx/components/bocha/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .bocha_web_search import BochaSearchComponent

__all__ = ["BochaSearchComponent"]
Loading
Loading