mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-22 02:23:30 +00:00
Fix Docs Embed host actions not reaching the assistant (#4512)
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"gitbook": patch
|
||||
---
|
||||
|
||||
Fix host action buttons in the Docs Embed not reaching the assistant.
|
||||
+9
-1
@@ -127,7 +127,15 @@ export async function GET(
|
||||
'Show me tips and tricks',
|
||||
],
|
||||
tabs: ['assistant', 'search', 'docs'],
|
||||
closeButton: useCustomTrigger
|
||||
closeButton: useCustomTrigger,
|
||||
// Host-page action: posts a message into the chat, like an embedding site would.
|
||||
actions: [
|
||||
{
|
||||
icon: 'rocket',
|
||||
label: 'Ask about pricing',
|
||||
onClick: () => window.GitBook('postUserMessage', 'How much does GitBook cost?'),
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
if (useCustomTrigger) {
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
} from '@gitbook/api';
|
||||
|
||||
import { getInsightsSession, useTrackEvent } from '../Insights';
|
||||
import { useSetSearchState } from '../Search';
|
||||
import { type UpdateSearchState, useSetSearchState } from '../Search';
|
||||
import { addRecentSearchQuery } from '../Search/recent-queries';
|
||||
import type { AnyAIControl } from './controls';
|
||||
import { ConfirmControlDef, ConfirmControlOutputSchema } from './controls/ConfirmControl';
|
||||
@@ -32,6 +32,8 @@ import { useCurrentContent } from '@/components/hooks';
|
||||
import { useLanguage } from '@/intl/client';
|
||||
import { tString } from '@/intl/translate';
|
||||
|
||||
const noopSetSearchState: UpdateSearchState = () => Promise.resolve(new URLSearchParams());
|
||||
|
||||
export type AIChatMessage = {
|
||||
role: AIMessageRole;
|
||||
content: React.ReactNode;
|
||||
@@ -235,7 +237,7 @@ export function AIChatProvider(props: {
|
||||
|
||||
const messageContextRef = useAIMessageContextRef();
|
||||
const trackEvent = useTrackEvent();
|
||||
const setSearchState = useSetSearchState();
|
||||
const setSearchStateInURL = useSetSearchState();
|
||||
const { siteSpaceId } = useCurrentContent();
|
||||
const language = useLanguage();
|
||||
|
||||
@@ -243,6 +245,11 @@ export function AIChatProvider(props: {
|
||||
? SiteInsightsDisplayContext.Embed
|
||||
: SiteInsightsDisplayContext.Site;
|
||||
|
||||
// The embed keeps its state in its own routes, not in URL search params.
|
||||
const setSearchState = renderMessageOptions?.asEmbeddable
|
||||
? noopSetSearchState
|
||||
: setSearchStateInURL;
|
||||
|
||||
// The assistant response the user is reacting to. Snapshotted when a new user turn begins
|
||||
// (before it overwrites the store's responseId/query), so the self-feedback tool rates that
|
||||
// previous response rather than the one this reaction turn produces.
|
||||
@@ -610,14 +617,12 @@ export function AIChatProvider(props: {
|
||||
// Post a message to the AI chat
|
||||
const onPostMessage = React.useCallback(
|
||||
async (input: { message: string }) => {
|
||||
const { query, messages, control, references, responding } = globalState.getState();
|
||||
const { query, messages, control, references, responding, opened } =
|
||||
globalState.getState();
|
||||
|
||||
if (control) {
|
||||
throw new Error("We can't post a message when a control is active");
|
||||
}
|
||||
|
||||
// Still streaming: queue this follow-up instead of dropping it (flushed in order in `streamResponse`).
|
||||
if (responding) {
|
||||
// Still streaming, or waiting on a control (e.g. a tool confirmation): queue this
|
||||
// follow-up instead of dropping it (flushed in order in `streamResponse`).
|
||||
if (responding || control) {
|
||||
globalState.setState((state) => ({
|
||||
...state,
|
||||
queuedMessages: [...state.queuedMessages, input.message],
|
||||
@@ -643,9 +648,7 @@ export function AIChatProvider(props: {
|
||||
|
||||
notify(eventsRef.current.get('postMessage'), { message: input.message });
|
||||
|
||||
if (query === input.message && references.length === 0) {
|
||||
// Return early if the message is the same as the previous message
|
||||
// (unless new references are staged, which change the payload)
|
||||
if (query === input.message && references.length === 0 && !opened) {
|
||||
globalState.setState((state) => ({
|
||||
...state,
|
||||
opened: true,
|
||||
|
||||
@@ -74,6 +74,9 @@ export function EmbeddableIframeAPI(props: { baseURL: string }) {
|
||||
break;
|
||||
}
|
||||
case 'postUserMessage': {
|
||||
// The answer renders in the assistant, so bring it up if another tab is showing.
|
||||
navToken.current++;
|
||||
router.push(`${baseURL}/assistant`);
|
||||
chatController.postMessage({
|
||||
message: message.message,
|
||||
});
|
||||
|
||||
@@ -99,7 +99,7 @@ function NavigationCard(
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
<span className="line-clamp-2 text-tint-strong leading-snug transition-colors group-hover:text-primary contrast-more:group-hover:text-primary-strong">
|
||||
<span className="line-clamp-2 leading-snug text-tint-strong transition-colors group-hover:text-primary contrast-more:group-hover:text-primary-strong">
|
||||
{title}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user