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: prompt store button & random examples #60

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions src/components/MainExplore.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
import Conversation from './main/Conversation'
---

<main class="relative h-full flex-1 flex flex-col overflow-hidden bg-base">
Explore
</main>
4 changes: 1 addition & 3 deletions src/components/Send.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,7 @@ export default () => {
if (!currentConversation())
addConversation()

const controller = new AbortController()
globalAbortController.set(controller)
handlePrompt(currentConversation(), inputRef.value, controller.signal)
handlePrompt(currentConversation(), inputRef.value)
clearPrompt()
scrollController().scrollToBottom()
}
Expand Down
4 changes: 4 additions & 0 deletions src/components/conversations/ConversationSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useI18n } from '@/hooks'
import { conversationMapSortList } from '@/stores/conversation'
import ConversationSidebarItem from './ConversationSidebarItem'
import ConversationSidebarAdd from './ConversationSidebarAdd'
import ConversationSidebarPromptStore from './ConversationSidebarPromptStore'

export default () => {
const { t } = useI18n()
Expand Down Expand Up @@ -31,6 +32,9 @@ export default () => {
</For>
</div>
</div>
<div class="p-4">
<ConversationSidebarPromptStore />
</div>
</div>
)
}
19 changes: 19 additions & 0 deletions src/components/conversations/ConversationSidebarPromptStore.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useI18n } from '@/hooks'
import Button from '../ui/Button'

export default () => {
const { t } = useI18n()
const handleClick = () => {
window.open('https://store.anse.app/')
}

return (
<Button
icon="i-carbon:software-resource-cluster"
onClick={handleClick}
size="sm"
>
{t('conversations.store')}
</Button>
)
}
47 changes: 46 additions & 1 deletion src/components/main/ConversationEmpty.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,37 @@
import { For, Show, createResource } from 'solid-js'
import { showConversationEditModal } from '@/stores/ui'
import { getBotMetaById } from '@/stores/provider'
import { handlePrompt } from '@/logics/conversation'
import Button from '../ui/Button'
import type { Conversation } from '@/types/conversation'

const fetchPromptStore = async() => {
const { data } = await fetch('https://store.anse.app/api/list').then(res => res.json())
return data as ExamplePrompt[]
}

interface ExamplePrompt {
title: string
content: string
}

interface Props {
conversation: Conversation
}

