Skip to content

feat: add agent tool integrations, KB query tracking, and reranking support#211

Merged
amirasaran merged 4 commits intodevelopmentfrom
feature/agentic
Feb 24, 2026
Merged

feat: add agent tool integrations, KB query tracking, and reranking support#211
amirasaran merged 4 commits intodevelopmentfrom
feature/agentic

Conversation

@amirasaran
Copy link
Contributor

@amirasaran amirasaran commented Feb 24, 2026

User description

Description

Backend:

  • Add enable_as_tool, tool_function_name, and tool_description fields to Agent model to support nested agent tool calling.
  • Create KnowledgeBaseQuery model and APIs to track search queries, their status, and retrieval costs.
  • Update RetrievalSetting model to include reranker_model_config and retrieval_cost.
  • Update billing/plan services and signals to account for knowledge base query usage.
  • Generate new migrations for agent and knowledge base models.
  • Update poetry.lock dependencies.

Frontend:

  • Add AgentFormToolConfigSection and useAgentToolConfig hook to allow users to configure agents as tools.
  • Add new AgentIntegrationsPage for managing agent tool integrations.
  • Add QueryLogsPage to display knowledge base query history and statuses.
  • Update KnowledgeBaseNewPage and RetrievalSettingsManager to support reranker configurations.
  • Add pricing information components (KnowledgeBasePricingInfo, RetrievalSettingPricingInfo) for better cost transparency.
  • Add fill-translations.cjs utility script for automated translation management and update all 10 locale JSON files.
  • Update TypeScript types (agent.ts, knowledge.ts, usage_history.ts) to reflect backend schema changes.
  • Update App routing and DashboardLayout sidebar navigation for the new pages.

PR Type

Enhancement


Description

  • Add agent tool configuration support with enable_as_tool, tool_function_name, and tool_description fields to enable nested agent tool calling

  • Implement knowledge base query tracking with KnowledgeBaseQuery model to monitor search queries, their status, and retrieval costs

  • Add reranker model configuration support to RetrievalSetting with automatic cost calculation

  • Integrate credit validation and usage tracking for knowledge base queries through billing/plan services and signals

  • Create new pages for agent integrations management (AgentIntegrationsPage) and knowledge base query logs (QueryLogsPage)

  • Add agent API documentation component with code examples for cURL, Python, and Node.js

  • Implement pricing information components (KnowledgeBasePricingInfo, RetrievalSettingPricingInfo) for cost transparency

  • Add translation fill utility script and update all 10 locale JSON files (en, fr, de, it, es, pt, ar, fa, ja, zh) with new feature translations

  • Update TypeScript types and API endpoints to reflect backend schema changes

  • Enhance UI components with improved retrieval settings form, agent tool configuration UI, and disabled state support

  • Update app routing and dashboard navigation for new pages and features


Diagram Walkthrough

flowchart LR
  Agent["Agent Model<br/>enable_as_tool<br/>tool_function_name<br/>tool_description"]
  KB["RetrievalSetting<br/>reranker_model_config<br/>retrieval_cost"]
  Query["KnowledgeBaseQuery<br/>status tracking<br/>cost calculation"]
  
  Agent -->|"tool config"| AgentForm["AgentFormPage<br/>AgentFormToolConfigSection"]
  Agent -->|"integrations"| IntegPage["AgentIntegrationsPage<br/>AgentApiDocumentation"]
  
  KB -->|"retrieval ops"| KBForm["KnowledgeBaseNewPage<br/>RetrievalSettingsManager"]
  KB -->|"pricing"| KBPrice["KnowledgeBasePricingInfo<br/>RetrievalSettingPricingInfo"]
  
  Query -->|"query history"| QueryLogs["QueryLogsPage<br/>listQueries API"]
  Query -->|"credit tracking"| Billing["TeamPlanService<br/>Usage Signals"]
  
  AgentForm -->|"save"| Agent
  IntegPage -->|"display"| Agent
  KBForm -->|"configure"| KB
  QueryLogs -->|"track"| Query
  Billing -->|"validate"| Query
Loading

File Walkthrough

Relevant files
Enhancement
30 files
useAgentToolConfig.ts
New hook for agent tool configuration management                 

frontend/src/hooks/useAgentToolConfig.ts

  • New custom hook for managing agent tool configuration state and API
    interactions
  • Handles enableAsTool, toolFunctionName, and toolDescription state
    management
  • Provides saveToolConfig function to persist changes via
    agentApi.update()
  • Includes error handling with toast notifications for validation and
    API errors
+70/-0   
knowledgeBase.ts
Knowledge base query API endpoints                                             

frontend/src/services/api/knowledgeBase.ts

  • Added listQueries() method to fetch paginated knowledge base query
    history with filtering
  • Added getQuery() method to retrieve individual query details
  • Supports filtering by status, page, pageSize, and knowledgeBaseUuid
+26/-0   
knowledge.ts
TypeScript types for retrieval settings and query tracking

frontend/src/types/knowledge.ts

  • Added reranker_model_config field to RetrievalSetting interface
  • Added retrieval_cost field to track costs per retrieval
  • New QueryStatus enum with states: new, processing, finished, failed
  • New KnowledgeBaseQuery interface for tracking query history with cost
    and status
+23/-1   
agent.ts
Agent tool configuration TypeScript types                               

