nucliadb-agentic-api 1.0.0.post244__tar.gz → 1.0.0.post262__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/PKG-INFO +1 -1
  2. nucliadb_agentic_api-1.0.0.post262/VERSION +1 -0
  3. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/pyproject.toml +8 -8
  4. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/pyproject.toml.orig +8 -8
  5. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/agentic/ask_transform_to_interaction.py +3 -1
  6. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/db/transform.py +16 -18
  7. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/models.py +16 -9
  8. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/v1/agentic_configs.py +15 -1
  9. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/v1/ask.py +1 -3
  10. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/v1/ask_websocket.py +2 -4
  11. nucliadb_agentic_api-1.0.0.post244/VERSION +0 -1
  12. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/README.md +0 -0
  13. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/alembic/README +0 -0
  14. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/alembic/env.py +0 -0
  15. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/alembic/script.py.mako +0 -0
  16. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/alembic/versions/7f3b2f92a8c1_add_agentic_config_table.py +0 -0
  17. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/alembic/versions/b3c4d5e6f7a8_add_sources_table.py +0 -0
  18. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/alembic/versions/c4d5e6f7a8b9_add_agentic_config_soft_deletion.py +0 -0
  19. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/alembic.ini +0 -0
  20. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/VERSION +0 -0
  21. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/__init__.py +0 -0
  22. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/agentic/__init__.py +0 -0
  23. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/agentic/ask_handler.py +0 -0
  24. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/agentic/ask_result.py +0 -0
  25. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/app.py +0 -0
  26. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/commands.py +0 -0
  27. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/db/__init__.py +0 -0
  28. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/db/agentic_configs.py +0 -0
  29. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/db/settings.py +0 -0
  30. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/db/sources.py +0 -0
  31. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/exceptions.py +0 -0
  32. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/logging.py +0 -0
  33. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/py.typed +0 -0
  34. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/server/__init__.py +0 -0
  35. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/server/server.py +0 -0
  36. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/server/session.py +0 -0
  37. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/server/settings.py +0 -0
  38. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/settings.py +0 -0
  39. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/utils.py +0 -0
  40. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/v1/__init__.py +0 -0
  41. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/v1/mcp_content.py +0 -0
  42. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/v1/mcp_nucliadb.py +0 -0
  43. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/v1/oauth.py +0 -0
  44. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/v1/router.py +0 -0
  45. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/v1/sources.py +0 -0
  46. {nucliadb_agentic_api-1.0.0.post244 → nucliadb_agentic_api-1.0.0.post262}/src/nucliadb_agentic_api/v1/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nucliadb_agentic_api
3
- Version: 1.0.0.post244
3
+ Version: 1.0.0.post262
4
4
  Summary: NucliaDB Agentic API for Hyperforge
5
5
  Author: AI Data Team
6
6
  Author-email: AI Data Team <learning@nuclia.com>
