2
0

Introduce a new high-performing standalone chat API (#1200)

Closes #1154

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
	- Added authentication functionality for user sessions in chat API.
- Introduced chat-related API endpoints for starting, previewing, and
continuing chat sessions, and streaming messages.
- Implemented WhatsApp API webhook handling for receiving and processing
messages.
- Added environment variable `NEXT_PUBLIC_CHAT_API_URL` for chat API URL
configuration.

- **Bug Fixes**
	- Adjusted file upload logic to correctly determine the API host.
	- Fixed message streaming URL in chat integration with OpenAI.

- **Documentation**
- Updated guides for creating blocks, local installation, self-hosting,
and deployment to use `bun` instead of `pnpm`.

- **Refactor**
	- Refactored chat API functionalities to use modular architecture.
- Simplified client log saving and session update functionalities by
using external functions.
	- Transitioned package management and workflow commands to use `bun`.

- **Chores**
- Switched to `bun` for package management in Dockerfiles and GitHub
workflows.
	- Added new Dockerfile for chat API service setup with Bun framework.
	- Updated `.prettierignore` and documentation with new commands.

- **Style**
	- No visible changes to end-users.

- **Tests**
	- No visible changes to end-users.

- **Revert**
	- No reverts in this release.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Baptiste Arnaud
2024-03-21 10:23:23 +01:00
committed by GitHub
parent 5b9176708c
commit 2fcf83c529
51 changed files with 1446 additions and 494 deletions

View File

@ -73,7 +73,8 @@ export const FileUploadForm = (props: Props) => {
})
setIsUploading(true)
const urls = await uploadFiles({
apiHost: props.context.apiHost ?? guessApiHost(),
apiHost:
props.context.apiHost ?? guessApiHost({ ignoreChatApiUrl: true }),
files: [
{
file,
@ -112,7 +113,8 @@ export const FileUploadForm = (props: Props) => {
})
setIsUploading(true)
const urls = await uploadFiles({
apiHost: props.context.apiHost ?? guessApiHost(),
apiHost:
props.context.apiHost ?? guessApiHost({ ignoreChatApiUrl: true }),
files: files.map((file) => ({
file: file,
input: {

View File

@ -25,16 +25,15 @@ export const streamChat =
const apiHost = context.apiHost
const res = await fetch(
`${
isNotEmpty(apiHost) ? apiHost : guessApiHost()
}/api/integrations/openai/streamer`,
`${isNotEmpty(apiHost) ? apiHost : guessApiHost()}/api/v1/sessions/${
context.sessionId
}/streamMessage`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
sessionId: context.sessionId,
messages,
}),
signal: abortController.signal,

View File

@ -83,7 +83,10 @@ export async function startChatQuery({
startFrom,
typebot,
prefilledVariables,
} satisfies Omit<StartPreviewChatInput, 'typebotId'>,
} satisfies Omit<
StartPreviewChatInput,
'typebotId' | 'isOnlyRegistering'
>,
timeout: false,
}
)

View File

@ -1,6 +1,29 @@
import { getRuntimeVariable } from '@typebot.io/env/getRuntimeVariable'
const cloudViewerUrl = 'https://typebot.io'
const chatApiCloudFallbackHost = 'https://chat.typebot.io'
export const guessApiHost = () =>
getRuntimeVariable('NEXT_PUBLIC_VIEWER_URL')?.split(',')[0] ?? cloudViewerUrl
type Params = {
ignoreChatApiUrl?: boolean
}
export const guessApiHost = (
{ ignoreChatApiUrl }: Params = { ignoreChatApiUrl: false }
) => {
const chatApiUrl = getRuntimeVariable('NEXT_PUBLIC_CHAT_API_URL')
const newChatApiOnUrls = getRuntimeVariable(
'NEXT_PUBLIC_USE_EXPERIMENTAL_CHAT_API_ON'
)
if (
!ignoreChatApiUrl &&
chatApiUrl &&
(!newChatApiOnUrls || newChatApiOnUrls.includes(window.location.href))
) {
return chatApiUrl
}
return (
getRuntimeVariable('NEXT_PUBLIC_VIEWER_URL')?.split(',')[0] ??
chatApiCloudFallbackHost
)
}