frontend/src/types/agent.ts

  • Added enable_as_tool, tool_function_name, and tool_description fields
    to Agent interface
  • Extended AgentUpdateRequest with the same three tool configuration
    fields
+6/-0     
usage_history.ts
Usage history content type for knowledge base queries       

frontend/src/types/usage_history.ts

  • Added KnowledgeBaseQuery to ContentType enum for usage tracking
+1/-0     
index.ts
Export agent tool config hook                                                       

frontend/src/hooks/index.ts

  • Exported new useAgentToolConfig hook
+1/-0     
models.py
Knowledge base query tracking and retrieval cost models   

backend/knowledge_base/models.py

  • Added query status constants (QUERY_STATUS_NEW,
    QUERY_STATUS_PROCESSING, QUERY_STATUS_FINISHED, QUERY_STATUS_FAILED)
  • Added reranker_model_config JSONField to RetrievalSetting model
  • Added retrieval_cost PositiveIntegerField to RetrievalSetting model
  • Implemented _calculate_retrieval_cost() method to compute costs based
    on provider configuration
  • Overrode save() method to auto-calculate retrieval cost before saving
  • New KnowledgeBaseQuery model to track query history with status,
    results count, and cost
+110/-3 
views.py
Query tracking and credit validation in knowledge base retrieval

backend/knowledge_base/views.py

  • Enhanced query() endpoint to create KnowledgeBaseQuery records for
    tracking
  • Added credit validation before retrieval using TeamPlanService
  • Implemented query status lifecycle (NEW → PROCESSING →
    FINISHED/FAILED)
  • New KnowledgeBaseQueryViewSet for listing and retrieving query history
+85/-7   
serializers.py
Agent tool configuration validation in serializers             

backend/agent/serializers.py

  • Added tool configuration fields to AgentListSerializer
  • Implemented validation for enable_as_tool requiring tool_function_name
    and tool_description
  • Added check to prevent disabling tool feature if agent is used in
    other agents
  • Enhanced validate_tool_agent_uuid() to verify agent is enabled as tool
    and published
+71/-8   
models.py
Agent tool configuration model fields                                       

backend/agent/models.py

  • Added enable_as_tool, tool_function_name, and tool_description fields
    to Agent model
  • Updated AgentAsTool cached properties to use configured tool name and
    description
  • Modified name, key, and description properties to prioritize tool
    configuration
+31/-14 
services.py
Credit calculation for knowledge base queries                       

backend/plan/services.py

  • Added KnowledgeBaseQuery handling to get_calculat_needed_credits()
    method
  • Added KnowledgeBaseQuery handling to get_actual_credits() method
+5/-1     
serializers.py
Serializers for retrieval settings and query history         

backend/knowledge_base/serializers.py

  • Added reranker_model_config and retrieval_cost fields to
    RetrievalSettingSerializer
  • Made retrieval_cost read-only
  • New KnowledgeBaseQuerySerializer for query history with read-only
    status and cost fields
+32/-1   
signals.py
Signal handler for knowledge base query credit tracking   

backend/plan/signals.py

  • New signal handler for KnowledgeBaseQuery post_save to track credit
    usage
  • Creates usage history on NEW status, updates on FINISHED, reverts on
    FAILED
+24/-1   
filters.py
Filter class for knowledge base query history                       

backend/knowledge_base/filters.py

  • New KnowledgeBaseQueryFilter for filtering queries by status and
    knowledge base UUID
+21/-1   
RetrievalSettingForm.tsx
Improved retrieval settings form UI and embedding requirements

frontend/src/components/knowledge/RetrievalSettingForm.tsx

  • Reorganized retrieval type options to show full text search first,
    then hybrid and vector search
  • Added disabled state and warning badges for vector and hybrid search
    when embeddings are not configured
  • Enhanced embedding requirement warning message with explanation text
  • Improved UI clarity by adding comments to separate retrieval type
    sections
+30/-14 
DashboardLayout.tsx
Added query logs navigation to dashboard layout                   

frontend/src/layouts/DashboardLayout.tsx

  • Added new navigation menu item for query logs page
    (/dashboard/logs/queries)
  • Uses MagnifyingGlassIcon for the queries navigation item
  • Positioned after sitemaps logs in the navigation structure
+5/-0     
QueryLogsPage.tsx
Add knowledge base query logs page with filtering and pagination

frontend/src/pages/dashboard/QueryLogsPage.tsx

  • New page component for displaying knowledge base query history with
    filtering by status
  • Implements pagination, responsive mobile/desktop layouts, and query
    detail display
  • Shows query text, status badges, results count, retrieval costs, and
    error messages
  • Integrates with knowledgeBaseApi.listQueries() and breadcrumb
    navigation
+303/-0 
AgentFormHeader.tsx
Add agent tool configuration UI to form header                     

frontend/src/components/agent/form/AgentFormHeader.tsx

  • Add tool configuration UI with toggle switch for enableAsTool feature
    (only visible when agent is published)
  • Implement modal dialog for configuring toolFunctionName and
    toolDescription with validation
  • Add state management for pending enable/disable and modal interactions
  • Support RTL direction for toggle switch animation
+178/-2 
KnowledgeBaseNewPage.tsx
Simplify KB creation form and adjust defaults                       

