Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export interface ConversationStarterContainerProps {
/**
* Optional click override. When provided, replaces the default
* send-to-thread behavior (still guarded by `isRunning`). The prefill-chips
* welcome uses it to append contextual-starter prompts into the draft.
* welcome uses it to submit contextual starters with the prefilled draft.
*/
onSelect?: (starter: ConversationStarterProps) => void;
}
Expand Down
15 changes: 5 additions & 10 deletions packages/react-ui/src/components/AgentInterface/WelcomeScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ConversationStarterProps } from "../../types/ConversationStarter";
import { PromptTemplate } from "../../types/PromptTemplate";
import { useStartersFromContext } from "./_shared/startersContext";
import { isChatEmpty } from "./_shared/utils";
import { appendStarterPrompt } from "./_shared/utils/welcomePrefill";
import { submitStarterPrompt } from "./_shared/utils/welcomePrefill";
import { DesktopWelcomeComposer, WelcomePrefillChips } from "./components";
import { ConversationStarter, ConversationStarterVariant } from "./ConversationStarter";
import { WelcomeGlow, WelcomeGlowProvider } from "./WelcomeGlow";
Expand Down Expand Up @@ -48,8 +48,8 @@ interface WelcomeScreenWithContentProps extends WelcomeScreenBaseProps {
/**
* Fill-in-the-blank prompt templates, rendered as chips between the composer
* and the starters. Clicking one drops its prompt stem into the composer
* (instead of sending) and shows the template's completions, which append to
* the draft.
* (instead of sending) and shows the template's completions. Selecting a
* completion sends the completed prompt immediately.
*/
promptTemplates?: PromptTemplate[];
/**
Expand Down Expand Up @@ -95,6 +95,7 @@ export const WelcomeScreen = (props: WelcomeScreenProps) => {
const messages = useThread((s) => s.messages);
const isLoadingMessages = useThread((s) => s.isLoadingMessages);
const isRunning = useThread((s) => s.isRunning);
const processMessage = useThread((s) => s.processMessage);

// Prefill-chips draft state — owned here (not in the composer) so chips can
// write into the draft. Hooks stay unconditional; unused without chips.
Expand Down Expand Up @@ -167,13 +168,7 @@ export const WelcomeScreen = (props: WelcomeScreenProps) => {
};

const handleContextualSelect = (starter: ConversationStarterProps) => {
const next = appendStarterPrompt(draft, starter.prompt);
setDraft(next);
setSelectedChip(null);
requestAnimationFrame(() => {
inputRef.current?.focus();
inputRef.current?.setSelectionRange(next.length, next.length);
});
submitStarterPrompt(processMessage, draft, starter.prompt);
};

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,16 @@ export const appendStarterPrompt = (draft: string, prompt: string): string => {
const separator = draft.length > 0 && !draft.endsWith(" ") ? " " : "";
return `${draft}${separator}${prompt}`;
};

type ProcessStarterMessage = (message: { role: "user"; content: string }) => void;

/** Composes a contextual starter with the current draft and submits it. */
export const submitStarterPrompt = (
processMessage: ProcessStarterMessage,
draft: string,
prompt: string,
): void =>
processMessage({
role: "user",
content: appendStarterPrompt(draft, prompt),
});
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export interface WelcomePrefillChipsProps {
* Chip row + grid-stacked starters layers for the prefill-chips welcome.
* Layer 1 (chips + default starters) hides via `visibility` while drafting so
* the layout doesn't jump; layer 2 shows the selected chip's contextual
* starters, which append to the draft (see WelcomeScreen).
* starters, which submit the completed prompt (see WelcomeScreen).
*/
export const WelcomePrefillChips = ({
chips,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ export const WithWelcome = {
),
};

/** Welcome with prefill chips — chip click prefills the composer; contextual starters append. */
/** Welcome with prompt templatesa chip prefills the composer; a completion submits it. */
export const WelcomeWithPrefillChips = {
render: () => (
<AgentInterface
Expand Down
6 changes: 3 additions & 3 deletions packages/react-ui/src/types/PromptTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import { ConversationStarterProps } from "./ConversationStarter";
/**
* A fill-in-the-blank prompt for the welcome screen, rendered as a chip:
* clicking drops the incomplete `prompt` stem into the welcome composer
* (instead of sending), then shows the template's `completions`, which append
* to the draft on click.
* (instead of sending), then shows the template's `completions`, which submit
* the completed prompt on click.
*/
export interface PromptTemplate {
displayText: string;
/** The prompt stem dropped into the composer, e.g. "Create a deck about ". */
prompt: string;
/** Optional icon; omit for none (chips render no default icon). */
icon?: ReactNode;
/** Suggested completions shown once this template is in the composer. */
/** Suggested completions that submit with the prompt stem when selected. */
completions: ConversationStarterProps[];
}
Loading