Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: collection hierarchy #59

Merged
merged 72 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
2704ad1
feat: question fallback support
karllu3 Jun 20, 2024
01491c2
Add synthatic sugar
karllu3 Jun 20, 2024
594fa4f
polishing
karllu3 Jun 20, 2024
f892125
Merge branch 'main' into lk/fallback_collections
karllu3 Jun 20, 2024
8c43cf6
resolve cyclic import
karllu3 Jun 20, 2024
63b80c6
fix build
karllu3 Jun 20, 2024
839a187
fixups
karllu3 Jun 20, 2024
0334b69
fixups
karllu3 Jun 21, 2024
9fdb5bd
error handling decorator
karllu3 Jun 21, 2024
5a6b0d2
pylint fixups
karllu3 Jun 22, 2024
0b9669e
adjustments
karllu3 Jun 22, 2024
5cb4117
Fallback monitor idea
karllu3 Jun 24, 2024
c864f18
remove fallback monitor
karllu3 Jun 24, 2024
e6f1dbd
decorator clean up
karllu3 Jun 24, 2024
97689a3
add docstrings
karllu3 Jun 24, 2024
ee50bc7
fix docstrings
karllu3 Jun 24, 2024
eddd203
isort fix
karllu3 Jun 24, 2024
d2d7acf
Feat: Implement global event handlers
karllu3 Jun 24, 2024
434e37a
enhancments
karllu3 Jun 25, 2024
c5b5f80
fix linters
karllu3 Jun 25, 2024
e5a808b
global variables moved to module
karllu3 Jun 25, 2024
e1d09c0
event handlers
karllu3 Jun 25, 2024
ae5d838
wrap into singleton
karllu3 Jun 28, 2024
933a696
collection ehnacmentS
karllu3 Jul 1, 2024
200eaf1
singleton remove
karllu3 Jul 1, 2024
aa3ea91
fixups
karllu3 Jul 1, 2024
0f7a20a
fixups
karllu3 Jul 1, 2024
f654d84
fixups
karllu3 Jul 1, 2024
25cc476
Merge branch 'main' into lk/fallback_collections
karllu3 Jul 1, 2024
0127597
Merge branch 'lk/global_event_handlers' into lk/fallback_collections
karllu3 Jul 1, 2024
7222425
fixups
karllu3 Jul 2, 2024
2c5bbd0
fixups
karllu3 Jul 2, 2024
70141cc
fixup
karllu3 Jul 2, 2024
272a523
fixup
karllu3 Jul 2, 2024
068c345
fixups
karllu3 Jul 2, 2024
d8466ba
global event handlers
karllu3 Jul 2, 2024
18b1637
cirucalr
karllu3 Jul 2, 2024
f30c965
pylint check
karllu3 Jul 2, 2024
d1aa012
fixups
karllu3 Jul 2, 2024
4552d85
comment fixups
karllu3 Jul 2, 2024
db3fc6f
Revert "fixups"
karllu3 Jul 2, 2024
94ab6c7
move create collections to collections
karllu3 Jul 2, 2024
219c52d
pre commit
karllu3 Jul 3, 2024
765f163
adjustments
karllu3 Jul 2, 2024
776a7b4
Merge branch 'lk/global_event_handlers' into lk/fallback_collections
karllu3 Jul 4, 2024
1f0ecbb
review fixups
karllu3 Jul 4, 2024
efdca49
event handler type
karllu3 Jul 4, 2024
2d08917
Remove cyclic with EventHandlers typing
karllu3 Jul 4, 2024
198a3ef
Merge branch 'main' into lk/global_event_handlers
karllu3 Jul 4, 2024
e3b5fd7
chore: doggify project (#67)
mhordynski Jul 2, 2024
63a9487
refactor(prompts): prompt templates (#66)
micpst Jul 2, 2024
ef025ac
feat(llms): add support for HuggingFace models loaded locally (#61)
akotyla Jul 3, 2024
2c3dccb
fix(nl-responder): prevent halucination when no data is returned (#68)
BartMiki Jul 4, 2024
f0c0cba
0.4.0
Jul 4, 2024
5c0db8f
chore: changelog update after v0.4.0
mhordynski Jul 4, 2024
3269137
chore: changelog heading fix
mhordynski Jul 4, 2024
986757a
import adjustments
karllu3 Jul 4, 2024
aa37e86
Merge branch 'lk/global_event_handlers' into lk/fallback_collections
karllu3 Jul 4, 2024
f432b61
chained fallback
karllu3 Jul 4, 2024
6bdbfd4
merge
karllu3 Jul 4, 2024
0570484
collections
karllu3 Jul 5, 2024
d36c939
override global events
karllu3 Jul 5, 2024
bbe933b
MR merge alignment
karllu3 Jul 5, 2024
feed5a8
collection fixups
karllu3 Jul 8, 2024
6465f1e
collection polishing
karllu3 Jul 8, 2024
4c81e39
moving events to print
karllu3 Jul 8, 2024
a088ca3
display improvementS
karllu3 Jul 8, 2024
2fc55fa
documentation update
karllu3 Jul 9, 2024
bc018d3
collection enhancment
karllu3 Jul 15, 2024
22a6d81
Merge branch 'main' into lk/fallback_collections
karllu3 Jul 15, 2024
67b51f3
tests
karllu3 Jul 17, 2024
bdd3c28
review: fallback collections (#75)
mhordynski Jul 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions examples/recruiting/candidates_freeform.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# pylint: disable=missing-return-doc, missing-param-doc, missing-function-docstring
from typing import List

from sqlalchemy import create_engine
from sqlalchemy.ext.automap import automap_base

from dbally.views.freeform.text2sql import BaseText2SQLView, ColumnConfig, TableConfig

engine = create_engine("sqlite:///examples/recruiting/data/candidates.db")

_Base = automap_base()
_Base.prepare(autoload_with=engine)
_Candidate = _Base.classes.candidates


class CandidateFreeformView(BaseText2SQLView):
"""
A view for retrieving candidates from the database.
"""

def get_tables(self) -> List[TableConfig]:
"""
Get the tables used by the view.

Returns:
A list of tables.
"""
return [
TableConfig(
name="candidates",
columns=[
ColumnConfig("name", "TEXT"),
ColumnConfig("country", "TEXT"),
ColumnConfig("years_of_experience", "INTEGER"),
ColumnConfig("position", "TEXT"),
ColumnConfig("university", "TEXT"),
ColumnConfig("skills", "TEXT"),
ColumnConfig("tags", "TEXT"),
ColumnConfig("id", "INTEGER PRIMARY KEY"),
],
),
]
32 changes: 32 additions & 0 deletions examples/visualize_fallback_code.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# pylint: disable=missing-function-docstring
import asyncio

from recruiting import candidate_view_with_similarity_store, candidates_freeform
from recruiting.candidate_view_with_similarity_store import CandidateView, country_similarity
from recruiting.candidates_freeform import CandidateFreeformView
from recruiting.cypher_text2sql_view import SampleText2SQLViewCyphers, create_freeform_memory_engine
from sqlalchemy import create_engine

import dbally
from dbally.audit import CLIEventHandler
from dbally.gradio import create_gradio_interface
from dbally.llms.litellm import LiteLLM

cm_engine = create_engine("postgresql+pg8000://postgres:ikar89pl@localhost:5432/codebase_community")
karllu3 marked this conversation as resolved.
Show resolved Hide resolved


async def main():
await country_similarity.update()
llm = LiteLLM(model_name="gpt-3.5-turbo")
collection1 = dbally.create_collection("candidates", llm, event_handlers=[CLIEventHandler()])
collection2 = dbally.create_collection("freeform candidates", llm, event_handlers=[CLIEventHandler()])
collection1.add(CandidateView, lambda: CandidateView(candidate_view_with_similarity_store.engine))
collection1.add(SampleText2SQLViewCyphers, lambda: SampleText2SQLViewCyphers(create_freeform_memory_engine()))
collection2.add(CandidateFreeformView, lambda: CandidateFreeformView(candidates_freeform.engine))
collection1.add_fallback(collection2)
gradio_interface = await create_gradio_interface(user_collection=collection1)
gradio_interface.launch()


if __name__ == "__main__":
asyncio.run(main())
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ install_requires =
tabulate>=0.9.0
click~=8.1.7
numpy>=1.24.0
StrEnum>=0.4.15
karllu3 marked this conversation as resolved.
Show resolved Hide resolved

[options.extras_require]
litellm =
Expand Down
3 changes: 3 additions & 0 deletions src/dbally/_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ def create_collection(
event_handlers: Optional[List[EventHandler]] = None,
view_selector: Optional[ViewSelector] = None,
nl_responder: Optional[NLResponder] = None,
fallback_collection: Optional[Collection] = None,
) -> Collection:
"""
Create a new [Collection](collection.md) that is a container for registering views and the\
Expand Down Expand Up @@ -44,6 +45,7 @@ def create_collection(
will be used.
nl_responder: NL responder used by the collection to respond to natural language queries. If None,\
a new instance of [NLResponder][dbally.nl_responder.nl_responder.NLResponder] will be used.
fallback_collection: Collection to be asked in case of base collection failure.

Returns:
a new instance of db-ally Collection
Expand All @@ -61,4 +63,5 @@ def create_collection(
view_selector=view_selector,
llm=llm,
event_handlers=event_handlers,
fallback_collection=fallback_collection,
)
33 changes: 33 additions & 0 deletions src/dbally/audit/event_handlers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,35 @@
from abc import ABC
from typing import Generic, Optional, TypeVar

from strenum import StrEnum

from dbally.audit.events import Event, RequestEnd, RequestStart

RequestCtx = TypeVar("RequestCtx")
EventCtx = TypeVar("EventCtx")


class LogLevel(StrEnum):
"""
An enumeration representing different logging levels.

This enumeration inherits from `StrEnum`, making each log level a string value.
The log levels indicate the severity or type of events that occur within an application,
and they are commonly used to filter and categorize log messages.

Attributes:
INFO (str): Represents informational messages that highlight the progress of the application.
WARNING (str): Represents potentially harmful situations that require attention.
ERROR (str): Represents error events that might still allow the application to continue running.
DEBUG (str): Represents detailed debugging messages useful during development and troubleshooting.
"""

INFO = "Info"
WARNING = "Warning"
ERROR = "Error"
DEBUG = "Debug"


class EventHandler(Generic[RequestCtx, EventCtx], ABC):
"""
A base class that every custom handler should inherit from
Expand Down Expand Up @@ -59,3 +82,13 @@ async def request_end(self, output: RequestEnd, request_context: RequestCtx) ->
output: The output of the request.
request_context: Optional context passed from request_start method
"""

@abc.abstractmethod
async def log_message(self, message: str, log_level: LogLevel = LogLevel.INFO) -> None:
"""
Displays the response from the LLM.

Args:
message: db-ally event to be logged with all the details.
log_level: log level/importance
"""
40 changes: 34 additions & 6 deletions src/dbally/audit/event_handlers/cli_event_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
from sys import stdout
from typing import Optional

from dbally.audit.event_handlers.base import EventHandler, LogLevel
from dbally.audit.events import Event, LLMEvent, RequestEnd, RequestStart, SimilarityEvent

try:
from rich import print as pprint
from rich.console import Console
Expand All @@ -14,8 +17,6 @@
RICH_OUTPUT = False
pprint = print # type: ignore

from dbally.audit.event_handlers.base import EventHandler
from dbally.audit.events import Event, LLMEvent, RequestEnd, RequestStart, SimilarityEvent

_RICH_FORMATING_KEYWORD_SET = {"green", "orange", "grey", "bold", "cyan"}
_RICH_FORMATING_PATTERN = rf"\[.*({'|'.join(_RICH_FORMATING_KEYWORD_SET)}).*\]"
Expand Down Expand Up @@ -98,6 +99,30 @@ async def event_start(self, event: Event, request_context: None) -> None:
f"[cyan bold]FETCHER: [grey53]{event.fetcher}\n"
)

async def log_message(self, message: str, log_level: LogLevel = LogLevel.INFO) -> None:
"""
Displays message logged by user

Args:
message: Message to be sent
log_level: Message log level.
"""
colour = None
if log_level == LogLevel.INFO:
colour = "white"
elif log_level == LogLevel.WARNING:
colour = "orange"
elif log_level == LogLevel.ERROR:
colour = "red"
elif log_level == LogLevel.DEBUG:
colour = "blue"

self._print_syntax("[grey53]\n=======================================")
self._print_syntax("[grey53]=======================================")
self._print_syntax(f"[{colour}]{log_level}: {message}")
self._print_syntax("[grey53]=======================================")
self._print_syntax("[grey53]=======================================\n")

async def event_end(self, event: Optional[Event], request_context: None, event_context: None) -> None:
"""
Displays the response from the LLM.
Expand All @@ -124,8 +149,11 @@ async def request_end(self, output: RequestEnd, request_context: Optional[dict]
output: The output of the request.
request_context: Optional context passed from request_start method
"""
self._print_syntax("[green bold]REQUEST OUTPUT:")
self._print_syntax(f"Number of rows: {len(output.result.results)}")
if output.result:
self._print_syntax("[green bold]REQUEST OUTPUT:")
self._print_syntax(f"Number of rows: {len(output.result.results)}")

if "sql" in output.result.context:
self._print_syntax(f"{output.result.context['sql']}", "psql")
if "sql" in output.result.context:
self._print_syntax(f"{output.result.context['sql']}", "psql")
else:
self._print_syntax("[red bold]No results found")
14 changes: 13 additions & 1 deletion src/dbally/audit/event_tracker.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from contextlib import asynccontextmanager
from typing import AsyncIterator, Dict, List, Optional

from dbally.audit.event_handlers.base import EventHandler
from dbally.audit.event_handlers.base import EventHandler, LogLevel
from dbally.audit.events import Event, RequestEnd, RequestStart
from dbally.audit.spans import EventSpan

Expand Down Expand Up @@ -92,3 +92,15 @@ async def track_event(self, event: Event) -> AsyncIterator[EventSpan]:
await handler.event_end(
span.data, event_context=contexts[handler], request_context=self._request_contexts[handler]
)

async def log_message(self, message: str, log_level: LogLevel = LogLevel.INFO) -> None:
karllu3 marked this conversation as resolved.
Show resolved Hide resolved
"""
Send message to the handler

Args:
message: Message to be sent to
log_level: Log level.
"""

for handler in self._handlers:
await handler.log_message(message, log_level)
Loading
Loading