frontend/src/pages/dashboard/knowledge-base/KnowledgeBaseNewPage.tsx

  • Change default retrieval_type from HybridSearch to FullTextSearch
  • Reorder embedding search method options (text-only first, then
    semantic)
  • Comment out entire summarization configuration section with
    explanation of default values
  • Remove unused imports and watch variables related to summarization
  • Add retrieval pricing info props to KnowledgeBasePricingInfo component
+31/-26 
AgentFormPage.tsx
Integrate agent tool configuration management in form       

frontend/src/pages/dashboard/AgentFormPage.tsx

  • Add useAgentToolConfig hook for managing agent tool configuration
    state
  • Fetch published agent data on page load to populate tool config fields
  • Implement auto-save for enable_as_tool toggle flag changes
  • Add tool config validation before publishing and pass tool config
    props to header
  • Update tempAgent object to include tool configuration fields
+60/-5   
AgentIntegrationsPage.tsx
Add agent integrations page with API documentation             

frontend/src/pages/dashboard/AgentIntegrationsPage.tsx

  • New page for managing agent integrations with tabbed interface (API,
    webhooks)
  • Display agent API documentation using AgentApiDocumentation component
  • Implement breadcrumb navigation and agent status validation (published
    only)
  • Show "coming soon" state for webhooks tab with placeholder UI
+198/-0 
AgentFormToolConfigSection.tsx
Add agent tool configuration form section component           

frontend/src/components/agent/form/AgentFormToolConfigSection.tsx

  • New component for configuring agent as tool with toggle and form
    fields
  • Display toolFunctionName and toolDescription inputs only when enabled
  • Implement warning modal when disabling tool if agent is in use (tracks
    agentUsageCount)
  • Support RTL direction for toggle switch
+164/-0 
KnowledgeBasePricingInfo.tsx
Add retrieval operation pricing display to KB pricing info

frontend/src/components/knowledge/KnowledgeBasePricingInfo.tsx

  • Add retrieval cost calculation based on retrievalType,
    rerankerEnabled, and provider types
  • Display cost breakdown for vector search and reranker when using
    WaterCrawl providers
  • Show "free" status when no WaterCrawl charges apply to retrieval
    operations
  • Accept new props: retrievalType, rerankerEnabled, rerankerProviderType
+76/-0   
AgentApiDocumentation.tsx
Add agent API documentation component with code examples 

frontend/src/components/agent/AgentApiDocumentation.tsx

  • New component generating API documentation tabs for cURL, Python, and
    Node.js
  • Generate code examples with agent UUID and optional JSON schema output
    parameter
  • Support both blocking and streaming modes for agent chat endpoints
  • Include installation commands and documentation links for each
    language
+150/-0 
RetrievalSettingPricingInfo.tsx
Add retrieval setting pricing information component           

frontend/src/components/knowledge/RetrievalSettingPricingInfo.tsx

  • New component displaying retrieval operation costs for specific
    retrieval settings
  • Calculate costs based on retrievalType, rerankerEnabled, and provider
    types
  • Show cost breakdown and "free" status with limited-time promotional
    message
  • Only render in enterprise mode
+119/-0 
AgentDetailPage.tsx
Update agent detail page integrations navigation                 

frontend/src/pages/dashboard/AgentDetailPage.tsx

  • Replace inline integrations modal state with navigation to dedicated
    integrations page
  • Add disabled state to integrations button when agent is not published
  • Navigate to /dashboard/agents/{agentId}/integrations route
+3/-31   
UsageHistoryPage.tsx
Add knowledge base query tracking to usage history             

frontend/src/pages/dashboard/UsageHistoryPage.tsx

  • Add KnowledgeBaseQuery content type to usage history filters
  • Add icon and label mapping for knowledge base query content type
  • Display query history in usage tracking alongside other content types
+5/-0     
OptionCard.tsx
Add disabled state support to option card component           

frontend/src/components/shared/OptionCard.tsx

  • Add optional disabled prop to prevent card selection
  • Apply opacity-60 and cursor-not-allowed styles when disabled
  • Prevent click handler execution when disabled
+8/-2     
AgentFormAgentToolsSection.tsx
Filter and display agent tool descriptions in agent tools section

frontend/src/components/agent/form/AgentFormAgentToolsSection.tsx

  • Filter agent list to only show agents with enable_as_tool === true
  • Use tool_description from agent if available, fallback to status label
  • Update section title from agentTools to agentsAsTools
+6/-3     
RetrievalSettingsManager.tsx
Display retrieval costs in retrieval settings cards           

frontend/src/components/knowledge/RetrievalSettingsManager.tsx

  • Add retrieval cost display to retrieval setting cards showing
    retrieval_cost value
  • Show cost in credits or display "free" status based on cost value
  • Display cost information alongside other retrieval settings like top_k
+15/-0   
Configuration changes
6 files
0005_knowledgebasequery.py
Database migration for knowledge base query model               

backend/knowledge_base/migrations/0005_knowledgebasequery.py

  • Django migration creating KnowledgeBaseQuery model with all fields and
    relationships
+35/-0   
0003_alter_apispecparameters_tool_parameter_type_and_more.py
Database migration for agent model field updates                 

backend/agent/migrations/0003_alter_apispecparameters_tool_parameter_type_and_more.py

  • Django migration altering field choices for APISpecParameters,
    MCPServer, and MCPServerParameters
