mirror of
https://github.com/onyx-dot-app/onyx.git
synced 2026-02-18 00:05:47 +00:00
Compare commits
9 Commits
additional
...
bookstack_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6fb85d53c9 | ||
|
|
3b92cf2f38 | ||
|
|
65485e0ea1 | ||
|
|
67028782f0 | ||
|
|
09b14c68ca | ||
|
|
8347bfe5ee | ||
|
|
bf175d0749 | ||
|
|
c892dd9c6f | ||
|
|
bf51ac5dc0 |
@@ -140,7 +140,7 @@ def on_task_postrun(
|
||||
f"{f'for tenant_id={tenant_id}' if tenant_id else ''}"
|
||||
)
|
||||
|
||||
r = get_redis_client(tenant_id=tenant_id)
|
||||
r = get_redis_client()
|
||||
|
||||
if task_id.startswith(RedisConnectorCredentialPair.PREFIX):
|
||||
r.srem(RedisConnectorCredentialPair.get_taskset_key(), task_id)
|
||||
|
||||
@@ -190,8 +190,7 @@ def create_chat_chain(
|
||||
and previous_message.message_type == MessageType.ASSISTANT
|
||||
and mainline_messages
|
||||
):
|
||||
if current_message.refined_answer_improvement:
|
||||
mainline_messages[-1] = current_message
|
||||
mainline_messages[-1] = current_message
|
||||
else:
|
||||
mainline_messages.append(current_message)
|
||||
|
||||
|
||||
@@ -142,15 +142,6 @@ class MessageResponseIDInfo(BaseModel):
|
||||
reserved_assistant_message_id: int
|
||||
|
||||
|
||||
class AgentMessageIDInfo(BaseModel):
|
||||
level: int
|
||||
message_id: int
|
||||
|
||||
|
||||
class AgenticMessageResponseIDInfo(BaseModel):
|
||||
agentic_message_ids: list[AgentMessageIDInfo]
|
||||
|
||||
|
||||
class StreamingError(BaseModel):
|
||||
error: str
|
||||
stack_trace: str | None = None
|
||||
|
||||
@@ -11,8 +11,6 @@ from onyx.agents.agent_search.orchestration.nodes.call_tool import ToolCallExcep
|
||||
from onyx.chat.answer import Answer
|
||||
from onyx.chat.chat_utils import create_chat_chain
|
||||
from onyx.chat.chat_utils import create_temporary_persona
|
||||
from onyx.chat.models import AgenticMessageResponseIDInfo
|
||||
from onyx.chat.models import AgentMessageIDInfo
|
||||
from onyx.chat.models import AgentSearchPacket
|
||||
from onyx.chat.models import AllCitations
|
||||
from onyx.chat.models import AnswerPostInfo
|
||||
@@ -310,7 +308,6 @@ ChatPacket = (
|
||||
| CustomToolResponse
|
||||
| MessageSpecificCitations
|
||||
| MessageResponseIDInfo
|
||||
| AgenticMessageResponseIDInfo
|
||||
| StreamStopInfo
|
||||
| AgentSearchPacket
|
||||
)
|
||||
@@ -1038,7 +1035,6 @@ def stream_chat_message_objects(
|
||||
next_level = 1
|
||||
prev_message = gen_ai_response_message
|
||||
agent_answers = answer.llm_answer_by_level()
|
||||
agentic_message_ids = []
|
||||
while next_level in agent_answers:
|
||||
next_answer = agent_answers[next_level]
|
||||
info = info_by_subq[
|
||||
@@ -1063,18 +1059,17 @@ def stream_chat_message_objects(
|
||||
refined_answer_improvement=refined_answer_improvement,
|
||||
is_agentic=True,
|
||||
)
|
||||
agentic_message_ids.append(
|
||||
AgentMessageIDInfo(level=next_level, message_id=next_answer_message.id)
|
||||
)
|
||||
next_level += 1
|
||||
prev_message = next_answer_message
|
||||
|
||||
logger.debug("Committing messages")
|
||||
db_session.commit() # actually save user / assistant message
|
||||
|
||||
yield AgenticMessageResponseIDInfo(agentic_message_ids=agentic_message_ids)
|
||||
msg_detail_response = translate_db_message_to_chat_message_detail(
|
||||
gen_ai_response_message
|
||||
)
|
||||
|
||||
yield translate_db_message_to_chat_message_detail(gen_ai_response_message)
|
||||
yield msg_detail_response
|
||||
except Exception as e:
|
||||
error_msg = str(e)
|
||||
logger.exception(error_msg)
|
||||
|
||||
@@ -7,22 +7,15 @@ from typing import Optional
|
||||
|
||||
import boto3 # type: ignore
|
||||
from botocore.client import Config # type: ignore
|
||||
from botocore.exceptions import ClientError
|
||||
from botocore.exceptions import NoCredentialsError
|
||||
from botocore.exceptions import PartialCredentialsError
|
||||
from mypy_boto3_s3 import S3Client # type: ignore
|
||||
|
||||
from onyx.configs.app_configs import INDEX_BATCH_SIZE
|
||||
from onyx.configs.constants import BlobType
|
||||
from onyx.configs.constants import DocumentSource
|
||||
from onyx.connectors.interfaces import ConnectorValidationError
|
||||
from onyx.connectors.interfaces import CredentialExpiredError
|
||||
from onyx.connectors.interfaces import GenerateDocumentsOutput
|
||||
from onyx.connectors.interfaces import InsufficientPermissionsError
|
||||
from onyx.connectors.interfaces import LoadConnector
|
||||
from onyx.connectors.interfaces import PollConnector
|
||||
from onyx.connectors.interfaces import SecondsSinceUnixEpoch
|
||||
from onyx.connectors.interfaces import UnexpectedError
|
||||
from onyx.connectors.models import ConnectorMissingCredentialError
|
||||
from onyx.connectors.models import Document
|
||||
from onyx.connectors.models import Section
|
||||
@@ -247,73 +240,6 @@ class BlobStorageConnector(LoadConnector, PollConnector):
|
||||
|
||||
return None
|
||||
|
||||
def validate_connector_settings(self) -> None:
|
||||
if self.s3_client is None:
|
||||
raise ConnectorMissingCredentialError(
|
||||
"Blob storage credentials not loaded."
|
||||
)
|
||||
|
||||
if not self.bucket_name:
|
||||
raise ConnectorValidationError(
|
||||
"No bucket name was provided in connector settings."
|
||||
)
|
||||
|
||||
try:
|
||||
# We only fetch one object/page as a light-weight validation step.
|
||||
# This ensures we trigger typical S3 permission checks (ListObjectsV2, etc.).
|
||||
self.s3_client.list_objects_v2(
|
||||
Bucket=self.bucket_name, Prefix=self.prefix, MaxKeys=1
|
||||
)
|
||||
|
||||
except NoCredentialsError:
|
||||
raise ConnectorMissingCredentialError(
|
||||
"No valid blob storage credentials found or provided to boto3."
|
||||
)
|
||||
except PartialCredentialsError:
|
||||
raise ConnectorMissingCredentialError(
|
||||
"Partial or incomplete blob storage credentials provided to boto3."
|
||||
)
|
||||
except ClientError as e:
|
||||
error_code = e.response["Error"].get("Code", "")
|
||||
status_code = e.response["ResponseMetadata"].get("HTTPStatusCode")
|
||||
|
||||
# Most common S3 error cases
|
||||
if error_code in [
|
||||
"AccessDenied",
|
||||
"InvalidAccessKeyId",
|
||||
"SignatureDoesNotMatch",
|
||||
]:
|
||||
if status_code == 403 or error_code == "AccessDenied":
|
||||
raise InsufficientPermissionsError(
|
||||
f"Insufficient permissions to list objects in bucket '{self.bucket_name}'. "
|
||||
"Please check your bucket policy and/or IAM policy."
|
||||
)
|
||||
if status_code == 401 or error_code == "SignatureDoesNotMatch":
|
||||
raise CredentialExpiredError(
|
||||
"Provided blob storage credentials appear invalid or expired."
|
||||
)
|
||||
|
||||
raise CredentialExpiredError(
|
||||
f"Credential issue encountered ({error_code})."
|
||||
)
|
||||
|
||||
if error_code == "NoSuchBucket" or status_code == 404:
|
||||
raise ConnectorValidationError(
|
||||
f"Bucket '{self.bucket_name}' does not exist or cannot be found."
|
||||
)
|
||||
|
||||
raise ConnectorValidationError(
|
||||
f"Unexpected S3 client error (code={error_code}, status={status_code}): {e}"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
# Catch-all for anything not captured by the above
|
||||
# Since we are unsure of the error and it may not disable the connector,
|
||||
# raise an unexpected error (does not disable connector)
|
||||
raise UnexpectedError(
|
||||
f"Unexpected error during blob storage settings validation: {e}"
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
credentials_dict = {
|
||||
|
||||
@@ -195,15 +195,10 @@ def validate_ccpair_for_user(
|
||||
db_session,
|
||||
get_editable=False,
|
||||
)
|
||||
|
||||
if not connector:
|
||||
raise ValueError("Connector not found")
|
||||
|
||||
if connector.source == DocumentSource.INGESTION_API:
|
||||
return
|
||||
|
||||
if not credential:
|
||||
raise ValueError("Credential not found")
|
||||
if not connector:
|
||||
raise ValueError("Connector not found")
|
||||
|
||||
try:
|
||||
runnable_connector = instantiate_connector(
|
||||
|
||||
@@ -87,18 +87,16 @@ class HubSpotConnector(LoadConnector, PollConnector):
|
||||
contact = api_client.crm.contacts.basic_api.get_by_id(
|
||||
contact_id=contact.id
|
||||
)
|
||||
email = contact.properties.get("email")
|
||||
if email is not None:
|
||||
associated_emails.append(email)
|
||||
associated_emails.append(contact.properties["email"])
|
||||
|
||||
if notes:
|
||||
for note in notes.results:
|
||||
note = api_client.crm.objects.notes.basic_api.get_by_id(
|
||||
note_id=note.id, properties=["content", "hs_body_preview"]
|
||||
)
|
||||
preview = note.properties.get("hs_body_preview")
|
||||
if preview is not None:
|
||||
associated_notes.append(preview)
|
||||
if note.properties["hs_body_preview"] is None:
|
||||
continue
|
||||
associated_notes.append(note.properties["hs_body_preview"])
|
||||
|
||||
associated_emails_str = " ,".join(associated_emails)
|
||||
associated_notes_str = " ".join(associated_notes)
|
||||
|
||||
@@ -20,13 +20,9 @@ from onyx.configs.app_configs import INDEX_BATCH_SIZE
|
||||
from onyx.configs.constants import DocumentSource
|
||||
from onyx.connectors.interfaces import CheckpointConnector
|
||||
from onyx.connectors.interfaces import CheckpointOutput
|
||||
from onyx.connectors.interfaces import ConnectorValidationError
|
||||
from onyx.connectors.interfaces import CredentialExpiredError
|
||||
from onyx.connectors.interfaces import GenerateSlimDocumentOutput
|
||||
from onyx.connectors.interfaces import InsufficientPermissionsError
|
||||
from onyx.connectors.interfaces import SecondsSinceUnixEpoch
|
||||
from onyx.connectors.interfaces import SlimConnector
|
||||
from onyx.connectors.interfaces import UnexpectedError
|
||||
from onyx.connectors.models import BasicExpertInfo
|
||||
from onyx.connectors.models import ConnectorCheckpoint
|
||||
from onyx.connectors.models import ConnectorFailure
|
||||
@@ -670,56 +666,6 @@ class SlackConnector(SlimConnector, CheckpointConnector):
|
||||
)
|
||||
return checkpoint
|
||||
|
||||
def validate_connector_settings(self) -> None:
|
||||
if self.client is None:
|
||||
raise ConnectorMissingCredentialError("Slack credentials not loaded.")
|
||||
|
||||
try:
|
||||
# Minimal API call to confirm we can list channels
|
||||
# We set limit=1 for a lightweight check
|
||||
response = self.client.conversations_list(limit=1, types=["public_channel"])
|
||||
# Just ensure Slack responded "ok: True"
|
||||
if not response.get("ok", False):
|
||||
error_msg = response.get("error", "Unknown error from Slack")
|
||||
if error_msg == "invalid_auth":
|
||||
raise ConnectorValidationError(
|
||||
f"Invalid or expired Slack bot token ({error_msg})."
|
||||
)
|
||||
elif error_msg == "not_authed":
|
||||
raise CredentialExpiredError(
|
||||
f"Invalid or expired Slack bot token ({error_msg})."
|
||||
)
|
||||
raise UnexpectedError(f"Slack API returned a failure: {error_msg}")
|
||||
|
||||
except SlackApiError as e:
|
||||
slack_error = e.response.get("error", "")
|
||||
if slack_error == "missing_scope":
|
||||
# The needed scope is typically "channels:read" or "groups:read"
|
||||
# for viewing channels. The error message might also contain the
|
||||
# specific scope needed vs. provided.
|
||||
raise InsufficientPermissionsError(
|
||||
"Slack bot token lacks the necessary scope to list channels. "
|
||||
"Please ensure your Slack app has 'channels:read' (or 'groups:read' for private channels) enabled."
|
||||
)
|
||||
elif slack_error == "invalid_auth":
|
||||
raise CredentialExpiredError(
|
||||
f"Invalid or expired Slack bot token ({slack_error})."
|
||||
)
|
||||
elif slack_error == "not_authed":
|
||||
raise CredentialExpiredError(
|
||||
f"Invalid or expired Slack bot token ({slack_error})."
|
||||
)
|
||||
else:
|
||||
# Generic Slack error
|
||||
raise UnexpectedError(
|
||||
f"Unexpected Slack error '{slack_error}' during settings validation."
|
||||
)
|
||||
except Exception as e:
|
||||
# Catch-all for unexpected exceptions
|
||||
raise UnexpectedError(
|
||||
f"Unexpected error during Slack settings validation: {e}"
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import os
|
||||
|
||||
@@ -5,7 +5,6 @@ from typing import Any
|
||||
|
||||
import msal # type: ignore
|
||||
from office365.graph_client import GraphClient # type: ignore
|
||||
from office365.runtime.client_request_exception import ClientRequestException # type: ignore
|
||||
from office365.teams.channels.channel import Channel # type: ignore
|
||||
from office365.teams.chats.messages.message import ChatMessage # type: ignore
|
||||
from office365.teams.team import Team # type: ignore
|
||||
@@ -13,14 +12,10 @@ from office365.teams.team import Team # type: ignore
|
||||
from onyx.configs.app_configs import INDEX_BATCH_SIZE
|
||||
from onyx.configs.constants import DocumentSource
|
||||
from onyx.connectors.cross_connector_utils.miscellaneous_utils import time_str_to_utc
|
||||
from onyx.connectors.interfaces import ConnectorValidationError
|
||||
from onyx.connectors.interfaces import CredentialExpiredError
|
||||
from onyx.connectors.interfaces import GenerateDocumentsOutput
|
||||
from onyx.connectors.interfaces import InsufficientPermissionsError
|
||||
from onyx.connectors.interfaces import LoadConnector
|
||||
from onyx.connectors.interfaces import PollConnector
|
||||
from onyx.connectors.interfaces import SecondsSinceUnixEpoch
|
||||
from onyx.connectors.interfaces import UnexpectedError
|
||||
from onyx.connectors.models import BasicExpertInfo
|
||||
from onyx.connectors.models import ConnectorMissingCredentialError
|
||||
from onyx.connectors.models import Document
|
||||
@@ -284,64 +279,6 @@ class TeamsConnector(LoadConnector, PollConnector):
|
||||
end_datetime = datetime.fromtimestamp(end, timezone.utc)
|
||||
return self._fetch_from_teams(start=start_datetime, end=end_datetime)
|
||||
|
||||
def validate_connector_settings(self) -> None:
|
||||
"""
|
||||
Validate that we can connect to Microsoft Teams with the provided MSAL/Graph credentials
|
||||
and that we can see at least one Team. If the user has specified a list of Teams by name,
|
||||
confirm at least one of them is found.
|
||||
|
||||
Raises:
|
||||
ConnectorMissingCredentialError: If the Graph client is not yet set (missing credentials).
|
||||
CredentialExpiredError: If credentials appear invalid/expired (e.g. 401 Unauthorized).
|
||||
InsufficientPermissionsError: If the app lacks required permissions to read Teams.
|
||||
ConnectorValidationError: If no Teams are found, or if requested Teams are not found.
|
||||
"""
|
||||
if self.graph_client is None:
|
||||
raise ConnectorMissingCredentialError("Teams credentials not loaded.")
|
||||
|
||||
try:
|
||||
# Minimal call to confirm we can retrieve Teams
|
||||
found_teams = self._get_all_teams()
|
||||
|
||||
# You may optionally catch the Graph/Office365 request exception if available:
|
||||
except ClientRequestException as e:
|
||||
status_code = e.response.status_code
|
||||
if status_code == 401:
|
||||
raise CredentialExpiredError(
|
||||
"Invalid or expired Microsoft Teams credentials (401 Unauthorized)."
|
||||
)
|
||||
elif status_code == 403:
|
||||
raise InsufficientPermissionsError(
|
||||
"Your app lacks sufficient permissions to read Teams (403 Forbidden)."
|
||||
)
|
||||
else:
|
||||
raise UnexpectedError(f"Unexpected error retrieving teams: {e}")
|
||||
|
||||
except Exception as e:
|
||||
error_str = str(e).lower()
|
||||
if (
|
||||
"unauthorized" in error_str
|
||||
or "401" in error_str
|
||||
or "invalid_grant" in error_str
|
||||
):
|
||||
raise CredentialExpiredError(
|
||||
"Invalid or expired Microsoft Teams credentials."
|
||||
)
|
||||
elif "forbidden" in error_str or "403" in error_str:
|
||||
raise InsufficientPermissionsError(
|
||||
"App lacks required permissions to read from Microsoft Teams."
|
||||
)
|
||||
raise ConnectorValidationError(
|
||||
f"Unexpected error during Teams validation: {e}"
|
||||
)
|
||||
|
||||
# If we get this far, the Graph call succeeded. Check for presence of Teams:
|
||||
if not found_teams:
|
||||
raise ConnectorValidationError(
|
||||
"No Teams found for the given credentials. "
|
||||
"Either there are no Teams in this tenant, or your app does not have permission to view them."
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
connector = TeamsConnector(teams=os.environ["TEAMS"].split(","))
|
||||
|
||||
@@ -440,10 +440,7 @@ class WebConnector(LoadConnector):
|
||||
"No URL configured. Please provide at least one valid URL."
|
||||
)
|
||||
|
||||
if (
|
||||
self.web_connector_type == WEB_CONNECTOR_VALID_SETTINGS.SITEMAP.value
|
||||
or self.web_connector_type == WEB_CONNECTOR_VALID_SETTINGS.RECURSIVE.value
|
||||
):
|
||||
if self.web_connector_type == WEB_CONNECTOR_VALID_SETTINGS.SITEMAP.value:
|
||||
return None
|
||||
|
||||
# We'll just test the first URL for connectivity and correctness
|
||||
|
||||
@@ -23,7 +23,6 @@ class PreviousMessage(BaseModel):
|
||||
message_type: MessageType
|
||||
files: list[InMemoryChatFile]
|
||||
tool_call: ToolCallFinalResult | None
|
||||
refined_answer_improvement: bool | None
|
||||
|
||||
@classmethod
|
||||
def from_chat_message(
|
||||
@@ -48,7 +47,6 @@ class PreviousMessage(BaseModel):
|
||||
)
|
||||
if chat_message.tool_call
|
||||
else None,
|
||||
refined_answer_improvement=chat_message.refined_answer_improvement,
|
||||
)
|
||||
|
||||
def to_langchain_msg(self) -> BaseMessage:
|
||||
|
||||
@@ -45,7 +45,7 @@ class Settings(BaseModel):
|
||||
gpu_enabled: bool | None = None
|
||||
application_status: ApplicationStatus = ApplicationStatus.ACTIVE
|
||||
anonymous_user_enabled: bool | None = None
|
||||
pro_search_enabled: bool | None = None
|
||||
pro_search_disabled: bool | None = None
|
||||
|
||||
temperature_override_enabled: bool = False
|
||||
auto_scroll: bool = False
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
cohere==5.6.1
|
||||
posthog==3.7.4
|
||||
python3-saml==1.15.0
|
||||
xmlsec==1.3.14
|
||||
|
||||
@@ -4,24 +4,6 @@ log_format custom_main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for" '
|
||||
'rt=$request_time';
|
||||
|
||||
# Map X-Forwarded-Proto or fallback to $scheme
|
||||
map $http_x_forwarded_proto $forwarded_proto {
|
||||
default $http_x_forwarded_proto;
|
||||
"" $scheme;
|
||||
}
|
||||
|
||||
# Map X-Forwarded-Host or fallback to $host
|
||||
map $http_x_forwarded_host $forwarded_host {
|
||||
default $http_x_forwarded_host;
|
||||
"" $host;
|
||||
}
|
||||
|
||||
# Map X-Forwarded-Port or fallback to server port
|
||||
map $http_x_forwarded_port $forwarded_port {
|
||||
default $http_x_forwarded_port;
|
||||
"" $server_port;
|
||||
}
|
||||
|
||||
upstream api_server {
|
||||
# fail_timeout=0 means we always retry an upstream even if it failed
|
||||
# to return a good HTTP response
|
||||
@@ -39,7 +21,8 @@ upstream web_server {
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen 80;
|
||||
server_name ${DOMAIN};
|
||||
|
||||
client_max_body_size 5G; # Maximum upload size
|
||||
|
||||
@@ -53,9 +36,8 @@ server {
|
||||
# misc headers
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $forwarded_proto;
|
||||
proxy_set_header X-Forwarded-Host $forwarded_host;
|
||||
proxy_set_header X-Forwarded-Port $forwarded_port;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header Host $host;
|
||||
|
||||
# need to use 1.1 to support chunked transfers
|
||||
@@ -72,9 +54,8 @@ server {
|
||||
# misc headers
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $forwarded_proto;
|
||||
proxy_set_header X-Forwarded-Host $forwarded_host;
|
||||
proxy_set_header X-Forwarded-Port $forwarded_port;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header Host $host;
|
||||
|
||||
proxy_http_version 1.1;
|
||||
@@ -91,25 +72,14 @@ server {
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl default_server;
|
||||
listen 443 ssl;
|
||||
server_name ${DOMAIN};
|
||||
|
||||
client_max_body_size 5G; # Maximum upload size
|
||||
|
||||
location / {
|
||||
# misc headers
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
# don't use forwarded schema, host, or port here - this is the entry point
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Port $server_port;
|
||||
proxy_set_header Host $host;
|
||||
|
||||
proxy_http_version 1.1;
|
||||
proxy_buffering off;
|
||||
# we don't want nginx trying to do something clever with
|
||||
# redirects, we set the Host: header above already.
|
||||
proxy_redirect off;
|
||||
proxy_pass http://localhost:80;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,8 @@ upstream web_server {
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen 80;
|
||||
server_name ${DOMAIN};
|
||||
|
||||
client_max_body_size 5G; # Maximum upload size
|
||||
|
||||
@@ -36,8 +37,7 @@ server {
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Port $server_port;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header Host $host;
|
||||
|
||||
# need to use 1.1 to support chunked transfers
|
||||
@@ -55,8 +55,7 @@ server {
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Port $server_port;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header Host $host;
|
||||
|
||||
proxy_http_version 1.1;
|
||||
|
||||
@@ -4,24 +4,6 @@ log_format custom_main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for" '
|
||||
'rt=$request_time';
|
||||
|
||||
# Map X-Forwarded-Proto or fallback to $scheme
|
||||
map $http_x_forwarded_proto $forwarded_proto {
|
||||
default $http_x_forwarded_proto;
|
||||
"" $scheme;
|
||||
}
|
||||
|
||||
# Map X-Forwarded-Host or fallback to $host
|
||||
map $http_x_forwarded_host $forwarded_host {
|
||||
default $http_x_forwarded_host;
|
||||
"" $host;
|
||||
}
|
||||
|
||||
# Map X-Forwarded-Port or fallback to server port
|
||||
map $http_x_forwarded_port $forwarded_port {
|
||||
default $http_x_forwarded_port;
|
||||
"" $server_port;
|
||||
}
|
||||
|
||||
upstream api_server {
|
||||
# fail_timeout=0 means we always retry an upstream even if it failed
|
||||
# to return a good HTTP response
|
||||
@@ -39,7 +21,8 @@ upstream web_server {
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen 80;
|
||||
server_name ${DOMAIN};
|
||||
|
||||
client_max_body_size 5G; # Maximum upload size
|
||||
|
||||
@@ -53,9 +36,8 @@ server {
|
||||
# misc headers
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $forwarded_proto;
|
||||
proxy_set_header X-Forwarded-Host $forwarded_host;
|
||||
proxy_set_header X-Forwarded-Port $forwarded_port;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header Host $host;
|
||||
|
||||
# need to use 1.1 to support chunked transfers
|
||||
@@ -72,9 +54,8 @@ server {
|
||||
# misc headers
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $forwarded_proto;
|
||||
proxy_set_header X-Forwarded-Host $forwarded_host;
|
||||
proxy_set_header X-Forwarded-Port $forwarded_port;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header Host $host;
|
||||
|
||||
proxy_http_version 1.1;
|
||||
@@ -87,25 +68,14 @@ server {
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl default_server;
|
||||
listen 443 ssl;
|
||||
server_name ${DOMAIN};
|
||||
|
||||
client_max_body_size 5G; # Maximum upload size
|
||||
|
||||
location / {
|
||||
# misc headers
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
# don't use forwarded schema, host, or port here - this is the entry point
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Port $server_port;
|
||||
proxy_set_header Host $host;
|
||||
|
||||
proxy_http_version 1.1;
|
||||
proxy_buffering off;
|
||||
# we don't want nginx trying to do something clever with
|
||||
# redirects, we set the Host: header above already.
|
||||
proxy_redirect off;
|
||||
proxy_pass http://localhost:80;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# fill in the template
|
||||
envsubst '$SSL_CERT_FILE_NAME $SSL_CERT_KEY_FILE_NAME' < "/etc/nginx/conf.d/$1" > /etc/nginx/conf.d/app.conf
|
||||
envsubst '$DOMAIN $SSL_CERT_FILE_NAME $SSL_CERT_KEY_FILE_NAME' < "/etc/nginx/conf.d/$1" > /etc/nginx/conf.d/app.conf
|
||||
|
||||
# wait for the api_server to be ready
|
||||
echo "Waiting for API server to boot up; this may take a minute or two..."
|
||||
|
||||
@@ -240,11 +240,11 @@ export function SettingsForm() {
|
||||
/>
|
||||
|
||||
<Checkbox
|
||||
label="Agent Search"
|
||||
sublabel="If set, users will be able to use Agent Search."
|
||||
checked={settings.pro_search_enabled ?? true}
|
||||
label="Pro Search Disabled"
|
||||
sublabel="If set, users will not be able to use Pro Search."
|
||||
checked={settings.pro_search_disabled ?? false}
|
||||
onChange={(e) =>
|
||||
handleToggleSettingsField("pro_search_enabled", e.target.checked)
|
||||
handleToggleSettingsField("pro_search_disabled", e.target.checked)
|
||||
}
|
||||
/>
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ export interface Settings {
|
||||
notifications: Notification[];
|
||||
needs_reindexing: boolean;
|
||||
gpu_enabled: boolean;
|
||||
pro_search_enabled: boolean | null;
|
||||
pro_search_disabled: boolean | null;
|
||||
application_status: ApplicationStatus;
|
||||
auto_scroll: boolean;
|
||||
temperature_override_enabled: boolean;
|
||||
|
||||
@@ -23,7 +23,6 @@ import {
|
||||
SubQuestionDetail,
|
||||
constructSubQuestions,
|
||||
DocumentsResponse,
|
||||
AgenticMessageResponseIDInfo,
|
||||
} from "./interfaces";
|
||||
|
||||
import Prism from "prismjs";
|
||||
@@ -1281,8 +1280,6 @@ export function ChatPage({
|
||||
let toolCall: ToolCallMetadata | null = null;
|
||||
let isImprovement: boolean | undefined = undefined;
|
||||
let isStreamingQuestions = true;
|
||||
let includeAgentic = false;
|
||||
let secondLevelMessageId: number | null = null;
|
||||
|
||||
let initialFetchDetails: null | {
|
||||
user_message_id: number;
|
||||
@@ -1339,7 +1336,7 @@ export function ChatPage({
|
||||
searchParams.get(SEARCH_PARAM_NAMES.SYSTEM_PROMPT) || undefined,
|
||||
useExistingUserMessage: isSeededChat,
|
||||
useLanggraph:
|
||||
settings?.settings.pro_search_enabled &&
|
||||
!settings?.settings.pro_search_disabled &&
|
||||
proSearchEnabled &&
|
||||
retrievalEnabled,
|
||||
});
|
||||
@@ -1420,17 +1417,6 @@ export function ChatPage({
|
||||
resetRegenerationState();
|
||||
} else {
|
||||
const { user_message_id, frozenMessageMap } = initialFetchDetails;
|
||||
if (Object.hasOwn(packet, "agentic_message_ids")) {
|
||||
const agenticMessageIds = (packet as AgenticMessageResponseIDInfo)
|
||||
.agentic_message_ids;
|
||||
const level1MessageId = agenticMessageIds.find(
|
||||
(item) => item.level === 1
|
||||
)?.message_id;
|
||||
if (level1MessageId) {
|
||||
secondLevelMessageId = level1MessageId;
|
||||
includeAgentic = true;
|
||||
}
|
||||
}
|
||||
|
||||
setChatState((prevState) => {
|
||||
if (prevState.get(chatSessionIdRef.current!) === "loading") {
|
||||
@@ -1582,10 +1568,7 @@ export function ChatPage({
|
||||
};
|
||||
}
|
||||
);
|
||||
} else if (
|
||||
Object.hasOwn(packet, "error") &&
|
||||
(packet as any).error != null
|
||||
) {
|
||||
} else if (Object.hasOwn(packet, "error")) {
|
||||
if (
|
||||
sub_questions.length > 0 &&
|
||||
sub_questions
|
||||
@@ -1597,8 +1580,8 @@ export function ChatPage({
|
||||
setAgenticGenerating(false);
|
||||
setAlternativeGeneratingAssistant(null);
|
||||
setSubmittedMessage("");
|
||||
|
||||
throw new Error((packet as StreamingError).error);
|
||||
return;
|
||||
// throw new Error((packet as StreamingError).error);
|
||||
} else {
|
||||
error = (packet as StreamingError).error;
|
||||
stackTrace = (packet as StreamingError).stack_trace;
|
||||
@@ -1681,19 +1664,6 @@ export function ChatPage({
|
||||
second_level_generating: second_level_generating,
|
||||
agentic_docs: agenticDocs,
|
||||
},
|
||||
...(includeAgentic
|
||||
? [
|
||||
{
|
||||
messageId: secondLevelMessageId!,
|
||||
message: second_level_answer,
|
||||
type: "assistant" as const,
|
||||
files: [],
|
||||
toolCall: null,
|
||||
parentMessageId:
|
||||
initialFetchDetails.assistant_message_id!,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -2722,11 +2692,6 @@ export function ChatPage({
|
||||
? messageHistory[i + 1]?.documents
|
||||
: undefined;
|
||||
|
||||
const nextMessage =
|
||||
messageHistory[i + 1]?.type === "assistant"
|
||||
? messageHistory[i + 1]
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<div
|
||||
className="text-text"
|
||||
@@ -2755,10 +2720,7 @@ export function ChatPage({
|
||||
selectedMessageForDocDisplay ==
|
||||
secondLevelMessage?.messageId)
|
||||
}
|
||||
isImprovement={
|
||||
message.isImprovement ||
|
||||
nextMessage?.isImprovement
|
||||
}
|
||||
isImprovement={message.isImprovement}
|
||||
secondLevelGenerating={
|
||||
(message.second_level_generating &&
|
||||
currentSessionChatState !==
|
||||
|
||||
@@ -805,12 +805,13 @@ export function ChatInputBar({
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center my-auto">
|
||||
{retrievalEnabled && settings?.settings.pro_search_enabled && (
|
||||
<AgenticToggle
|
||||
proSearchEnabled={proSearchEnabled}
|
||||
setProSearchEnabled={setProSearchEnabled}
|
||||
/>
|
||||
)}
|
||||
{retrievalEnabled &&
|
||||
!settings?.settings.pro_search_disabled && (
|
||||
<AgenticToggle
|
||||
proSearchEnabled={proSearchEnabled}
|
||||
setProSearchEnabled={setProSearchEnabled}
|
||||
/>
|
||||
)}
|
||||
<button
|
||||
id="onyx-chat-input-send-button"
|
||||
className={`cursor-pointer ${
|
||||
|
||||
@@ -155,15 +155,6 @@ export interface MessageResponseIDInfo {
|
||||
reserved_assistant_message_id: number;
|
||||
}
|
||||
|
||||
export interface AgentMessageIDInfo {
|
||||
level: number;
|
||||
message_id: number;
|
||||
}
|
||||
|
||||
export interface AgenticMessageResponseIDInfo {
|
||||
agentic_message_ids: AgentMessageIDInfo[];
|
||||
}
|
||||
|
||||
export interface DocumentsResponse {
|
||||
top_documents: OnyxDocument[];
|
||||
rephrased_query: string | null;
|
||||
|
||||
@@ -25,7 +25,6 @@ import {
|
||||
RetrievalType,
|
||||
StreamingError,
|
||||
ToolCallMetadata,
|
||||
AgenticMessageResponseIDInfo,
|
||||
} from "./interfaces";
|
||||
import { Persona } from "../admin/assistants/interfaces";
|
||||
import { ReadonlyURLSearchParams } from "next/navigation";
|
||||
@@ -155,8 +154,7 @@ export type PacketType =
|
||||
| AgentAnswerPiece
|
||||
| SubQuestionPiece
|
||||
| ExtendedToolResponse
|
||||
| RefinedAnswerImprovement
|
||||
| AgenticMessageResponseIDInfo;
|
||||
| RefinedAnswerImprovement;
|
||||
|
||||
export async function* sendMessage({
|
||||
regenerate,
|
||||
|
||||
@@ -21,9 +21,11 @@ import { fetchAssistantData } from "@/lib/chat/fetchAssistantdata";
|
||||
import { AppProvider } from "@/components/context/AppProvider";
|
||||
import { PHProvider } from "./providers";
|
||||
import { getCurrentUserSS } from "@/lib/userSS";
|
||||
import CardSection from "@/components/admin/CardSection";
|
||||
import { Suspense } from "react";
|
||||
import PostHogPageView from "./PostHogPageView";
|
||||
import Script from "next/script";
|
||||
import { LogoType } from "@/components/logo/Logo";
|
||||
import { Hanken_Grotesk } from "next/font/google";
|
||||
import { WebVitals } from "./web-vitals";
|
||||
import { ThemeProvider } from "next-themes";
|
||||
|
||||
@@ -51,7 +51,7 @@ export async function fetchSettingsSS(): Promise<CombinedSettings | null> {
|
||||
notifications: [],
|
||||
needs_reindexing: false,
|
||||
anonymous_user_enabled: false,
|
||||
pro_search_enabled: true,
|
||||
pro_search_disabled: false,
|
||||
temperature_override_enabled: true,
|
||||
};
|
||||
} else {
|
||||
@@ -95,8 +95,8 @@ export async function fetchSettingsSS(): Promise<CombinedSettings | null> {
|
||||
}
|
||||
}
|
||||
|
||||
if (enterpriseSettings && settings.pro_search_enabled == null) {
|
||||
settings.pro_search_enabled = true;
|
||||
if (enterpriseSettings && settings.pro_search_disabled == null) {
|
||||
settings.pro_search_disabled = true;
|
||||
}
|
||||
|
||||
const webVersion = getWebVersion();
|
||||
|
||||
Reference in New Issue
Block a user