Skip to content

Commit 160cdfa

Browse files
author
Manuel Rodriguez
committed
v1.0-ga
1 parent ba9bfc0 commit 160cdfa

150 files changed

Lines changed: 8045 additions & 3921 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,20 @@
11
ai_sdk_vector_store/
22
ai_sdk_sample_data/
3-
node_modules/
43
unstructured_*/
4+
node_modules/
55
__pycache__/
66
embeddings/
7-
uploads/
87
reports/
8+
uploads/
9+
.vscode/
910
tests/
1011
logs/
1112
venv/
12-
env/
13-
.vscode/
1413
google_service_account.json
15-
chatbot_config.env
1614
package-lock.json
17-
sdk_config.env
1815
.DS_Store
1916
*.pem
2017
*.crt
2118
*.key
2219
*.bak
20+
*.env

.hadolint.yaml

Lines changed: 0 additions & 6 deletions
This file was deleted.

Dockerfile

Lines changed: 0 additions & 35 deletions
This file was deleted.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# Denodo AI SDK
44

5-
Denodo AI SDK helps you quickly build AI chatbots and agents that answer questions using your enterprise data, combining search + generative AI for accurate, context-aware results.
5+
Denodo AI SDK helps you quickly build AI chatbots and agents that answer questions using your enterprise data, combining similarity search + LLMs for accurate, context-aware results.
66

77
It connects to the Denodo Platform, works with popular LLMs and vector stores, and ships with a ready-to-run sample chatbot and simple APIs to get started fast.
88

RELEASE_NOTES.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
version 1.0 - 20260220
2+
------------------------
3+
4+
- Added enhancement to pre-fill AI SDK/Chatbot LLM settings in chatbot UI modal
5+
- Integrated sample data generation errors in getMetadata endpoint output
6+
- Enhanced vectorization endpoints access control to only allow specified users to insert/delete data in the vector store
7+
- Improved migration script in run.py --migrate to account for duplicates/new/deprecated variables
8+
9+
version 1.0-beta - 20260212
10+
------------------------
11+
12+
- Changed default value of allow_external_associations to false in answerQuestion endpoint
13+
- Made ambiguity detection optional in the answerQuestion endpoints with check_ambiguity parameter
14+
- Updated default LLM models in sdk_config.env.example and chatbot_config.env.example
15+
- Fixed execution result pagination not resetting between different tool calls in chatbot UI
16+
- Included tool output in chatbot UI
17+
- Added support for new vector functions in VQL generation prompts
18+
- Included truncateVectors parameter in execute_vql
19+
- Improved Knowledge Base Manager to handle unstructured data in the Chatbot UI
20+
121
version 0.13 - 20260122
222
------------------------
323

api/deepquery/reporting_agent/utils.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,6 @@ def prepare_html(html_content, logo_data_uri=None):
422422

423423
return str(body)
424424

425-
426425
def build_styled_html(html_content: str, color_palette: dict, title: str) -> str:
427426
"""
428427
Build a complete styled HTML document with Denodo branding and color palette.

api/deepquery/utils.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ def filter_tool_calls_report_agent(tool_calls, default_rows=10):
7575

7676
return filtered_calls
7777

78-
7978
def filter_tool_calls_visualization(tool_calls, default_rows=10):
8079
"""
8180
Filter visualization tool calls (database_agent with generate_graph action).

api/endpoints/answerDataQuestion.py

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,32 +14,18 @@
1414
import traceback
1515

1616
from pydantic import BaseModel, Field
17-
from typing import Dict, Annotated, List
17+
from typing import Dict, List
1818

1919
from fastapi.responses import JSONResponse
2020
from fastapi.encoders import jsonable_encoder
2121
from fastapi import APIRouter, Depends, HTTPException, Query
22-
from fastapi.security import HTTPBasic, HTTPBasicCredentials, HTTPAuthorizationCredentials, HTTPBearer
2322

24-
from api.utils.sdk_utils import timing_context, add_tokens, generate_session_id, handle_endpoint_error
23+
from api.utils.sdk_utils import timing_context, add_tokens, generate_session_id, handle_endpoint_error, authenticate
2524
from api.utils import sdk_ai_tools
2625
from api.utils import sdk_answer_question
2726
from api.utils import state_manager
2827

2928
router = APIRouter()
30-
security_basic = HTTPBasic(auto_error = False)
31-
security_bearer = HTTPBearer(auto_error = False)
32-
33-
def authenticate(
34-
basic_credentials: Annotated[HTTPBasicCredentials, Depends(security_basic)],
35-
bearer_credentials: Annotated[HTTPAuthorizationCredentials, Depends(security_bearer)]
36-
):
37-
if bearer_credentials is not None:
38-
return bearer_credentials.credentials
39-
elif basic_credentials is not None:
40-
return (basic_credentials.username, basic_credentials.password)
41-
else:
42-
raise HTTPException(status_code=401, detail="Authentication required")
4329