+28/-0   
0004_retrievalsetting_reranker_model_config_and_more.py
Database migration for retrieval setting enhancements       

backend/knowledge_base/migrations/0004_retrievalsetting_reranker_model_config_and_more.py

  • Django migration adding reranker_model_config and retrieval_cost
    fields to RetrievalSetting
+28/-0   
0004_agent_enable_as_tool_agent_tool_description_and_more.py
Database migration for agent tool configuration                   

backend/agent/migrations/0004_agent_enable_as_tool_agent_tool_description_and_more.py

  • Django migration adding enable_as_tool, tool_description, and
    tool_function_name fields to Agent model
+28/-0   
urls.py
URL routing for knowledge base query endpoints                     

backend/knowledge_base/urls.py

  • Registered KnowledgeBaseQueryViewSet router for query history
    endpoints
+5/-0     
App.tsx
Add routes for query logs and agent integrations pages     

frontend/src/App.tsx

  • Add lazy-loaded QueryLogsPage route at /dashboard/logs/queries
  • Add lazy-loaded AgentIntegrationsPage route at
    /dashboard/agents/:agentId/integrations
  • Import both new page components
+4/-0     
Documentation
10 files
it.json
Italian locale translations for new features                         

frontend/public/locales/it.json

  • Updated Italian translations for agent tool configuration features
  • Added translations for query logs, retrieval costs, and pricing
    information
  • Fixed grammar and terminology in existing translations
+122/-22
fr.json
French locale translations for new features                           

frontend/public/locales/fr.json

  • Updated French translations for agent tool configuration and query
    tracking
  • Added translations for integrations, pricing, and retrieval settings
  • Improved consistency in terminology across the interface
+112/-12
de.json
German locale translations for new features                           

frontend/public/locales/de.json

  • Updated German translations for agent tools, query logs, and retrieval
    costs
  • Added translations for tool configuration, integrations, and pricing
    information
  • Fixed terminology and grammar in existing translations
+111/-11
en.json
English locale translations for new features                         

frontend/public/locales/en.json

  • Added English translations for agent tool configuration features
  • Added translations for query logs, retrieval costs, and pricing
    information
  • Added new common UI labels and error messages
+103/-3 
fa.json
Comprehensive Persian locale updates for agent tools and query logs

frontend/public/locales/fa.json

  • Added new translation keys for agent tool configuration UI elements
    (enableAsTool, enableAsToolDescription, toolFunctionName,
    toolFunctionNameHint, etc.)
  • Added warning messages for disabling agents as tools with
    pluralization support
  • Added new section for agent integrations with API documentation and
    webhook translations
  • Added query logs related translations (queryHistory, queryLogs,
    queryLogsDesc, queryText, resultsCount, retrievalCost)
  • Added missing common UI translations (cards, configure, confirm,
    error, false, open, saving, search, stop, true)
  • Added retrieval settings pricing information translations
+106/-6 
ja.json
Complete Japanese locale additions for agent tools and queries

frontend/public/locales/ja.json

  • Added Japanese translations for agent tool configuration features
    (enableAsTool, enableAsToolDescription, toolFunctionName, etc.)
  • Added warning messages for disabling agents as tools with proper
    pluralization
  • Added new integrations section with API documentation and webhook
    translations
  • Added query logs and query history related translations
  • Added missing common UI element translations (cards, configure,
    confirm, error, false, open, saving, search, stop, true)
  • Added retrieval settings pricing information and embedding requirement
    explanations
+102/-2 
es.json
Spanish locale updates for agent tools and knowledge base queries

frontend/public/locales/es.json

  • Added Spanish translations for agent tool configuration UI
    (enableAsTool, enableAsToolDescription, toolFunctionName,
    toolFunctionNameHint, etc.)
  • Added disable tool warning messages with pluralization support
  • Added new integrations section translations
  • Added query logs and query history related translations
  • Added missing common UI translations and fixed capitalization
    inconsistencies
  • Added retrieval settings pricing information and embedding requirement
    explanations
+107/-7 
ar.json
Arabic locale additions for agent tools and query features

frontend/public/locales/ar.json

  • Added Arabic translations for agent tool configuration features
  • Added warning messages for disabling agents as tools with proper
    Arabic pluralization
  • Added new integrations section with API and webhook translations
  • Added query logs and query history related translations
  • Added missing common UI element translations
  • Added retrieval settings pricing information and embedding requirement
    explanations
+103/-3 
pt.json
Portuguese locale updates for agent tools and queries       

frontend/public/locales/pt.json

  • Added Portuguese translations for agent tool configuration UI elements
  • Added disable tool warning messages with proper pluralization
  • Added new integrations section translations
  • Added query logs and query history related translations
  • Added missing common UI translations
  • Added retrieval settings pricing information and embedding requirement
    explanations
+106/-6 
zh.json
Chinese locale additions for agent tools and query logs   

frontend/public/locales/zh.json

  • Added Chinese translations for agent tool configuration features
    (enableAsTool, enableAsToolDescription, toolFunctionName, etc.)
  • Added disable tool warning messages with pluralization support
  • Added new integrations section with API and webhook translations
  • Added query logs and query history related translations
  • Added missing common UI element translations
  • Added retrieval settings pricing information and embedding requirement
    explanations
+106/-6 
Miscellaneous
1 files
fill-translations.cjs
Add translation fill utility script for locale management

