Skip to content

Commit e03ecd7

Browse files
committed
..
1 parent 48b7357 commit e03ecd7

File tree

6 files changed

+151
-157
lines changed

6 files changed

+151
-157
lines changed

.github/workflows/deploy-dev.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@ jobs:
4949
python scripts/typesense_indexer.py --docs-path ./docs --blog-path ./blog --force
5050
python scripts/synonym_indexer.py
5151
52+
- name: Create Conversational RAG
53+
env:
54+
TYPESENSE_ADMIN_API_KEY: ${{ secrets.DEV_TYPESENSE_ADMIN_API_KEY }}
55+
TYPESENSE_HOST: ${{ secrets.DEV_TYPESENSE_HOST }}
56+
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
57+
run: |
58+
uv pip install typesense
59+
python scripts/conversation_indexer.py --force
60+
5261
- name: Deploy to Reflex
5362
id: deploy
5463
run: |

.github/workflows/deploy-prd.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,15 @@ jobs:
4747
python scripts/typesense_indexer.py --docs-path ./docs --blog-path ./blog --force
4848
python scripts/synonym_indexer.py
4949
50+
- name: Create Conversational RAG
51+
env:
52+
TYPESENSE_ADMIN_API_KEY: ${{ secrets.PRD_TYPESENSE_ADMIN_API_KEY }}
53+
TYPESENSE_HOST: ${{ secrets.PRD_TYPESENSE_HOST }}
54+
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
55+
run: |
56+
uv pip install typesense
57+
python scripts/conversation_indexer.py --force
58+
5059
- name: Deploy to Reflex
5160
id: deploy
5261
run: |

.github/workflows/deploy-stg.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@ jobs:
4949
python scripts/typesense_indexer.py --docs-path ./docs --blog-path ./blog --force
5050
python scripts/synonym_indexer.py
5151
52+
- name: Create Conversational RAG
53+
env:
54+
TYPESENSE_ADMIN_API_KEY: ${{ secrets.STG_TYPESENSE_ADMIN_API_KEY }}
55+
TYPESENSE_HOST: ${{ secrets.STG_TYPESENSE_HOST }}
56+
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
57+
run: |
58+
uv pip install typesense
59+
python scripts/conversation_indexer.py --force
60+
5261
- name: Deploy to Reflex
5362
id: deploy
5463
run: |

pcweb/components/docpage/navbar/typesense.py

Lines changed: 102 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
import typesense
55

66
from reflex.experimental import ClientStateVar
7-
from .web_ai import Message
7+
from .web_ai import Message, ConversationalSearch
8+
9+
web_interface = ClientStateVar.create("web_interface", "search")
10+
is_processing_prompt = ClientStateVar.create("is_processing_prompt", False)
811
last_copied = ClientStateVar.create("is_copied", "")
912

