mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-08-23 05:02:21 +02:00
[eric] composer: stop rotating ghost-text guesses + only predict after real usage (4+ chats)
This commit is contained in:
@@ -17,6 +17,10 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
MAX_TOPICS = 24
|
||||
MAX_SUGGESTIONS = 5
|
||||
# Don't predict someone's next prompt until we ACTUALLY know their patterns. Below this many real
|
||||
# past chats, any guess is just noise (onboarding starters alone are what they browsed at setup, not
|
||||
# a read on what they want now), so we stay silent and let the neutral placeholder stand.
|
||||
MIN_REAL_TOPICS = 4
|
||||
# Names the aux title-gen hands out for empty/greeting chats; they carry no topic signal.
|
||||
P_SKIP_NAMES = {"untitled", "new chat", "greeting", "chat", ""}
|
||||
|
||||
@@ -70,8 +74,9 @@ async def predict_prompts(count: int = MAX_SUGGESTIONS) -> List[str]:
|
||||
for s in (global_settings.personalized_starters or [])
|
||||
if getattr(s, "prompt", None)
|
||||
]
|
||||
# Nothing to personalize from: let the composer keep its static placeholder.
|
||||
if not topics and not starters:
|
||||
# Only predict once there's a real track record. Onboarding starters can enrich a prediction
|
||||
# but never trigger one on their own: a brand-new user hasn't shown us what they want yet.
|
||||
if len(topics) < MIN_REAL_TOPICS:
|
||||
return []
|
||||
|
||||
aux_model = (await resolve_aux_model(global_settings, preferred_tier="haiku"))[0]
|
||||
|
||||
@@ -99,7 +99,6 @@ const DashboardToolbar = React.forwardRef<HTMLDivElement, Props>(
|
||||
// load (cached), then one is shown at a time and cycled while the composer sits idle+empty. Empty
|
||||
// list (no signal / no provider / error) just leaves the static "What should I do sir..." placeholder.
|
||||
const [ghostList, setGhostList] = useState<string[]>([]);
|
||||
const [ghostIdx, setGhostIdx] = useState(0);
|
||||
const ghostFetchedRef = useRef(false);
|
||||
useEffect(() => {
|
||||
if (!inputOpen || ghostFetchedRef.current) return;
|
||||
@@ -116,14 +115,10 @@ const DashboardToolbar = React.forwardRef<HTMLDivElement, Props>(
|
||||
} catch { /* fail open: keep the static placeholder */ }
|
||||
})();
|
||||
}, [inputOpen]);
|
||||
// Rotate the visible suggestion every few seconds while the composer is open, so the user sees a
|
||||
// few different ideas instead of one. Cheap; the list is already fetched and cached.
|
||||
useEffect(() => {
|
||||
if (!inputOpen || ghostList.length <= 1) return undefined;
|
||||
const t = setInterval(() => setGhostIdx((i) => (i + 1) % ghostList.length), 4500);
|
||||
return () => clearInterval(t);
|
||||
}, [inputOpen, ghostList.length]);
|
||||
const ghostSuggestion = ghostList.length ? ghostList[ghostIdx % ghostList.length] : undefined;
|
||||
// ONE stable suggestion, never a rotating carousel: cycling guesses every few seconds reads as
|
||||
// "the app is throwing darts." The backend only returns anything when it has real usage history to
|
||||
// predict from (see predict_prompts.py), so an empty list just leaves the neutral placeholder.
|
||||
const ghostSuggestion = ghostList.length ? ghostList[0] : undefined;
|
||||
|
||||
// Reset defaults on each new compose session so in-session picks don't leak into the next new-chat draft.
|
||||
const prevInputOpen = useRef(false);
|
||||
|
||||
Reference in New Issue
Block a user