| ... | ... | @@ -5881,15 +5881,13 @@ export default function ChatView(props: ChatViewProps) { |
| 5881 | 5881 | pendingApprovals.length > 0 || |
| 5882 | 5882 | pendingUserInputs.length > 0 || |
| 5883 | 5883 | showPlanFollowUpPrompt; |
| 5884 | | const compactDisabled = compactThreadUnavailable || composerHasUnsentContent; |
| 5884 | const compactDisabled = compactThreadUnavailable; |
| 5885 | 5885 | const compactDisabledReason = compactDisabled |
| 5886 | | ? composerHasUnsentContent |
| 5887 | | ? "Send or clear your draft before compacting" |
| 5888 | | : !activeProject |
| 5889 | | ? "Choose a project before compacting" |
| 5890 | | : !manualCompactionProviderAvailable |
| 5891 | | ? "Compaction is unavailable for this provider" |
| 5892 | | : "Compacting is unavailable right now" |
| 5886 | ? !activeProject |
| 5887 | ? "Choose a project before compacting" |
| 5888 | : !manualCompactionProviderAvailable |
| 5889 | ? "Compaction is unavailable for this provider" |
| 5890 | : "Compacting is unavailable right now" |
| 5893 | 5891 | : null; |
| 5894 | 5892 | const resumeCompactionBannerItem = useMemo<ComposerBannerStackItem | null>(() => { |
| 5895 | 5893 | if ( |
| ... | ... | @@ -6479,6 +6477,78 @@ export default function ChatView(props: ChatViewProps) { |
| 6479 | 6477 | ], |
| 6480 | 6478 | ); |
| 6481 | 6479 | |
| 6480 | const onCompactContext = async () => { |
| 6481 | if (compactDisabled || !activeThread || !clientSettingsHydrated || sendInFlightRef.current) { |
| 6482 | return; |
| 6483 | } |
| 6484 | const context = composerRef.current?.getSendContext(); |
| 6485 | if (!context?.providerAvailable) return; |
| 6486 | |
| 6487 | // Compaction is a standalone command; the draft and its attachments stay local. |
| 6488 | const threadId = activeThread.id; |
| 6489 | const messageId = newMessageId(); |
| 6490 | const createdAt = new Date().toISOString(); |
| 6491 | sendInFlightRef.current = true; |
| 6492 | beginLocalDispatch(); |
| 6493 | setThreadError(threadId, null); |
| 6494 | setOptimisticUserMessages((messages) => [ |
| 6495 | ...messages, |
| 6496 | { |
| 6497 | id: messageId, |
| 6498 | role: "user", |
| 6499 | text: "/compact", |
| 6500 | turnId: null, |
| 6501 | createdAt, |
| 6502 | updatedAt: createdAt, |
| 6503 | streaming: false, |
| 6504 | }, |
| 6505 | ]); |
| 6506 | scrollToEnd(); |
| 6507 | try { |
| 6508 | const settingsResult = await persistThreadSettingsForNextTurn({ |
| 6509 | threadId, |
| 6510 | createdAt, |
| 6511 | modelSelection: context.selectedModelSelection, |
| 6512 | ...(localCheckoutBranchMismatch |
| 6513 | ? { branch: localCheckoutBranchMismatch.currentBranch } |
| 6514 | : {}), |
| 6515 | runtimeMode, |
| 6516 | interactionMode: context.interactionMode, |
| 6517 | }); |
| 6518 | const result = |
| 6519 | settingsResult._tag === "Failure" |
| 6520 | ? settingsResult |
| 6521 | : await startThreadTurn({ |
| 6522 | environmentId, |
| 6523 | input: { |
| 6524 | threadId, |
| 6525 | message: { messageId, role: "user", text: "/compact", attachments: [] }, |
| 6526 | modelSelection: context.selectedModelSelection, |
| 6527 | runtimeMode, |
| 6528 | interactionMode: context.interactionMode, |
| 6529 | createdAt, |
| 6530 | }, |
| 6531 | }); |
| 6532 | if (result._tag === "Failure") { |
| 6533 | setOptimisticUserMessages((messages) => |
| 6534 | messages.filter((message) => message.id !== messageId), |
| 6535 | ); |
| 6536 | resetLocalDispatch(); |
| 6537 | if (!isAtomCommandInterrupted(result)) { |
| 6538 | const error = squashAtomCommandFailure(result); |
| 6539 | setThreadError( |
| 6540 | threadId, |
| 6541 | error instanceof Error ? error.message : "Failed to compact context.", |
| 6542 | ); |
| 6543 | } |
| 6544 | } else { |
| 6545 | clearUsageLimitsFor(routeThreadKey); |
| 6546 | } |
| 6547 | } finally { |
| 6548 | sendInFlightRef.current = false; |
| 6549 | } |
| 6550 | }; |
| 6551 | |
| 6482 | 6552 | const onSend = async ( |
| 6483 | 6553 | e?: { preventDefault: () => void }, |
| 6484 | 6554 | submissionIntent: ComposerSubmissionIntent = "foreground", |
| ... | ... | @@ -8575,6 +8645,7 @@ export default function ChatView(props: ChatViewProps) { |
| 8575 | 8645 | onPageScrollKeyDown={onComposerPageScrollKeyDown} |
| 8576 | 8646 | onPageScrollKeyUp={onComposerPageScrollKeyUp} |
| 8577 | 8647 | onPageScrollRelease={onComposerPageScrollRelease} |
| 8648 | onCompactContext={onCompactContext} |
| 8578 | 8649 | onSend={onSend} |
| 8579 | 8650 | onInterrupt={onInterrupt} |
| 8580 | 8651 | onImplementPlanInNewThread={onImplementPlanInNewThread} |