Skip to content

Commit 47736bd

Browse files
committed
rough draft for web ai
1 parent 68be0b2 commit 47736bd

File tree

3 files changed

+536
-28
lines changed

3 files changed

+536
-28
lines changed

pcweb/components/docpage/navbar/typesense.py

Lines changed: 111 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import typesense
55

66
from reflex.experimental import ClientStateVar
7+
from .web_ai import Message
78
last_copied = ClientStateVar.create("is_copied", "")
89

910
suggestion_items = [
@@ -387,39 +388,80 @@ def search_input():
387388
size=14,
388389
class_name="absolute left-2 top-1/2 transform -translate-y-1/2 !text-gray-500/40",
389390
),
390-
rx.box(
391-
filter_component(),
392-
rx.link(
391+
rx.cond(
392+
web_interface.value == "search",
393+
rx.box(
394+
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+
# ),
393407
ui.button(
394-
ui.icon(icon="SparklesIcon", class_name="shrink-0 size-2"),
395-
"Ask AI",
396-
type="button",
397-
variant="secondary",
408+
"Esc",
398409
size="xs",
399-
class_name="text-sm flex flex-row gap-x-2 items-center",
400-
410+
type="button",
411+
variant="outline",
412+
on_click=rx.run_script(
413+
"document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape' }))"
414+
),
401415
),
402-
href="https://reflex.dev/docs/ai-builder/integrations/mcp-overview/"
416+
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",
403417
),
404-
ui.button(
405-
"Esc",
406-
size="xs",
407-
type="button",
408-
variant="outline",
409-
on_click=rx.run_script(
410-
"document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape' }))"
418+
rx.box(
419+
rx.el.div(
420+
rx.el.p("← Back to search", class_name="text-xs text-slate-9 cursor-pointer", on_click=web_interface.set_value("search")),
411421
),
422+
rx.el.button(
423+
rx.cond(
424+
ConversationalSearch.is_loading,
425+
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"
431+
),
432+
class_name="relative flex size-3",
433+
),
434+
rx.icon(tag="arrow-up", size=13, class_name=rx.cond(ConversationalSearch.current_message.length() > 1, "!text-white", "")),
435+
),
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+
on_click=ConversationalSearch.send_message,
439+
),
440+
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",
412441
),
413-
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",
414442
),
415-
rx.el.input(
416-
on_change=[
417-
lambda value: SimpleSearch.user_query(value).debounce(500),
418-
SimpleSearch.perform_search(),
419-
],
420-
auto_focus=True,
421-
placeholder="Search documentation ...",
422-
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"
443+
rx.cond(
444+
web_interface.value == "search",
445+
rx.el.input(
446+
on_change=[
447+
lambda value: SimpleSearch.user_query(value).debounce(500),
448+
SimpleSearch.perform_search(),
449+
],
450+
auto_focus=True,
451+
placeholder="Search documentation ...",
452+
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"
453+
),
454+
rx.form(
455+
rx.el.input(
456+
on_change=lambda value: ConversationalSearch.set_current_message(value),
457+
auto_focus=True,
458+
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"
460+
),
461+
enter_key_submit=True,
462+
on_submit=ConversationalSearch.send_message,
463+
reset_on_submit=True,
464+
),
423465
),
424466
class_name="w-full relative focus:outline-none",
425467
),
@@ -545,7 +587,6 @@ def searching_in_progress():
545587
class_name="w-full flex items-center justify-center text-sm py-4",
546588
)
547589

548-
549590
def search_content():
550591
return rx.scroll_area(
551592
rx.cond(
@@ -604,14 +645,56 @@ def search_content():
604645
)
605646

606647

648+
def chat_message(message: Message):
649+
return rx.cond(
650+
message.role == "user",
651+
rx.el.div(
652+
rx.el.div(
653+
rx.el.p(message.content, class_name="text-sm"),
654+
class_name="bg-secondary-3 rounded-md p-2 max-w-xs break-words"
655+
),
656+
class_name="flex justify-end"
657+
),
658+
rx.el.div(
659+
rx.el.div(
660+
rx.markdown(message.content),
661+
class_name="p-2 text-sm"
662+
),
663+
class_name="flex justify-start"
664+
)
665+
)
666+
667+
668+
669+
def chat_content():
670+
return rx.box(
671+
rx.auto_scroll(
672+
rx.foreach(
673+
ConversationalSearch.messages, chat_message,
674+
),
675+
class_name="h-[57vh] px-1 flex flex-col gap-y-2 [&_.rt-ScrollAreaScrollbar]:right-[0.2875rem] [&_.rt-ScrollAreaScrollbar]:mt-[3rem]"
676+
),
677+
class_name="w-full h-full pt-12"
678+
),
679+
680+
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+
607686
def typesense_search() -> rx.Component:
608687
"""Create the main search component for Reflex Web"""
609688
return rx.fragment(
610689
rx.dialog.root(
611690
rx.dialog.trigger(search_trigger(), id="search-trigger"),
612691
rx.dialog.content(
613692
search_input(),
614-
search_content(),
693+
rx.cond(
694+
web_interface.value == "search",
695+
search_content(),
696+
chat_content(),
697+
),
615698
on_interact_outside=SimpleSearch.reset_search,
616699
on_escape_key_down=SimpleSearch.reset_search,
617700
class_name="w-full max-w-[650px] mx-auto bg-secondary-1 border-none outline-none p-3 lg:!fixed lg:!top-24 lg:!left-1/2 lg:!transform lg:!-translate-x-1/2 lg:!translate-y-0 lg:!m-0 "

0 commit comments

Comments
 (0)