fixes infomaniak download
This commit is contained in:
parent
9816f13ae9
commit
49f3660d89
5 changed files with 68 additions and 10 deletions
|
|
@ -13,6 +13,35 @@ from modules.datamodels.datamodelAi import AiModel, PriorityEnum, ProcessingMode
|
|||
# Configure logger
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _supportsCustomTemperature(modelName: str) -> bool:
|
||||
"""Check whether an Anthropic model accepts a custom ``temperature``.
|
||||
|
||||
Anthropic's Extended-Thinking models (Claude 4.7 Opus and the
|
||||
upcoming 4.7 Sonnet/Haiku, plus all 5.x and beyond) reject every
|
||||
``temperature`` value with HTTP 400
|
||||
``{"error": "`temperature` is deprecated for this model."}`` --
|
||||
only the model's internal default is accepted. Older Claude 4.5 /
|
||||
4.6 models still accept any value in [0, 1].
|
||||
|
||||
Returns:
|
||||
True if ``temperature`` may be sent; False if it must be omitted.
|
||||
"""
|
||||
if not modelName:
|
||||
return True
|
||||
name = modelName.lower()
|
||||
if name.startswith("claude-opus-4-7"):
|
||||
return False
|
||||
if name.startswith("claude-sonnet-4-7"):
|
||||
return False
|
||||
if name.startswith("claude-haiku-4-7"):
|
||||
return False
|
||||
# 5.x and beyond: same Extended-Thinking family, no custom temperature.
|
||||
if name.startswith("claude-opus-5") or name.startswith("claude-sonnet-5") or name.startswith("claude-haiku-5"):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def loadConfigData():
|
||||
"""Load configuration data for Anthropic connector"""
|
||||
return {
|
||||
|
|
@ -276,8 +305,11 @@ class AiAnthropic(BaseConnectorAi):
|
|||
payload: Dict[str, Any] = {
|
||||
"model": model.name,
|
||||
"messages": converted_messages,
|
||||
"temperature": temperature,
|
||||
}
|
||||
# Extended-Thinking models (claude-opus-4-7 etc.) reject any
|
||||
# `temperature` value -- only the model default is accepted.
|
||||
if _supportsCustomTemperature(model.name):
|
||||
payload["temperature"] = temperature
|
||||
|
||||
# Anthropic requires max_tokens - use provided value or throw error
|
||||
if maxTokens is None:
|
||||
|
|
@ -381,10 +413,11 @@ class AiAnthropic(BaseConnectorAi):
|
|||
payload: Dict[str, Any] = {
|
||||
"model": model.name,
|
||||
"messages": converted,
|
||||
"temperature": temperature,
|
||||
"max_tokens": model.maxTokens,
|
||||
"stream": True,
|
||||
}
|
||||
if _supportsCustomTemperature(model.name):
|
||||
payload["temperature"] = temperature
|
||||
if system_prompt:
|
||||
payload["system"] = system_prompt
|
||||
if modelCall.tools:
|
||||
|
|
@ -609,8 +642,8 @@ class AiAnthropic(BaseConnectorAi):
|
|||
if systemPrompt:
|
||||
payload["system"] = systemPrompt
|
||||
|
||||
# Set temperature from model
|
||||
payload["temperature"] = temperature
|
||||
if _supportsCustomTemperature(model.name):
|
||||
payload["temperature"] = temperature
|
||||
|
||||
# Make API call with headers from httpClient (which includes anthropic-version)
|
||||
response = await self.httpClient.post(
|
||||
|
|
|
|||
|
|
@ -101,13 +101,22 @@ async def _infomaniakDownload(
|
|||
endpoint: str,
|
||||
baseUrl: str = _API_BASE,
|
||||
) -> Optional[bytes]:
|
||||
"""Binary download from an Infomaniak host. Returns bytes or ``None``."""
|
||||
"""Binary download from an Infomaniak host. Returns bytes or ``None``.
|
||||
|
||||
Unlike :func:`_infomaniakGet`, this follows redirects: kDrive's
|
||||
``/2/drive/{driveId}/files/{fileId}/download`` answers with
|
||||
``302 -> presigned CDN URL`` (standard for bandwidth-heavy
|
||||
transfers), and the same pattern shows up on Calendar/Contacts
|
||||
export endpoints. Refusing to follow would lose every download.
|
||||
The Authorization header is preserved across the redirect by
|
||||
aiohttp because the host is the same Infomaniak property.
|
||||
"""
|
||||
url = f"{baseUrl.rstrip('/')}/{endpoint.lstrip('/')}"
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
timeout = aiohttp.ClientTimeout(total=120)
|
||||
try:
|
||||
async with aiohttp.ClientSession(timeout=timeout) as session:
|
||||
async with session.get(url, headers=headers, allow_redirects=False) as resp:
|
||||
async with session.get(url, headers=headers, allow_redirects=True) as resp:
|
||||
if resp.status == 200:
|
||||
return await resp.read()
|
||||
logger.warning(
|
||||
|
|
|
|||
|
|
@ -26,7 +26,12 @@ class DataSource(PowerOnModel):
|
|||
json_schema_extra={"label": "Verbindungs-ID", "fk_target": {"db": "poweron_app", "table": "UserConnection", "labelField": "externalUsername"}},
|
||||
)
|
||||
sourceType: str = Field(
|
||||
description="sharepointFolder, googleDriveFolder, outlookFolder, ftpFolder, clickupList (path under /team/...)",
|
||||
description=(
|
||||
"sharepointFolder, onedriveFolder, googleDriveFolder, "
|
||||
"outlookFolder, gmailFolder, ftpFolder, clickupList "
|
||||
"(path under /team/...), kdriveFolder, calendarFolder, "
|
||||
"contactFolder"
|
||||
),
|
||||
json_schema_extra={"label": "Quellentyp"},
|
||||
)
|
||||
path: str = Field(
|
||||
|
|
|
|||
|
|
@ -188,6 +188,9 @@ _SOURCE_TYPE_TO_SERVICE = {
|
|||
"gmailFolder": "gmail",
|
||||
"ftpFolder": "files",
|
||||
"clickupList": "clickup",
|
||||
"kdriveFolder": "kdrive",
|
||||
"calendarFolder": "calendar",
|
||||
"contactFolder": "contact",
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,11 @@ def _registerDataSourceTools(registry: ToolRegistry, services):
|
|||
return getattr(chatService, "interfaceDbComponent", None)
|
||||
|
||||
# ---- DataSource convenience tools ----
|
||||
# Maps the FE-side `sourceType` literal (see SourcesTab.tsx
|
||||
# `_SERVICE_TO_SOURCE_TYPE`) to the Connector's `service` key in
|
||||
# `_SERVICE_MAP`. Keep this table in sync with both the FE and the
|
||||
# Connector `_SERVICE_MAP` entries -- a missing row produces
|
||||
# "Service '<sourceType>' not available" in the agent tools.
|
||||
_SOURCE_TYPE_TO_SERVICE = {
|
||||
"sharepointFolder": "sharepoint",
|
||||
"onedriveFolder": "onedrive",
|
||||
|
|
@ -45,6 +50,9 @@ def _registerDataSourceTools(registry: ToolRegistry, services):
|
|||
"gmailFolder": "gmail",
|
||||
"ftpFolder": "files",
|
||||
"clickupList": "clickup",
|
||||
"kdriveFolder": "kdrive",
|
||||
"calendarFolder": "calendar",
|
||||
"contactFolder": "contact",
|
||||
}
|
||||
|
||||
async def _resolveDataSource(dsId: str):
|
||||
|
|
|
|||
Loading…
Reference in a new issue