Skip to content

Commit

Permalink
Merge branch 'danswer-ai:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
colachg authored Mar 4, 2024
2 parents 7067924 + 563df1f commit c5c83e0
Show file tree
Hide file tree
Showing 28 changed files with 670 additions and 266 deletions.
31 changes: 31 additions & 0 deletions backend/alembic/versions/0a2b51deb0b8_add_starter_prompts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""Add starter prompts
Revision ID: 0a2b51deb0b8
Revises: 5f4b8568a221
Create Date: 2024-03-02 23:23:49.960309
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = "0a2b51deb0b8"
down_revision = "5f4b8568a221"
branch_labels = None
depends_on = None


def upgrade() -> None:
op.add_column(
"persona",
sa.Column(
"starter_messages",
postgresql.JSONB(astext_type=sa.Text()),
nullable=True,
),
)


def downgrade() -> None:
op.drop_column("persona", "starter_messages")
1 change: 1 addition & 0 deletions backend/danswer/chat/load_yamls.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ def load_personas_from_yaml(
if persona.get("num_chunks") is not None
else default_chunks,
llm_relevance_filter=persona.get("llm_relevance_filter"),
starter_messages=persona.get("starter_messages"),
llm_filter_extraction=persona.get("llm_filter_extraction"),
llm_model_version_override=None,
recency_bias=RecencyBiasSetting(persona["recency_bias"]),
Expand Down
4 changes: 3 additions & 1 deletion backend/danswer/configs/app_configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
# User Facing Features Configs
#####
BLURB_SIZE = 128 # Number Encoder Tokens included in the chunk blurb
GENERATIVE_MODEL_ACCESS_CHECK_FREQ = 86400 # 1 day
GENERATIVE_MODEL_ACCESS_CHECK_FREQ = int(
os.environ.get("GENERATIVE_MODEL_ACCESS_CHECK_FREQ") or 86400
) # 1 day
DISABLE_GENERATIVE_AI = os.environ.get("DISABLE_GENERATIVE_AI", "").lower() == "true"


Expand Down
3 changes: 3 additions & 0 deletions backend/danswer/configs/chat_configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
DISABLE_LLM_CHOOSE_SEARCH = (
os.environ.get("DISABLE_LLM_CHOOSE_SEARCH", "").lower() == "true"
)
DISABLE_LLM_QUERY_REPHRASE = (
os.environ.get("DISABLE_LLM_QUERY_REPHRASE", "").lower() == "true"
)
# 1 edit per 20 characters, currently unused due to fuzzy match being too slow
QUOTE_ALLOWED_ERROR_PERCENT = 0.05
QA_TIMEOUT = int(os.environ.get("QA_TIMEOUT") or "60") # 60 seconds
Expand Down
4 changes: 4 additions & 0 deletions backend/danswer/db/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from danswer.db.models import Prompt
from danswer.db.models import SearchDoc
from danswer.db.models import SearchDoc as DBSearchDoc
from danswer.db.models import StarterMessage
from danswer.search.models import RecencyBiasSetting
from danswer.search.models import RetrievalDocs
from danswer.search.models import SavedSearchDoc
Expand Down Expand Up @@ -465,6 +466,7 @@ def upsert_persona(
prompts: list[Prompt] | None,
document_sets: list[DBDocumentSet] | None,
llm_model_version_override: str | None,
starter_messages: list[StarterMessage] | None,
shared: bool,
db_session: Session,
persona_id: int | None = None,
Expand All @@ -490,6 +492,7 @@ def upsert_persona(
persona.recency_bias = recency_bias
persona.default_persona = default_persona
persona.llm_model_version_override = llm_model_version_override
persona.starter_messages = starter_messages
persona.deleted = False # Un-delete if previously deleted

# Do not delete any associations manually added unless
Expand All @@ -516,6 +519,7 @@ def upsert_persona(
prompts=prompts or [],
document_sets=document_sets or [],
llm_model_version_override=llm_model_version_override,
starter_messages=starter_messages,
)
db_session.add(persona)

Expand Down
12 changes: 12 additions & 0 deletions backend/danswer/db/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,15 @@ class Prompt(Base):
)


class StarterMessage(TypedDict):
"""NOTE: is a `TypedDict` so it can be used as a type hint for a JSONB column
in Postgres"""

name: str
description: str
message: str


class Persona(Base):
__tablename__ = "persona"

Expand Down Expand Up @@ -744,6 +753,9 @@ class Persona(Base):
llm_model_version_override: Mapped[str | None] = mapped_column(
String, nullable=True
)
starter_messages: Mapped[list[StarterMessage] | None] = mapped_column(
postgresql.JSONB(), nullable=True
)
# Default personas are configured via backend during deployment
# Treated specially (cannot be user edited etc.)
default_persona: Mapped[bool] = mapped_column(Boolean, default=False)
Expand Down
1 change: 1 addition & 0 deletions backend/danswer/db/slack_bot_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ def create_slack_bot_persona(
prompts=None,
document_sets=document_sets,
llm_model_version_override=None,
starter_messages=None,
shared=True,
default_persona=False,
db_session=db_session,
Expand Down
6 changes: 5 additions & 1 deletion backend/danswer/llm/chat_llm.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,11 @@ def __init__(
max_tokens=max_output_tokens,
temperature=temperature,
request_timeout=timeout,
model_kwargs=DefaultMultiLLM.DEFAULT_MODEL_PARAMS,
# LiteLLM and some model providers don't handle these params well
# only turning it on for OpenAI
model_kwargs=DefaultMultiLLM.DEFAULT_MODEL_PARAMS
if model_provider == "openai"
else {},
verbose=should_be_verbose(),
max_retries=0, # retries are handled outside of langchain
)
Expand Down
5 changes: 5 additions & 0 deletions backend/danswer/secondary_llm_flows/query_expansion.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from typing import cast

from danswer.chat.chat_utils import combine_message_chain
from danswer.configs.chat_configs import DISABLE_LLM_QUERY_REPHRASE
from danswer.configs.model_configs import GEN_AI_HISTORY_CUTOFF
from danswer.db.models import ChatMessage
from danswer.llm.exceptions import GenAIDisabledException
Expand Down Expand Up @@ -95,6 +96,10 @@ def history_based_query_rephrase(
) -> str:
user_query = cast(str, query_message.message)

# Globally disabled, just use the exact user query
if DISABLE_LLM_QUERY_REPHRASE:
return user_query

if not user_query:
raise ValueError("Can't rephrase/search an empty query")

Expand Down
1 change: 1 addition & 0 deletions backend/danswer/server/features/persona/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def create_update_persona(
prompts=prompts,
document_sets=document_sets,
llm_model_version_override=create_persona_request.llm_model_version_override,
starter_messages=create_persona_request.starter_messages,
shared=create_persona_request.shared,
db_session=db_session,
)
Expand Down
4 changes: 4 additions & 0 deletions backend/danswer/server/features/persona/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from pydantic import BaseModel

from danswer.db.models import Persona
from danswer.db.models import StarterMessage
from danswer.search.models import RecencyBiasSetting
from danswer.server.features.document_set.models import DocumentSet
from danswer.server.features.prompt.models import PromptSnapshot
Expand All @@ -17,6 +18,7 @@ class CreatePersonaRequest(BaseModel):
prompt_ids: list[int]
document_set_ids: list[int]
llm_model_version_override: str | None = None
starter_messages: list[StarterMessage] | None = None


class PersonaSnapshot(BaseModel):
Expand All @@ -30,6 +32,7 @@ class PersonaSnapshot(BaseModel):
llm_relevance_filter: bool
llm_filter_extraction: bool
llm_model_version_override: str | None
starter_messages: list[StarterMessage] | None
default_persona: bool
prompts: list[PromptSnapshot]
document_sets: list[DocumentSet]
Expand All @@ -50,6 +53,7 @@ def from_model(cls, persona: Persona) -> "PersonaSnapshot":
llm_relevance_filter=persona.llm_relevance_filter,
llm_filter_extraction=persona.llm_filter_extraction,
llm_model_version_override=persona.llm_model_version_override,
starter_messages=persona.starter_messages,
default_persona=persona.default_persona,
prompts=[PromptSnapshot.from_model(prompt) for prompt in persona.prompts],
document_sets=[
Expand Down
4 changes: 2 additions & 2 deletions backend/danswer/server/manage/administrative.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from sqlalchemy.orm import Session

from danswer.auth.users import current_admin_user
from danswer.configs.app_configs import GENERATIVE_MODEL_ACCESS_CHECK_FREQ
from danswer.configs.constants import GEN_AI_API_KEY_STORAGE_KEY
from danswer.configs.constants import GEN_AI_DETECTED_MODEL
from danswer.configs.model_configs import GEN_AI_MODEL_PROVIDER
Expand Down Expand Up @@ -170,8 +171,7 @@ def validate_existing_genai_api_key(
last_check = datetime.fromtimestamp(
cast(float, kv_store.load(GEN_AI_KEY_CHECK_TIME)), tz=timezone.utc
)
# GENERATIVE_MODEL_ACCESS_CHECK_FREQ
check_freq_sec = timedelta(seconds=1)
check_freq_sec = timedelta(seconds=GENERATIVE_MODEL_ACCESS_CHECK_FREQ)
if curr_time - last_check < check_freq_sec:
return
except ConfigNotFoundError:
Expand Down
8 changes: 8 additions & 0 deletions deployment/docker_compose/docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ services:
- DISABLE_LLM_FILTER_EXTRACTION=${DISABLE_LLM_FILTER_EXTRACTION:-}
- DISABLE_LLM_CHUNK_FILTER=${DISABLE_LLM_CHUNK_FILTER:-}
- DISABLE_LLM_CHOOSE_SEARCH=${DISABLE_LLM_CHOOSE_SEARCH:-}
- DISABLE_LLM_QUERY_REPHRASE=${DISABLE_LLM_QUERY_REPHRASE:-}
- DISABLE_GENERATIVE_AI=${DISABLE_GENERATIVE_AI:-}
# Query Options
- DOC_TIME_DECAY=${DOC_TIME_DECAY:-} # Recency Bias for search results, decay at 1 / (1 + DOC_TIME_DECAY * x years)
Expand Down Expand Up @@ -76,6 +77,8 @@ services:
- model_cache_torch:/root/.cache/torch/
- model_cache_nltk:/root/nltk_data/
- model_cache_huggingface:/root/.cache/huggingface/
extra_hosts:
- "host.docker.internal:host-gateway"
logging:
driver: json-file
options:
Expand Down Expand Up @@ -106,7 +109,9 @@ services:
- DISABLE_LLM_FILTER_EXTRACTION=${DISABLE_LLM_FILTER_EXTRACTION:-}
- DISABLE_LLM_CHUNK_FILTER=${DISABLE_LLM_CHUNK_FILTER:-}
- DISABLE_LLM_CHOOSE_SEARCH=${DISABLE_LLM_CHOOSE_SEARCH:-}
- DISABLE_LLM_QUERY_REPHRASE=${DISABLE_LLM_QUERY_REPHRASE:-}
- DISABLE_GENERATIVE_AI=${DISABLE_GENERATIVE_AI:-}
- GENERATIVE_MODEL_ACCESS_CHECK_FREQ=${GENERATIVE_MODEL_ACCESS_CHECK_FREQ:-}
# Query Options
- DOC_TIME_DECAY=${DOC_TIME_DECAY:-} # Recency Bias for search results, decay at 1 / (1 + DOC_TIME_DECAY * x years)
- HYBRID_ALPHA=${HYBRID_ALPHA:-} # Hybrid Search Alpha (0 for entirely keyword, 1 for entirely vector)
Expand Down Expand Up @@ -164,6 +169,8 @@ services:
- model_cache_torch:/root/.cache/torch/
- model_cache_nltk:/root/nltk_data/
- model_cache_huggingface:/root/.cache/huggingface/
extra_hosts:
- "host.docker.internal:host-gateway"
logging:
driver: json-file
options:
Expand All @@ -176,6 +183,7 @@ services:
dockerfile: Dockerfile
args:
- NEXT_PUBLIC_DISABLE_STREAMING=${NEXT_PUBLIC_DISABLE_STREAMING:-false}
- NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA=${NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA:-false}
depends_on:
- api_server
restart: always
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ services:
- model_cache_torch:/root/.cache/torch/
- model_cache_nltk:/root/nltk_data/
- model_cache_huggingface:/root/.cache/huggingface/
extra_hosts:
- "host.docker.internal:host-gateway"
logging:
driver: json-file
options:
Expand Down Expand Up @@ -52,6 +54,8 @@ services:
- model_cache_torch:/root/.cache/torch/
- model_cache_nltk:/root/nltk_data/
- model_cache_huggingface:/root/.cache/huggingface/
extra_hosts:
- "host.docker.internal:host-gateway"
logging:
driver: json-file
options:
Expand All @@ -64,6 +68,7 @@ services:
dockerfile: Dockerfile
args:
- NEXT_PUBLIC_DISABLE_STREAMING=${NEXT_PUBLIC_DISABLE_STREAMING:-false}
- NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA=${NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA:-false}
depends_on:
- api_server
restart: always
Expand Down
5 changes: 5 additions & 0 deletions deployment/docker_compose/docker-compose.prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ services:
- model_cache_torch:/root/.cache/torch/
- model_cache_nltk:/root/nltk_data/
- model_cache_huggingface:/root/.cache/huggingface/
extra_hosts:
- "host.docker.internal:host-gateway"
logging:
driver: json-file
options:
Expand Down Expand Up @@ -52,6 +54,8 @@ services:
- model_cache_torch:/root/.cache/torch/
- model_cache_nltk:/root/nltk_data/
- model_cache_huggingface:/root/.cache/huggingface/
extra_hosts:
- "host.docker.internal:host-gateway"
logging:
driver: json-file
options:
Expand All @@ -64,6 +68,7 @@ services:
dockerfile: Dockerfile
args:
- NEXT_PUBLIC_DISABLE_STREAMING=${NEXT_PUBLIC_DISABLE_STREAMING:-false}
- NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA=${NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA:-false}
depends_on:
- api_server
restart: always
Expand Down
1 change: 1 addition & 0 deletions deployment/kubernetes/env-configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ data:
DISABLE_LLM_FILTER_EXTRACTION: ""
DISABLE_LLM_CHUNK_FILTER: ""
DISABLE_LLM_CHOOSE_SEARCH: ""
DISABLE_LLM_QUERY_REPHRASE: ""
# Query Options
DOC_TIME_DECAY: ""
HYBRID_ALPHA: ""
Expand Down
6 changes: 6 additions & 0 deletions web/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ ENV NEXT_TELEMETRY_DISABLED 1
ARG NEXT_PUBLIC_DISABLE_STREAMING
ENV NEXT_PUBLIC_DISABLE_STREAMING=${NEXT_PUBLIC_DISABLE_STREAMING}

ARG NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA
ENV NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA=${NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA}

RUN npm run build

# Step 3. Production image, copy all the files and run next
Expand Down Expand Up @@ -70,6 +73,9 @@ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
ARG NEXT_PUBLIC_DISABLE_STREAMING
ENV NEXT_PUBLIC_DISABLE_STREAMING=${NEXT_PUBLIC_DISABLE_STREAMING}

ARG NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA
ENV NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA=${NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA}

# Note: Don't expose ports here, Compose will handle that for us if necessary.
# If you want to run this without compose, specify the ports to
# expose via cli
Expand Down
50 changes: 50 additions & 0 deletions web/src/app/admin/personas/HidableSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { useState } from "react";
import { FiChevronDown, FiChevronRight } from "react-icons/fi";

export function SectionHeader({
children,
includeMargin = true,
}: {
children: string | JSX.Element;
includeMargin?: boolean;
}) {
return (
<div
className={"font-bold text-xl my-auto" + (includeMargin ? " mb-4" : "")}
>
{children}
</div>
);
}

export function HidableSection({
children,
sectionTitle,
defaultHidden = false,
}: {
children: string | JSX.Element;
sectionTitle: string | JSX.Element;
defaultHidden?: boolean;
}) {
const [isHidden, setIsHidden] = useState(defaultHidden);

return (
<div>
<div
className="flex hover:bg-hover-light rounded cursor-pointer p-2"
onClick={() => setIsHidden(!isHidden)}
>
<SectionHeader includeMargin={false}>{sectionTitle}</SectionHeader>
<div className="my-auto ml-auto p-1">
{isHidden ? (
<FiChevronRight size={24} />
) : (
<FiChevronDown size={24} />
)}
</div>
</div>

{!isHidden && <div className="mx-2 mt-2">{children}</div>}
</div>
);
}
Loading

0 comments on commit c5c83e0

Please sign in to comment.