export default (props: Props) => {
const [examplePrompts] = createResource(fetchPromptStore)
const botMeta = () => getBotMetaById(props.conversation.bot) || null

const handleExamplePromptClick = (prompt: ExamplePrompt) => {
handlePrompt(props.conversation, prompt.content)
}
const handleOpenStoreClick = () => {
window.open('https://store.anse.app/')
}

return (
<div class="fi flex-col h-full px-6 py-8 overflow-auto">
<div class="fi flex-col gap-6 h-full px-6 py-8 overflow-auto">
<Button
icon="i-carbon-settings-adjust text-sm"
onClick={() => showConversationEditModal.set(true)}
Expand All @@ -24,6 +45,30 @@ export default (props: Props) => {
)}
</div>
</Button>
<Show when={examplePrompts()}>
<div class="w-full max-w-md mx-12 px-4 py-3 sm:mx-18 border border-base rounded-lg">
<h3 class="flex items-center gap-1 text-sm op-50">
<div class="i-carbon:idea font-semibold" />
<div class="flex-1">Examples</div>
<div
class="fcc p-2 rounded-md hv-foreground"
onClick={handleOpenStoreClick}
>
<div i-carbon-arrow-up-right />
</div>
</h3>
<div class="flex flex-col gap-1 mt-1">
<For each={examplePrompts()}>
{prompt => (
<div class="-mx-1 px-2 py-2 hv-base rounded-md" onClick={() => handleExamplePromptClick(prompt)}>
<div class="text-sm font-semibold">{prompt.title}</div>
<div class="mt-1 text-xs line-clamp-2 op-60">{prompt.content}</div>
</div>
)}
</For>
</div>
</div>
</Show>
</div>
)
}
10 changes: 2 additions & 8 deletions src/components/main/MessageItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { deleteMessageByConversationId, spliceMessageByConversationId, spliceUpd
import { conversationMap } from '@/stores/conversation'
import { handlePrompt } from '@/logics/conversation'
import { scrollController } from '@/stores/ui'
import { globalAbortController } from '@/stores/settings'
import StreamableText from '../StreamableText'
import { DropDownMenu, Tooltip } from '../ui/base'
import Button from '../ui/Button'
Expand Down Expand Up @@ -45,10 +44,8 @@ export default (props: Props) => {
}

const handleRetryMessageItem = () => {
const controller = new AbortController()
globalAbortController.set(controller)
spliceMessageByConversationId(props.conversationId, props.message)
handlePrompt(currentConversation(), '', controller.signal)
handlePrompt(currentConversation(), '')
// TODO: scrollController seems not working
scrollController().scrollToBottom()
}
Expand All @@ -61,16 +58,13 @@ export default (props: Props) => {
const handleSend = () => {
if (!inputRef.value)
return
const controller = new AbortController()
const currentMessage: MessageInstance = {
...props.message,
content: inputPrompt(),
}

globalAbortController.set(controller)
spliceUpdateMessageByConversationId(props.conversationId, currentMessage)
setIsEditing(false)
handlePrompt(currentConversation(), '', controller.signal)
handlePrompt(currentConversation(), '')
scrollController().scrollToBottom()
}

Expand Down
1 change: 1 addition & 0 deletions src/locale/lang/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const en = {
conversations: {
title: 'Conversations',
add: 'New',
store: 'Prompt Store',
recent: 'Recents',
noRecent: 'No recents',
untitled: 'Untitled',
Expand Down
1 change: 1 addition & 0 deletions src/locale/lang/zh-cn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const zhCN = {
conversations: {
title: '对话列表',
add: '新对话',
store: '提示词商店',
recent: '最近对话',
noRecent: '暂无最近对话',
untitled: '未命名对话',
Expand Down
8 changes: 5 additions & 3 deletions src/logics/conversation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import destr from 'destr'
import { getBotMetaById, getProviderById } from '@/stores/provider'
import { updateConversationById } from '@/stores/conversation'
import { clearMessagesByConversationId, getMessagesByConversationId, pushMessageByConversationId } from '@/stores/messages'
import { getGeneralSettings, getSettingsByProviderId } from '@/stores/settings'
import { getGeneralSettings, getSettingsByProviderId, globalAbortController } from '@/stores/settings'
import { setLoadingStateByConversationId, setStreamByConversationId } from '@/stores/streams'
import { currentErrorMessage } from '@/stores/ui'
import { generateRapidProviderPayload, promptHelper } from './helper'
import type { HandlerPayload, PromptResponse } from '@/types/provider'
import type { Conversation } from '@/types/conversation'
import type { ErrorMessage, Message } from '@/types/message'

export const handlePrompt = async(conversation: Conversation, prompt?: string, signal?: AbortSignal) => {
export const handlePrompt = async(conversation: Conversation, prompt?: string) => {
const generalSettings = getGeneralSettings()
const bot = getBotMetaById(conversation.bot)
const [providerId, botId] = conversation.bot.split(':')
Expand Down Expand Up @@ -49,10 +49,12 @@ export const handlePrompt = async(conversation: Conversation, prompt?: string, s
})),
],
}
const controller = new AbortController()
globalAbortController.set(controller)
try {
providerResponse = await getProviderResponse(provider.id, handlerPayload, {
caller: callMethod,
signal,
signal: controller.signal,
})
} catch (e) {
const error = e as Error
Expand Down
24 changes: 13 additions & 11 deletions src/pages/index.astro
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
import Layout from '@/layouts/Layout.astro'
import Main from '@/components/Main.astro'
import MainExplore from '@/components/MainExplore.astro'
import ConversationSidebar from '@/components/conversations/ConversationSidebar'
import Settings from '@/components/settings/SettingsSidebar'
import ModalsLayer from '@/components/ModalsLayer'
Expand All @@ -9,15 +10,16 @@ import BuildStores from '@/components/client-only/BuildStores'
---

<Layout title="Anse">
<div class="h-100vh w-screen flex">
<Sidebar direction="left" class="hidden md:block">
<ConversationSidebar client:only />
</Sidebar>
<Main />
<Sidebar direction="right" class="hidden lg:block">
<Settings client:only />
</Sidebar>
</div>
<ModalsLayer client:only />
<BuildStores client:only />
<div class="h-100vh w-screen flex">
<Sidebar direction="left" class="hidden md:block">
<ConversationSidebar client:only />
</Sidebar>
<Main />
<!-- <MainExplore /> -->
<Sidebar direction="right" class="hidden lg:block">
<Settings client:only />
</Sidebar>
</div>
<ModalsLayer client:only />
<BuildStores client:only />
</Layout>