@@ -0,0 +1 @@
1
+ 1.0.0.post262
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "nucliadb_agentic_api"
7
- version = "1.0.0.post244"
7
+ version = "1.0.0.post262"
8
8
  description = "NucliaDB Agentic API for Hyperforge"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -72,15 +72,15 @@ server = [
72
72
  "nucliadb-sdk>=6.14.0.post6532",
73
73
  "nucliadb-telemetry[otel]>=6.14.0.post6534",
74
74
  "nucliadb-utils[storages,fastapi]>=6.15.0.post6671",
75
- "hyperforge>=1.0.0.post237",
75
+ "hyperforge>=1.0.0.post281",
76
76
  "hyperforge_conditional>=1.0.0.post27",
77
- "hyperforge_mcp>=1.0.0.post41",
77
+ "hyperforge_mcp>=1.0.0.post95",
78
78
  "hyperforge_nucliadb>=1.0.0.post46",
79
- "hyperforge_rephrase>=1.0.0.post40",
80
- "hyperforge_smart>=1.0.0.post30",
81
- "hyperforge_summarize>=1.0.0.post29",
82
- "hyperforge_google>=1.0.0.post38",
83
- "hyperforge_perplexity>=1.0.0.post30",
79
+ "hyperforge_rephrase>=1.0.0.post74",
80
+ "hyperforge_smart>=1.0.0.post117",
81
+ "hyperforge_summarize>=1.0.0.post85",
82
+ "hyperforge_google>=1.0.0.post71",
83
+ "hyperforge_perplexity>=1.0.0.post57",
84
84
  "pydantic_settings",
85
85
  "mcp>=1.26.0",
86
86
  "prometheus_client",
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "nucliadb_agentic_api"
7
- version = "1.0.0.post244"
7
+ version = "1.0.0.post262"
8
8
  authors = [{ name = "AI Data Team", email = "learning@nuclia.com" }]
9
9
  description = "NucliaDB Agentic API for Hyperforge"
10
10
  readme = "README.md"
@@ -67,15 +67,15 @@ server = [
67
67
  "nucliadb-sdk>=6.14.0.post6532",
68
68
  "nucliadb-telemetry[otel]>=6.14.0.post6534",
69
69
  "nucliadb-utils[storages,fastapi]>=6.15.0.post6671",
70
- "hyperforge>=1.0.0.post237",
70
+ "hyperforge>=1.0.0.post281",
71
71
  "hyperforge_conditional>=1.0.0.post27",
72
- "hyperforge_mcp>=1.0.0.post41",
72
+ "hyperforge_mcp>=1.0.0.post95",
73
73
  "hyperforge_nucliadb>=1.0.0.post46",
74
- "hyperforge_rephrase>=1.0.0.post40",
75
- "hyperforge_smart>=1.0.0.post30",
76
- "hyperforge_summarize>=1.0.0.post29",
77
- "hyperforge_google>=1.0.0.post38",
78
- "hyperforge_perplexity>=1.0.0.post30",
74
+ "hyperforge_rephrase>=1.0.0.post74",
75
+ "hyperforge_smart>=1.0.0.post117",
76
+ "hyperforge_summarize>=1.0.0.post85",
77
+ "hyperforge_google>=1.0.0.post71",
78
+ "hyperforge_perplexity>=1.0.0.post57",
79
79
  "pydantic_settings",
80
80
  "mcp>=1.26.0",
81
81
  "prometheus_client",
@@ -6,5 +6,7 @@ def interaction_from_ask_request(ask_request: AskRequest) -> InteractionRequest:
6
6
  # Transform the AskRequest into an ARAG interaction
7
7
  # This is a placeholder implementation and should be adapted to the actual ARAG interaction format
8
8
  interaction = InteractionRequest(question=ask_request.query, streaming=True)
9
- interaction.arguments["ask_request"] = ask_request.model_dump_json()
9
+ interaction.arguments["ask_request"] = ask_request.model_dump_json(
10
+ exclude_unset=True
11
+ )
10
12
  return interaction
@@ -63,7 +63,7 @@ async def transform_agentic_config(
63
63
  kb=rephrase.ask_to,
64
64
  history=rephrase.history if rephrase.history is not None else False,
65
65
  )
66
- if rephrase.model:
66
+ if rephrase.model is not None:
67
67
  rephrase_config.model = rephrase.model
68
68
  preprocess.append(rephrase_config)
69
69
 
@@ -139,16 +139,16 @@ async def transform_agentic_config(
139
139
  ),
140
140
  ) # TODO: pass real config if needed
141
141
  drivers[uid] = mcp_driver_config
142
- registered_agents.append(
143
- MCPAgentConfig(
144
- id=f"mcp-agent-{source}",
145
- title=source_title,
146
- source=uid,
147
- transport=Transport.HTTP,
148
- tool_choice_model=source_obj.tool_choice_model or "chatgpt-4.1",
149
- valid_headers=source_obj.valid_headers or [],
150
- )
142
+ mcp_agent_config = MCPAgentConfig(
143
+ id=f"mcp-agent-{source}",
144
+ title=source_title,
145
+ source=uid,
146
+ transport=Transport.HTTP,
147
+ valid_headers=source_obj.valid_headers or [],
151
148
  )
149
+ if source_obj.tool_choice_model is not None:
150
+ mcp_agent_config.tool_choice_model = source_obj.tool_choice_model
151
+ registered_agents.append(mcp_agent_config)
152
152
 
153
153
  elif source_obj.type == "google":
154
154
  global_driver.append("google")
@@ -167,7 +167,6 @@ async def transform_agentic_config(
167
167
  )
168
168
  )
169
169
 
170
- models = smart_agent.models
171
170
  smart_config = SmartAgentConfig(
172
171
  title=f"{title} - Smart Agent",
173
172
  planning_mode=smart_agent.mode.value,
@@ -176,14 +175,13 @@ async def transform_agentic_config(
176
175
  # SmartAgentConfig's before-validator accepts serialized agent configs.
177
176
  registered_agents=[agent.model_dump() for agent in registered_agents], # type: ignore[misc]
178
177
  )
179
- # Only set the models if they are provided; otherwise, leave them as None to use hyperforge's default models.
180
- # TODO: Provide nucliadb agentic api level defaults for models
181
- if models:
182
- if models.context_validation:
178
+ models = smart_agent.models
179
+ if models is not None:
180
+ if models.context_validation is not None:
183
181
  smart_config.context_validation_model = models.context_validation
184
- if models.planner:
182
+ if models.planner is not None:
185
183
  smart_config.planner_model = models.planner
186
- if models.executor:
184
+ if models.executor is not None:
187
185
  smart_config.executor_model = models.executor
188
186
  context.append(smart_config)
189
187
 
@@ -198,7 +196,7 @@ async def transform_agentic_config(
198
196
  force_chunk_level_citations=False,
199
197
  history=summarize.history if summarize.history is not None else False,
200
198
  )
201
- if summarize.model:
199
+ if summarize.model is not None:
202
200
  summarize_config.model = summarize.model
203
201
  generation.append(summarize_config)
204
202
 
@@ -2,6 +2,7 @@ from enum import Enum
2
2
  from typing import Any, Dict, List, Literal, Optional, Union
3
3
 
4
4
  from hyperforge.driver import DriverConfig
5
+ from hyperforge.llm_config import LLMConfig, LLMField, llm_defaults
5
6
  from hyperforge.models import Rules
6
7
  from nucliadb_models import FilterExpression, TextFormat
7
8
  from pydantic import BaseModel, Field
@@ -132,7 +133,7 @@ class InteractionRequest(BaseModel):
132
133
  class AgenticRephraseConfiguration(BaseModel):
133
134
  ask_to: Optional[str] = None
134
135
  prompt: Optional[str] = None
135
- model: Optional[str] = None
136
+ model: LLMField | None = Field(default=LLMConfig(model_id=llm_defaults.default))
136
137
  history: Optional[bool] = True
137
138
 
138
139
 
@@ -142,9 +143,11 @@ class AgenticSmartAgentMode(str, Enum):
142
143
 
143
144
 
144
145
  class AgenticSmartAgentModels(BaseModel):
145
- context_validation: Optional[str] = None
146
- planner: Optional[str] = None
147
- executor: Optional[str] = None
146
+ context_validation: LLMField | None = Field(
147
+ default=LLMConfig(model_id=llm_defaults.default)
148
+ )
149
+ planner: LLMField | None = Field(default=LLMConfig(model_id=llm_defaults.smart))
150
+ executor: LLMField | None = Field(default=LLMConfig(model_id=llm_defaults.smart))
148
151
 
149
152
 
150
153
  class NucliaDBAgenticSource(BaseModel):
@@ -188,7 +191,9 @@ class MCPAgenticSource(BaseModel):
188
191
  description: Optional[str] = None
189
192
  uri: str
190
193
  headers: Optional[Dict[str, Any]] = None
191
- tool_choice_model: Optional[str] = None
194
+ tool_choice_model: LLMField | None = Field(
195
+ default=LLMConfig(model_id=llm_defaults.smart)
196
+ )
192
197
  valid_headers: Optional[List[str]] = None
193
198
 
194
199
 
@@ -216,7 +221,9 @@ AgenticSource = Annotated[
216
221
  class AgenticSmartAgentConfiguration(BaseModel):
217
222
  mode: AgenticSmartAgentMode = AgenticSmartAgentMode.REACTIVE
218
223
  extra_prompt: Optional[str] = None
219
- models: Optional[AgenticSmartAgentModels] = None
224
+ models: AgenticSmartAgentModels | None = Field(
225
+ default_factory=AgenticSmartAgentModels
226
+ )
220
227
  sources: List[str] = Field(default_factory=list)
221
228
  history: Optional[bool] = True
222
229
 
@@ -225,7 +232,7 @@ class AgenticSummarizeConfiguration(BaseModel):
225
232
  user_prompt: Optional[str] = None
226
233
  system_prompt: Optional[str] = None
227
234
  conversational: bool = True
228
- model: Optional[str] = None
235
+ model: LLMField | None = Field(default=LLMConfig(model_id=llm_defaults.default))
229
236
  history: Optional[bool] = True
230
237
 
231
238
 
@@ -292,8 +299,8 @@ class MCPSourceSchema(BaseModel):
292
299
  default=None,
293
300
  description="HTTP headers forwarded with every MCP request",
294
301
  )
295
- tool_choice_model: Optional[str] = Field(
296
- default=None,
302
+ tool_choice_model: LLMField | None = Field(
303
+ default=LLMConfig(model_id=llm_defaults.smart),
297
304
  description="Model used for MCP tool selection",
298
305
  )
299
306
  valid_headers: Optional[List[str]] = Field(
@@ -1,4 +1,4 @@
1
- from typing import TYPE_CHECKING, cast
1
+ from typing import TYPE_CHECKING, Any, cast
2
2
 
3
3
  from fastapi import Header, HTTPException, Request, Response
4
4
  from nucliadb_models.resource import NucliaDBRoles
@@ -12,6 +12,20 @@ if TYPE_CHECKING:
12
12
  from nucliadb_agentic_api.app import HTTPApplication
13
13
 
14
14
 
15
+ @router.get(
16
+ "/api/v1/kb/{kbid}/agentic_configs/schema",
17
+ status_code=200,
18
+ summary="Get agentic configuration schema",
19
+ tags=["Agentic configs"],
20
+ )
21
+ @requires(NucliaDBRoles.READER)
22
+ async def get_agentic_config_schema_endpoint(
23
+ request: Request,
24
+ kbid: str,
25
+ ) -> dict[str, Any]:
26
+ return AgenticConfigSchema.model_json_schema()
27
+
28
+
15
29
  @router.post(
16
30
  "/api/v1/kb/{kbid}/agentic_configs/{agentic_id}",
17
31
  status_code=201,
@@ -72,9 +72,7 @@ async def ask_knowledgebox_endpoint(
72
72
  rpc.get_sdk("reader"), kbid, item
73
73
  )
74
74
  except rpc.SearchConfigurationNotFound:
75
- return HTTPClientError(
76
- status_code=400, detail="Search configuration not found"
77
- )
75
+ return HTTPClientError(status_code=400, detail="Search configuration not found")
78
76
  except rpc.InvalidAskSearchConfiguration:
79
77
  return HTTPClientError(
80
78
  status_code=400,
@@ -75,9 +75,7 @@ async def websocket_endpoint(
75
75
  rpc.get_sdk("reader"), kbid, item
76
76
  )
77
77
  except rpc.SearchConfigurationNotFound:
78
- return HTTPClientError(
79
- status_code=400, detail="Search configuration not found"
80
- )
78
+ return HTTPClientError(status_code=400, detail="Search configuration not found")
81
79
  except rpc.InvalidAskSearchConfiguration:
82
80
  return HTTPClientError(
83
81
  status_code=400,
@@ -110,7 +108,7 @@ async def websocket_endpoint(
110
108
  interaction.headers[header] = header_value
111
109
 
112
110
  item.query = interaction.question
113
- interaction.arguments["ask_request"] = item.model_dump_json()
111
+ interaction.arguments["ask_request"] = item.model_dump_json(exclude_unset=True)
114
112
 
115
113
  async for msg in stream_response(
116
114
  websocket.app,
@@ -1 +0,0 @@
1
- 1.0.0.post244