frontend/scripts/fill-translations.cjs

  • New Node.js utility script for filling empty translation values from
    English locale
  • Reads en.json and identifies empty/null values in target language
    files
  • Outputs empty keys with English values as JSON for processing
  • Supports nested translation keys using dot notation
+90/-0   

…upport

Backend:
- Add `enable_as_tool`, `tool_function_name`, and `tool_description` fields to `Agent` model to support nested agent tool calling.
- Create `KnowledgeBaseQuery` model and APIs to track search queries, their status, and retrieval costs.
- Update `RetrievalSetting` model to include `reranker_model_config` and `retrieval_cost`.
- Update billing/plan services and signals to account for knowledge base query usage.
- Generate new migrations for agent and knowledge base models.
- Update `poetry.lock` dependencies.

Frontend:
- Add `AgentFormToolConfigSection` and `useAgentToolConfig` hook to allow users to configure agents as tools.
- Add new `AgentIntegrationsPage` for managing agent tool integrations.
- Add `QueryLogsPage` to display knowledge base query history and statuses.
- Update `KnowledgeBaseNewPage` and `RetrievalSettingsManager` to support reranker configurations.
- Add pricing information components (`KnowledgeBasePricingInfo`, `RetrievalSettingPricingInfo`) for better cost transparency.
- Add `fill-translations.cjs` utility script for automated translation management and update all 10 locale JSON files.
- Update TypeScript types (`agent.ts`, `knowledge.ts`, `usage_history.ts`) to reflect backend schema changes.
- Update App routing and DashboardLayout sidebar navigation for the new pages.
@dosubot dosubot bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label Feb 24, 2026
@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Feb 24, 2026

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🔴
Debug logging leak

Description: The overridden RetrievalSetting.save() prints self.retrieval_cost to stdout
(print(self.retrieval_cost)), which can leak internal billing/pricing signals into logs
and is unsafe in production environments where logs may be accessible to unintended
parties.
models.py [361-366]

Referred Code
def save(self, *args, **kwargs):
    """Override save to calculate retrieval cost."""
    # Calculate retrieval cost before saving
    self.retrieval_cost = self._calculate_retrieval_cost()
    print(self.retrieval_cost)
    super().save(*args, **kwargs)
Sensitive error exposure

Description: The API stores str(e) from arbitrary exceptions into KnowledgeBaseQuery.error_message and
exposes it via KnowledgeBaseQuerySerializer, which can reveal sensitive internal details
(stack traces, provider errors, query payload fragments, or infrastructure identifiers) to
end users through the query-history endpoints.
views.py [262-267]

Referred Code
except Exception as e:
    # Mark query as failed and save error
    query_record.status = QUERY_STATUS_FAILED
    query_record.error_message = str(e)
    query_record.save(update_fields=["status", "error_message"])
    raise
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: Comprehensive Audit Trails

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

Status:
Missing user context: The new KnowledgeBaseQuery audit record does not store which user initiated the query,
preventing reconstruction of actions by actor.