4430
class answerDataQuestionRequest(BaseModel):
4531
question: str
@@ -64,7 +50,7 @@ class answerDataQuestionRequest(BaseModel):
6450
description="A comma-separated list of tags to reduce the scope of the question to. If empty, all tags in the vector DB the user has permissions to will be considered."
6551
)
6652
allow_external_associations: bool = Field(
67-
default = True,
53+
default = False,
6854
description="If False, views from associations will NOT be considered if they don't belong to the VDBs/Tags specified in vdp_database_names and vdp_tag_names. If no VDBs/Tags specified, all views from associations will be considered."
6955
)
7056
use_views: str = Field(
@@ -95,6 +81,10 @@ class answerDataQuestionRequest(BaseModel):
9581
)
9682
disclaimer: bool = True
9783
verbose: bool = True
84+
check_ambiguity: bool = Field(
85+
default = bool(int(os.getenv('CHECK_AMBIGUITY', '1'))),
86+
description="If false, skip ambiguity detection."
87+
)
9888
vql_execute_rows_limit: int = int(os.getenv('VQL_EXECUTE_ROWS_LIMIT', '100'))
9989
llm_response_rows_limit: int = int(os.getenv('LLM_RESPONSE_ROWS_LIMIT', '15'))
10090

@@ -246,7 +236,8 @@ async def process_data_question(request_data: answerDataQuestionRequest, auth: s
246236
mode="data",
247237
custom_instructions=request_data.custom_instructions,
248238
session_id=session_id,
249-
column_description_char_limit=request_data.vector_search_column_description_char_limit
239+
column_description_char_limit=request_data.vector_search_column_description_char_limit,
240+
check_ambiguity=request_data.check_ambiguity
250241
)
251242

252243
ambiguity_message = sdk_answer_question.build_ambiguity_message(category_response)

api/endpoints/answerMetadataQuestion.py

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,32 +14,18 @@
1414
import traceback
1515

1616
from pydantic import BaseModel, Field
17-
from typing import Dict, Annotated, List
17+
from typing import Dict, List
1818

1919
from fastapi.responses import JSONResponse
2020
from fastapi.encoders import jsonable_encoder
2121
from fastapi import APIRouter, Depends, HTTPException, Query
22-
from fastapi.security import HTTPBasic, HTTPBasicCredentials, HTTPAuthorizationCredentials, HTTPBearer
2322

24-
from api.utils.sdk_utils import timing_context, handle_endpoint_error, generate_session_id
23+
from api.utils.sdk_utils import timing_context, handle_endpoint_error, generate_session_id, authenticate
2524
from api.utils import sdk_ai_tools
2625
from api.utils import sdk_answer_question
2726
from api.utils import state_manager
2827

2928
router = APIRouter()
30-
security_basic = HTTPBasic(auto_error = False)
31-
security_bearer = HTTPBearer(auto_error = False)
32-
33-
def authenticate(
34-
basic_credentials: Annotated[HTTPBasicCredentials, Depends(security_basic)],
35-
bearer_credentials: Annotated[HTTPAuthorizationCredentials, Depends(security_bearer)]
36-
):
37-
if bearer_credentials is not None:
38-
return bearer_credentials.credentials
39-
elif basic_credentials is not None:
40-
return (basic_credentials.username, basic_credentials.password)
41-
else:
42-
raise HTTPException(status_code=401, detail="Authentication required")
4329

4430
class answerMetadataQuestionRequest(BaseModel):
4531
question: str
@@ -64,7 +50,7 @@ class answerMetadataQuestionRequest(BaseModel):
6450
description="A comma-separated list of tags to reduce the scope of the question to. If empty, all tags in the vector DB the user has permissions to will be considered."
6551
)
6652
allow_external_associations: bool = Field(
67-
default = True,
53+
default = False,
6854
description="If False, views from associations will NOT be considered if they don't belong to the VDBs/Tags specified in vdp_database_names and vdp_tag_names. If no VDBs/Tags specified, all views from associations will be considered."
6955
)
7056
use_views: str = Field(

api/endpoints/answerQuestion.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class answerQuestionRequest(BaseModel):
5353
description="A comma-separated list of tags to reduce the scope of the question to. If empty, all tags in the vector DB the user has permissions to will be considered."
5454
)
5555
allow_external_associations: bool = Field(
56-
default = True,
56+
default = False,
5757
description="If False, views from associations will NOT be considered if they don't belong to the VDBs/Tags specified in vdp_database_names and vdp_tag_names. If no VDBs/Tags specified, all views from associations will be considered."
5858
)
5959
use_views: str = Field(
@@ -85,6 +85,10 @@ class answerQuestionRequest(BaseModel):
8585
mode: Literal["default", "data", "metadata"] = Field(default = "default")
8686
disclaimer: bool = True
8787
verbose: bool = True
88+
check_ambiguity: bool = Field(
89+
default = bool(int(os.getenv('CHECK_AMBIGUITY', '1'))),
90+
description="If false, skip ambiguity detection."
91+
)
8892
vql_execute_rows_limit: int = int(os.getenv('VQL_EXECUTE_ROWS_LIMIT', '100'))
8993
llm_response_rows_limit: int = int(os.getenv('LLM_RESPONSE_ROWS_LIMIT', '15'))
9094

@@ -251,7 +255,8 @@ async def process_question(request_data: answerQuestionRequest, auth: str):
251255
mode=request_data.mode,
252256
custom_instructions=request_data.custom_instructions,
253257
session_id=session_id,
254-
column_description_char_limit=request_data.vector_search_column_description_char_limit
258+
column_description_char_limit=request_data.vector_search_column_description_char_limit,
259+
check_ambiguity=request_data.check_ambiguity
255260
)
256261

257262
ambiguity_message = sdk_answer_question.build_ambiguity_message(category_response)

0 commit comments

Comments
 (0)