1013
suggestion_items = [
@@ -392,18 +395,15 @@ def search_input():
392395
web_interface.value == "search",
393396
rx.box(
394397
filter_component(),
395-
# rx.link(
396-
ui.button(
397-
ui.icon(icon="SparklesIcon", class_name="shrink-0 size-2"),
398-
"Ask AI",
399-
type="button",
400-
variant="secondary",
401-
size="xs",
402-
class_name="text-sm flex flex-row gap-x-2 items-center",
403-
on_click=web_interface.set_value("ai_chat"),
404-
),
405-
# href="https://reflex.dev/docs/ai-builder/integrations/mcp-overview/"
406-
# ),
398+
ui.button(
399+
ui.icon(icon="SparklesIcon", class_name="shrink-0 size-2"),
400+
"Ask AI",
401+
type="button",
402+
variant="secondary",
403+
size="xs",
404+
class_name="text-sm flex flex-row gap-x-2 items-center",
405+
on_click=web_interface.set_value("ai_chat"),
406+
),
407407
ui.button(
408408
"Esc",
409409
size="xs",
@@ -423,18 +423,31 @@ def search_input():
423423
rx.cond(
424424
ConversationalSearch.is_loading,
425425
rx.box(
426-
rx.box(
427-
class_name="absolute inline-flex h-full w-full animate-ping rounded-md bg-orange-4 opacity-75"
428-
),
429-
rx.box(
430-
class_name="relative inline-flex size-3 rounded-md bg-orange-5"
426+
class_name="flex size-3 bg-white rounded-[15px]",
427+
),
428+
rx.icon(
429+
tag="arrow-up",
430+
size=13,
431+
class_name=rx.cond(
432+
ConversationalSearch.current_message.length() > 1,
433+
"!text-white",
434+
"",
431435
),
432-
class_name="relative flex size-3",
433436
),
434-
rx.icon(tag="arrow-up", size=13, class_name=rx.cond(ConversationalSearch.current_message.length() > 1, "!text-white", "")),
435437
),
436-
class_name="p-2 rounded-md cursor-pointer disabled:cursor-not-allowed overflow-hidden "
437-
+ rx.cond(ConversationalSearch.current_message.length() > 1, "bg-violet-9", "bg-secondary-3"),
438+
class_name=(
439+
"p-2 rounded-md cursor-pointer disabled:cursor-not-allowed overflow-hidden "
440+
+
441+
rx.cond(
442+
ConversationalSearch.is_loading,
443+
"bg-violet-9",
444+
rx.cond(
445+
ConversationalSearch.current_message.length() > 1,
446+
"bg-violet-9",
447+
"bg-secondary-3",
448+
)
449+
)
450+
),
438451
on_click=ConversationalSearch.send_message,
439452
),
440453
class_name="hidden md:flex absolute right-2 top-1/2 transform -translate-y-1/2 text-sm flex-row items-center gap-x-2",
@@ -456,7 +469,7 @@ def search_input():
456469
on_change=lambda value: ConversationalSearch.set_current_message(value),
457470
auto_focus=True,
458471
placeholder="Ask the AI about Reflex ...",
459-
class_name="py-2 pl-7 md:pr-[310px] w-full placeholder:text-sm text-sm rounded-lg outline-none focus:outline-none border border-secondary-a4 bg-secondary-1 text-secondary-12 resize-none"
472+
class_name="py-2 pl-7 md:pr-[100px] w-full placeholder:text-sm text-sm rounded-lg outline-none focus:outline-none border border-secondary-a4 bg-secondary-1 text-secondary-12 resize-none"
460473
),
461474
enter_key_submit=True,
462475
on_submit=ConversationalSearch.send_message,
@@ -645,6 +658,33 @@ def search_content():
645658
)
646659

647660

661+
@rx.memo
662+
def markdown_copy_button(
663+
content: str,
664+
):
665+
markdown_copy_state = ClientStateVar.create(
666+
"content_id", default=False, global_ref=False
667+
)
668+
669+
return rx.el.button(
670+
rx.cond(
671+
markdown_copy_state.value,
672+
rx.icon(tag="check", size=13, class_name="!text-slate-9"),
673+
rx.icon(tag="copy", size=13, class_name="!text-slate-9"),
674+
),
675+
cursor="pointer",
676+
position="absolute",
677+
right="15px",
678+
top="35px",
679+
on_click=[
680+
rx.call_function(markdown_copy_state.set_value(True)),
681+
rx.set_clipboard(content),
682+
],
683+
on_mouse_down=rx.call_function(markdown_copy_state.set_value(False)).debounce(
684+
1500
685+
),
686+
)
687+
648688
def chat_message(message: Message):
649689
return rx.cond(
650690
message.role == "user",
@@ -657,7 +697,45 @@ def chat_message(message: Message):
657697
),
658698
rx.el.div(
659699
rx.el.div(
660-
rx.markdown(message.content),
700+
rx.markdown(
701+
message.content,
702+
component_map={
703+
"h1": lambda value: rx.el.h1(value),
704+
"h2": lambda value: rx.el.h2(value),
705+
"h3": lambda value: rx.el.h3(value),
706+
"h4": lambda value: rx.el.h4(value),
707+
"h5": lambda value: rx.el.h5(value),
708+
"h6": lambda value: rx.el.h6(value),
709+
"p": lambda value: rx.el.p(value, class_name="leading-7"),
710+
"strong": lambda value: rx.el.strong(
711+
value, class_name="text-secondary-12"
712+
),
713+
"ul": lambda value: rx.el.ul(value),
714+
"ol": lambda value: rx.el.ol(value),
715+
"li": lambda value: rx.el.li(value),
716+
"a": lambda value: rx.el.a(
717+
value,
718+
class_name="underline",
719+
target="_blank",
720+
),
721+
"pre": lambda value: rx.el.pre(value, class_name="not-prose"),
722+
"codeblock": lambda value, **props: rx.el.div(
723+
rx.code_block(
724+
value,
725+
**props,
726+
wrap_long_lines=False,
727+
class_name="code-block !text-xs max-h-[300px] overflow-auto",
728+
),
729+
markdown_copy_button(content=value),
730+
class_name="flex flex-row relative py-2",
731+
),
732+
"code": lambda value, **props: rx.el.code(
733+
value,
734+
**props,
735+
class_name="font-mono border border-slate-4 bg-slate-3 px-1 rounded-[0.35rem] font-normal not-prose text-sm text-[12.5px] text-slate-12",
736+
),
737+
},
738+
),
661739
class_name="p-2 text-sm"
662740
),
663741
class_name="flex justify-start"
@@ -678,11 +756,6 @@ def chat_content():
678756
),
679757

680758

681-
from .web_ai import ConversationalSearch
682-
683-
web_interface = ClientStateVar.create("web_interface", "search")
684-
is_processing_prompt = ClientStateVar.create("is_processing_prompt", False)
685-
686759
def typesense_search() -> rx.Component:
687760
"""Create the main search component for Reflex Web"""
688761
return rx.fragment(

0 commit comments

Comments
 (0)