Referred Code
class KnowledgeBaseQuery(BaseModel):
    """Track knowledge base query requests for usage history and billing."""

    QUERY_STATUS_CHOICES = (
        (QUERY_STATUS_NEW, _("New")),
        (QUERY_STATUS_PROCESSING, _("Processing")),
        (QUERY_STATUS_FINISHED, _("Finished")),
        (QUERY_STATUS_FAILED, _("Failed")),
    )

    knowledge_base = models.ForeignKey(
        "knowledge_base.KnowledgeBase",
        on_delete=models.CASCADE,
        verbose_name=_("Knowledge Base"),
        related_name="queries",
    )
    retrieval_setting = models.ForeignKey(
        "knowledge_base.RetrievalSetting",
        on_delete=models.SET_NULL,
        verbose_name=_("Retrieval Setting"),
        related_name="queries",


 ... (clipped 31 lines)

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:
Sensitive error exposure: The server persists raw exception text into KnowledgeBaseQuery.error_message, which is
then exposed via the KnowledgeBaseQuerySerializer, potentially leaking internal details to
end users.

Referred Code
except Exception as e:
    # Mark query as failed and save error
    query_record.status = QUERY_STATUS_FAILED
    query_record.error_message = str(e)
    query_record.save(update_fields=["status", "error_message"])
    raise

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:
Debug print in save: The new RetrievalSetting.save() uses print(self.retrieval_cost), producing unstructured
stdout logs and bypassing centralized logging controls.

Referred Code
def save(self, *args, **kwargs):
    """Override save to calculate retrieval cost."""
    # Calculate retrieval cost before saving
    self.retrieval_cost = self._calculate_retrieval_cost()
    print(self.retrieval_cost)
    super().save(*args, **kwargs)

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:
Broad exception rethrow: The query endpoint catches a broad exception, persists str(e), and re-raises without
mapping to a controlled API error response, which may lead to inconsistent client behavior
depending on global exception handling.

Referred Code
except Exception as e:
    # Mark query as failed and save error
    query_record.status = QUERY_STATUS_FAILED
    query_record.error_message = str(e)
    query_record.save(update_fields=["status", "error_message"])
    raise

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:
Raw server message UI: The UI surfaces backend-provided error fields directly to users via toast.error(...),
which may inadvertently display sensitive details if the backend returns verbose
validation/exception messages.

Referred Code
} catch (error: any) {
  console.error('Error saving tool configuration:', error);
  const errorMessage = error.response?.data?.tool_function_name
    || error.response?.data?.tool_description
    || error.response?.data?.enable_as_tool
    || error.response?.data?.message
    || t('errors.generic');
  toast.error(errorMessage);
  throw error;

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

@dosubot dosubot bot added 🔗 feat:integration 3rd-party tool integrations 🖼️ feat:ui Frontend/UI components 🧠 feat:workflow Smart crawl planning, route building labels Feb 24, 2026
@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Feb 24, 2026

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
Decouple hardcoded pricing from models

The retrieval cost calculation is currently hardcoded within the
RetrievalSetting model. This should be moved to a dedicated pricing service or
configuration to decouple business logic from the data model, improving
flexibility for future updates.

Examples:

backend/knowledge_base/models.py [339-360]
    def _calculate_retrieval_cost(self):
        """Calculate the cost in credits for using this retrieval setting."""
        cost = 0

        # Check if vector/hybrid search uses WaterCrawl embedding provider
        if self.retrieval_type in [
            self.RETRIEVAL_TYPE_VECTOR,
            self.RETRIEVAL_TYPE_HYBRID,
        ]:
            if self.knowledge_base.embedding_provider_config:

 ... (clipped 12 lines)

Solution Walkthrough:

Before:

# backend/knowledge_base/models.py

class RetrievalSetting(BaseModel):
    # ... fields ...
    retrieval_cost = models.PositiveIntegerField(...)

    def _calculate_retrieval_cost(self):
        cost = 0
        # Hardcoded logic:
        if self.retrieval_type in ["vector", "hybrid"]:
            if self.knowledge_base.embedding_provider_config.is_global:
                cost += 1 # Hardcoded value
        
        if self.reranker_enabled and self.reranker_provider_config.is_global:
            cost += 1 # Hardcoded value
        
        return cost

    def save(self, *args, **kwargs):
        self.retrieval_cost = self._calculate_retrieval_cost()
        super().save(*args, **kwargs)

After:

# backend/pricing/services.py (new or existing service)

class PricingService:
    @staticmethod
    def calculate_retrieval_cost(retrieval_setting):
        cost = 0
        # Logic now uses a configuration or a more flexible rule set
        # e.g., from a database model or settings
        pricing_config = get_pricing_config() # Fetches from DB/settings

        if retrieval_setting.retrieval_type in ["vector", "hybrid"]:
            if retrieval_setting.knowledge_base.embedding_provider_config.is_global:
                cost += pricing_config.vector_search_cost
        
        if retrieval_setting.reranker_enabled and retrieval_setting.reranker_provider_config.is_global:
            cost += pricing_config.reranker_cost
        
        return cost

# backend/knowledge_base/models.py
from pricing.services import PricingService

class RetrievalSetting(BaseModel):
    # ... fields ...
    def save(self, *args, **kwargs):
        self.retrieval_cost = PricingService.calculate_retrieval_cost(self)
        super().save(*args, **kwargs)
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a significant design flaw where pricing logic is hardcoded in the RetrievalSetting model, which impacts maintainability and flexibility for future pricing adjustments.

Medium
Possible issue
Ensure atomic query status updates

Wrap the creation and status update of KnowledgeBaseQuery in a
transaction.atomic() block to prevent data inconsistency if the status update
fails.

backend/knowledge_base/views.py [235-247]

-# Create query history record
-query_record = KnowledgeBaseQuery.objects.create(
-    knowledge_base=knowledge_base,
-    retrieval_setting=retrieval_setting,
-    query_text=serializer.validated_data["query"],
-    status=QUERY_STATUS_NEW,
-    retrieval_cost=retrieval_cost,
-)
+from django.db import transaction
 
-try:
+# ...
+
+# Create query history record and update status atomically
+with transaction.atomic():
+    query_record = KnowledgeBaseQuery.objects.create(
+        knowledge_base=knowledge_base,
+        retrieval_setting=retrieval_setting,
+        query_text=serializer.validated_data["query"],
+        status=QUERY_STATUS_NEW,
+        retrieval_cost=retrieval_cost,
+    )
+    # The post_save signal for QUERY_STATUS_NEW is triggered here.
+
     # Update status to processing
     query_record.status = QUERY_STATUS_PROCESSING
     query_record.save(update_fields=["status"])
 
+try:
+

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 8

__

Why: This suggestion correctly identifies a potential data inconsistency issue and proposes using a database transaction to ensure atomicity, which is a critical fix for maintaining data integrity.

Medium
Use current form state for testing

Update the tempAgent object to use the current tool configuration values from
the toolConfig hook instead of the potentially stale values from agentData to
ensure the test bench reflects unsaved changes.

frontend/src/pages/dashboard/AgentFormPage.tsx [355-369]

 const tempAgent = useMemo<Agent | null>(() => {
   const canTest = formState.providerConfigId && formState.modelKey && agentId;
   if (!canTest || !formState.draft || !agentData) return null;
 
   return {
     uuid: agentId,
     name: formState.name || t('agents.form.draftAgent'),
     status: 'draft' as AgentVersionStatus,
-    enable_as_tool: agentData.enable_as_tool,
-    tool_function_name: agentData.tool_function_name,
-    tool_description: agentData.tool_description,
+    enable_as_tool: toolConfig.enableAsTool,
+    tool_function_name: toolConfig.toolFunctionName,
+    tool_description: toolConfig.toolDescription,
     created_at: formState.draft.created_at,
     updated_at: formState.draft.updated_at,
   };
-}, [agentId, formState.providerConfigId, formState.modelKey, formState.draft, formState.name, agentData, t]);
+}, [agentId, formState.providerConfigId, formState.modelKey, formState.draft, formState.name, agentData, toolConfig, t]);
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a bug where the test bench would use stale tool configuration from agentData instead of the live form state from the toolConfig hook, which would lead to incorrect and confusing testing behavior for the user.

