Repository navigation
feat(web,mobile): /side starts the side chat with the message's attachments #32096
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
base: main
Are you sure you want to change the base?
Changes from all commits
4873ab6
bbc031c
751a51c
c672780
a3a8dd3
b77df93
93957e0
cf2eb6f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -59,6 +59,7 @@ import { | |||||||||||||||||||
| appendPendingThreadMessages, | ||||||||||||||||||||
| selectPendingAcknowledgedMessages, | ||||||||||||||||||||
| } from "../features/threads/pending-thread-feed"; | ||||||||||||||||||||
| import type { SideChatMessage } from "../features/threads/useStartSideChat"; | ||||||||||||||||||||
| import { threadAllowsProviderSwitch } from "./thread-provider-switching"; | ||||||||||||||||||||
| import { appAtomRegistry } from "./atom-registry"; | ||||||||||||||||||||
| import { pendingThreadCreationMessage } from "./pending-thread-creation"; | ||||||||||||||||||||
|
|
@@ -178,10 +179,10 @@ export function useThreadDraftForThread(input: { | |||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| export function useThreadComposerState(input: { | ||||||||||||||||||||
| /** Forks the thread into a side chat that gets `prompt`; resolves false when it did not start. */ | ||||||||||||||||||||
| /** Forks the thread into a side chat that gets `message`; resolves false when it did not start. */ | ||||||||||||||||||||
| readonly startSideChat: ( | ||||||||||||||||||||
| source: ScopedThreadRef, | ||||||||||||||||||||
| prompt: string, | ||||||||||||||||||||
| message: SideChatMessage, | ||||||||||||||||||||
| settings: { readonly runtimeMode: RuntimeMode; readonly modelSelection: ModelSelection }, | ||||||||||||||||||||
| ) => Promise<boolean>; | ||||||||||||||||||||
| }) { | ||||||||||||||||||||
|
|
@@ -558,24 +559,34 @@ export function useThreadComposerState(input: { | |||||||||||||||||||
| }; | ||||||||||||||||||||
| // A redirect's text answers its approval, so `/side` there is that text, not the command. | ||||||||||||||||||||
| const sideChatCommand = beforeDispatch === undefined ? parseSideChatCommand(text) : null; | ||||||||||||||||||||
| const contextBlockReason = composerContextSendBlockReason(draft.context); | ||||||||||||||||||||
| if (sideChatCommand) { | ||||||||||||||||||||
| if (sideChatUnavailableReason !== null) { | ||||||||||||||||||||
| Dialog.alert("Side chat not started", sideChatUnavailableReason); | ||||||||||||||||||||
| } else if (attachments.length > 0 || (draft.context?.records.length ?? 0) > 0) { | ||||||||||||||||||||
| } else if ( | ||||||||||||||||||||
| draft.context?.records.some((record) => record.kind !== "image" && record.kind !== "file") | ||||||||||||||||||||
| ) { | ||||||||||||||||||||
| Dialog.alert( | ||||||||||||||||||||
| "Side chats take text only", | ||||||||||||||||||||
| "Remove the attachments and context, then send it again.", | ||||||||||||||||||||
| "Side chats take text and attachments only", | ||||||||||||||||||||
| "Remove the added context, then send it again.", | ||||||||||||||||||||
| ); | ||||||||||||||||||||
| } else if (sideChatCommand.prompt.length === 0) { | ||||||||||||||||||||
| } else if (sideChatCommand.prompt.length === 0 && attachments.length === 0) { | ||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The The A draft with too many attachments or too much image/file context now reaches Apply both checks to the Proposed fix
Committable suggestion
|
||||||||||||||||||||
| Dialog.alert("Ask a side question", "Type the question after /side, then send it."); | ||||||||||||||||||||
| } else if (attachments.length > PROVIDER_SEND_TURN_MAX_ATTACHMENTS) { | ||||||||||||||||||||
| Dialog.alert( | ||||||||||||||||||||
| "Too many attachments", | ||||||||||||||||||||
| `Remove attachments until there are at most ${PROVIDER_SEND_TURN_MAX_ATTACHMENTS}.`, | ||||||||||||||||||||
| ); | ||||||||||||||||||||
| } else if (contextBlockReason) { | ||||||||||||||||||||
| Dialog.alert("Too much context", contextBlockReason); | ||||||||||||||||||||
| } else if (modelUnavailable) { | ||||||||||||||||||||
| alertModelUnavailable(); | ||||||||||||||||||||
| } else if (!startingSideChatRef.current) { | ||||||||||||||||||||
| startingSideChatRef.current = true; | ||||||||||||||||||||
| const started = await input | ||||||||||||||||||||
| .startSideChat( | ||||||||||||||||||||
| { environmentId: thread.environmentId, threadId: thread.id }, | ||||||||||||||||||||
| sideChatCommand.prompt, | ||||||||||||||||||||
| { text: sideChatCommand.prompt, attachments, context: draft.context }, | ||||||||||||||||||||
| { | ||||||||||||||||||||
| runtimeMode: draft.runtimeMode ?? thread.runtimeMode, | ||||||||||||||||||||
| modelSelection, | ||||||||||||||||||||
|
|
@@ -589,8 +600,11 @@ export function useThreadComposerState(input: { | |||||||||||||||||||
| if ( | ||||||||||||||||||||
| started && | ||||||||||||||||||||
| current.text === draft.text && | ||||||||||||||||||||
| current.attachments.length === 0 && | ||||||||||||||||||||
| (current.context?.records.length ?? 0) === 0 | ||||||||||||||||||||
| current.attachments.length === attachments.length && | ||||||||||||||||||||
| current.attachments.every( | ||||||||||||||||||||
| (attachment, index) => attachment.id === attachments[index]?.id, | ||||||||||||||||||||
| ) && | ||||||||||||||||||||
| JSON.stringify(current.context) === JSON.stringify(draft.context) | ||||||||||||||||||||
| ) { | ||||||||||||||||||||
| clearComposerDraftContent(threadKey); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
@@ -619,7 +633,6 @@ export function useThreadComposerState(input: { | |||||||||||||||||||
| return null; | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| const contextBlockReason = composerContextSendBlockReason(draft.context); | ||||||||||||||||||||
| if (contextBlockReason) { | ||||||||||||||||||||
| Dialog.alert("Too much context", contextBlockReason); | ||||||||||||||||||||
| return null; | ||||||||||||||||||||
|
|
||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Script executed:
Repository: pingdotgg/t3code
Length of output: 154
Script executed:
Repository: pingdotgg/t3code
Length of output: 15430
Script executed:
Repository: pingdotgg/t3code
Length of output: 11187
Script executed:
Repository: pingdotgg/t3code
Length of output: 18230
Script executed:
Repository: pingdotgg/t3code
Length of output: 10914
Script executed:
Repository: pingdotgg/t3code
Length of output: 18210
Script executed:
Repository: pingdotgg/t3code
Length of output: 964
Script executed:
Repository: pingdotgg/t3code
Length of output: 5778
Script executed:
Repository: pingdotgg/t3code
Length of output: 6227
Restore the prompt for an attachment-only side chat.
With
/sideand attachments but no text, mobile dispatches an empty message instead of the instruction to respond using the attachments.Suggested fix
+import { restoreAttachmentOnlyBootstrapPrompt } from "@t3tools/shared/composerContextReferences"; import * as Dialog from "../../components/ui/Dialog";