Medium
Fix incorrect API parameter value

Conditionally pass the status parameter to knowledgeBaseApi.listQueries, sending
undefined instead of an empty string when no status is selected to prevent an
API error.

frontend/src/pages/dashboard/QueryLogsPage.tsx [55-60]

 const data = await knowledgeBaseApi.listQueries(
   undefined,
   page,
   20,
-  status as QueryStatus
+  status ? (status as QueryStatus) : undefined
 );
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies that casting an empty string to the QueryStatus enum is invalid and would cause an API error, proposing a valid fix to ensure the filter works correctly.

Medium
Remove incorrect pluralization keys

Remove the redundant and grammatically incorrect _one and _other pluralization
keys for disableToolWarningMessage in the Japanese translations.

frontend/public/locales/ja.json [139-141]

 "disableToolWarningMessage": "このエージェントは現在{{count}}個の他のエージェントでツールとして使用されています。",
-"disableToolWarningMessage_one": "このエージェントは現在{{count}}他のエージェントでツールとして使用されています。",
-"disableToolWarningMessage_other": "このエージェントは現在{{count}}他のエージェントでツールとして使用されています。",
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: The suggestion correctly identifies that the added pluralization keys are grammatically incorrect and redundant in Japanese, proposing to remove them and rely on the correct base key.

Low
Prevent unhandled promise rejection
Suggestion Impact:The commit removed the `throw error;` from the catch block and replaced it with a comment, preventing unhandled promise rejections.

code diff:

@@ -53,7 +53,7 @@
         || error.response?.data?.message
         || t('errors.generic');
       toast.error(errorMessage);
-      throw error;
+      // Do not re-throw the error to prevent unhandled promise rejections.
     }

Remove the throw error; statement from the catch block in the saveToolConfig
function to prevent unhandled promise rejections in the browser console.

frontend/src/hooks/useAgentToolConfig.ts [38-58]

 const saveToolConfig = useCallback(async () => {
   if (!agentId) return;
 
   try {
     await agentApi.update(agentId, {
       enable_as_tool: enableAsTool,
       tool_function_name: enableAsTool ? toolFunctionName : '',
       tool_description: enableAsTool ? toolDescription : '',
     });
     toast.success(t('agents.form.toolConfigSaved'));
   } catch (error: any) {
     console.error('Error saving tool configuration:', error);
     const errorMessage = error.response?.data?.tool_function_name
       || error.response?.data?.tool_description
       || error.response?.data?.enable_as_tool
       || error.response?.data?.message
       || t('errors.generic');
     toast.error(errorMessage);
-    throw error;
+    // Do not re-throw the error to prevent unhandled promise rejections.
   }
 }, [agentId, enableAsTool, toolFunctionName, toolDescription, t]);

[Suggestion processed]

Suggestion importance[1-10]: 5

__

Why: The suggestion correctly points out that re-throwing an error after handling it can lead to unhandled promise rejections in the console, which is a valid code quality improvement.

Low
Fix incorrect pluralization in translation

Correct the Persian translation for disableToolWarningMessage_one to use a more
natural singular form instead of a placeholder.

frontend/public/locales/fa.json [140-141]

-"disableToolWarningMessage_one": "این نماینده در حال حاضر در {{count}} نماینده دیگر به‌عنوان ابزار استفاده می‌شود.",
+"disableToolWarningMessage_one": "این نماینده در حال حاضر در یک نماینده دیگر به‌عنوان ابزار استفاده می‌شود.",
 "disableToolWarningMessage_other": "این نماینده در حال حاضر در {{count}} نماینده دیگر به‌عنوان ابزار استفاده می‌شود.",
  • Apply / Chat
Suggestion importance[1-10]: 5

__

Why: The suggestion correctly identifies that the singular and plural translations are identical and proposes a more grammatically natural version for the singular case, improving translation quality.

Low
General
Fix missing hook dependencies
Suggestion Impact:The commit imported useCallback, converted fetchAgent to a useCallback with dependencies [agentId, navigate, t], and updated the fetching useEffect to depend on [agentId, fetchAgent], removing the eslint-disable for exhaustive-deps.

code diff:

-import { useState, useEffect } from 'react';
+import { useState, useEffect, useCallback } from 'react';
 
 import toast from 'react-hot-toast';
 import { useTranslation } from 'react-i18next';
@@ -25,25 +25,7 @@
   const [loading, setLoading] = useState(true);
   const [activeTab, setActiveTab] = useState<IntegrationTab>('api');
 
-  useEffect(() => {
-    if (agentId) {
-      fetchAgent();
-    }
-    // eslint-disable-next-line react-hooks/exhaustive-deps
-  }, [agentId]);
-
-  useEffect(() => {
-    if (agent) {
-      setItems([
-        { label: t('dashboard.navigation.dashboard'), href: '/dashboard' },
-        { label: t('dashboard.navigation.agents'), href: '/dashboard/agents' },
-        { label: agent.name, href: `/dashboard/agents/${agentId}` },
-        { label: t('agents.integrations.title'), current: true },
-      ]);
-    }
-  }, [agent, agentId, setItems, t]);
-
-  const fetchAgent = async () => {
+  const fetchAgent = useCallback(async () => {
     if (!agentId) return;
 
     setLoading(true);
@@ -63,7 +45,26 @@
     } finally {
       setLoading(false);
     }
-  };
+  }, [agentId, navigate, t]);
+
+  useEffect(() => {
+    if (agentId) {
+      fetchAgent();
+    }
+  }, [agentId, fetchAgent]);
+
+  useEffect(() => {
+    if (agent) {
+      setItems([
+        { label: t('dashboard.navigation.dashboard'), href: '/dashboard' },
+        { label: t('dashboard.navigation.agents'), href: '/dashboard/agents' },
+        { label: agent.name, href: `/dashboard/agents/${agentId}` },
+        { label: t('agents.integrations.title'), current: true },
+      ]);
+    }
+  }, [agent, agentId, setItems, t]);

Wrap the fetchAgent function in useCallback with all its dependencies (agentId,
navigate, t) and include fetchAgent in the useEffect dependency array to prevent
stale closures.

frontend/src/pages/dashboard/AgentIntegrationsPage.tsx [28-33]

+const fetchAgent = useCallback(async () => {
+  if (!agentId) return;
+
+  setLoading(true);
+  try {
+    const agentData = await agentApi.get(agentId);
+    setAgent(agentData);
+
+    // Redirect if agent is not published
+    if (agentData.status !== 'published') {
+      toast.error(t('agents.integrations.publishedOnly'));
+      navigate(`/dashboard/agents/${agentId}`);
+    }
+  } catch (error: any) {
+    console.error('Error fetching agent:', error);
+    toast.error(error.response?.data?.message || t('errors.generic'));
+    navigate('/dashboard/agents');
+  } finally {
+    setLoading(false);
+  }
+}, [agentId, navigate, t]);
+
 useEffect(() => {
   if (agentId) {
     fetchAgent();
   }
-  // eslint-disable-next-line react-hooks/exhaustive-deps
-}, [agentId]);
+}, [agentId, fetchAgent]);

[Suggestion processed]

Suggestion importance[1-10]: 5

__

Why: The suggestion correctly identifies missing dependencies in a useEffect hook and proposes the standard useCallback pattern to fix it, improving code correctness and preventing potential stale closures.

Low
Remove debug print statement
Suggestion Impact:Removed the debug print(self.retrieval_cost) line from the save method.

code diff:

@@ -362,7 +362,6 @@
         """Override save to calculate retrieval cost."""
         # Calculate retrieval cost before saving
         self.retrieval_cost = self._calculate_retrieval_cost()
-        print(self.retrieval_cost)
         super().save(*args, **kwargs)

Remove the debug print() statement from the save method in
backend/knowledge_base/models.py.

backend/knowledge_base/models.py [361-366]

 def save(self, *args, **kwargs):
     """Override save to calculate retrieval cost."""
     # Calculate retrieval cost before saving
     self.retrieval_cost = self._calculate_retrieval_cost()
-    print(self.retrieval_cost)
     super().save(*args, **kwargs)

[Suggestion processed]

Suggestion importance[1-10]: 4

__

Why: The suggestion correctly identifies a debug print() statement that should be removed from production code for better code hygiene and to avoid cluttering logs.

Low
Remove redundant base translation key

Remove the redundant base translation key importSuccess and rely on the specific
_one and _other pluralization keys.

frontend/public/locales/es.json [1339-1341]

-"importSuccess": "{{count}} resultado importado con éxito",
 "importSuccess_one": "{{count}} resultado importado con éxito",
 "importSuccess_other": "{{count}} resultados importados con éxito",
  • Apply / Chat
Suggestion importance[1-10]: 4

__

Why: The suggestion correctly identifies a redundant translation key and proposes its removal to improve maintainability, which is a valid but low-impact improvement.

Low
  • Update

- Add `.windsurf/rules/snyk_rules.md` to gitignore for auto-generated Snyk security rules
- Remove debug print statement from `RetrievalSetting.save()` method
amirasaran and others added 2 commits February 24, 2026 23:46
…ve reliability

- Add missing dependencies to useCallback and useEffect hooks in AgentFormPage and AgentDetailPage
- Destructure formState and toolConfig objects to use individual state values directly
- Wrap fetchAgent in useCallback with proper dependencies
- Fix useVariableDetection timer callback to avoid stale closure
- Add fallback to existing instance values in AgentListSerializer validation for tool_function_name and tool_description
Co-authored-by: qodo-code-review[bot] <151058649+qodo-code-review[bot]@users.noreply.github.com>
@amirasaran amirasaran merged commit 99cdaee into development Feb 24, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔗 feat:integration 3rd-party tool integrations 🖼️ feat:ui Frontend/UI components 🧠 feat:workflow Smart crawl planning, route building Review effort 4/5 size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant