@@ -13,7 +13,6 @@ import {
1313} from "@t3tools/contracts" ;
1414import { Cache , Cause , Duration , Effect , Equal , Layer , Option , Schema , Stream } from "effect" ;
1515import { makeDrainableWorker } from "@t3tools/shared/DrainableWorker" ;
16- import { truncate } from "@t3tools/shared/String" ;
1716
1817import { resolveThreadWorkspaceCwd } from "../../checkpointing/Utils.ts" ;
1918import { GitCore } from "../../git/Services/GitCore.ts" ;
@@ -76,43 +75,16 @@ const WORKTREE_BRANCH_PREFIX = "t3code";
7675const TEMP_WORKTREE_BRANCH_PATTERN = new RegExp ( `^${ WORKTREE_BRANCH_PREFIX } \\/[0-9a-f]{8}$` ) ;
7776const DEFAULT_THREAD_TITLE = "New thread" ;
7877
79- function buildReplaceableThreadTitles ( input : {
80- readonly messageText : string ;
81- readonly attachments ?: ReadonlyArray < ChatAttachment > ;
82- readonly titleSeed ?: string ;
83- } ) : ReadonlySet < string > {
84- const titles = new Set < string > ( [ DEFAULT_THREAD_TITLE ] ) ;
85- const trimmedTitleSeed = input . titleSeed ?. trim ( ) ;
86-
87- if ( trimmedTitleSeed ) {
88- titles . add ( trimmedTitleSeed ) ;
89- return titles ;
78+ function canReplaceThreadTitle ( currentTitle : string , titleSeed ?: string ) : boolean {
79+ const trimmedCurrentTitle = currentTitle . trim ( ) ;
80+ if ( trimmedCurrentTitle === DEFAULT_THREAD_TITLE ) {
81+ return true ;
9082 }
9183
92- const trimmedMessage = input . messageText . trim ( ) ;
93-
94- if ( trimmedMessage . length > 0 ) {
95- titles . add ( truncate ( trimmedMessage ) ) ;
96- return titles ;
97- }
98-
99- const firstImageAttachment = input . attachments ?. find ( ( attachment ) => attachment . type === "image" ) ;
100- if ( firstImageAttachment ) {
101- titles . add ( truncate ( `Image: ${ firstImageAttachment . name } ` ) ) ;
102- }
103-
104- return titles ;
105- }
106-
107- function isReplaceableThreadTitle (
108- currentTitle : string ,
109- input : {
110- readonly messageText : string ;
111- readonly attachments ?: ReadonlyArray < ChatAttachment > ;
112- readonly titleSeed ?: string ;
113- } ,
114- ) : boolean {
115- return buildReplaceableThreadTitles ( input ) . has ( currentTitle . trim ( ) ) ;
84+ const trimmedTitleSeed = titleSeed ?. trim ( ) ;
85+ return trimmedTitleSeed !== undefined && trimmedTitleSeed . length > 0
86+ ? trimmedCurrentTitle === trimmedTitleSeed
87+ : false ;
11688}
11789
11890function isUnknownPendingApprovalRequestError ( cause : Cause . Cause < ProviderServiceError > ) : boolean {
@@ -511,7 +483,7 @@ const make = Effect.gen(function* () {
511483
512484 const thread = yield * resolveThread ( input . threadId ) ;
513485 if ( ! thread ) return ;
514- if ( ! isReplaceableThreadTitle ( thread . title , input ) ) {
486+ if ( ! canReplaceThreadTitle ( thread . title , input . titleSeed ) ) {
515487 return ;
516488 }
517489
@@ -579,7 +551,7 @@ const make = Effect.gen(function* () {
579551 ...generationInput ,
580552 } ) . pipe ( Effect . forkScoped ) ;
581553
582- if ( isReplaceableThreadTitle ( thread . title , generationInput ) ) {
554+ if ( canReplaceThreadTitle ( thread . title , event . payload . titleSeed ) ) {
583555 yield * maybeGenerateThreadTitleForFirstTurn ( {
584556 threadId : event . payload . threadId ,
585557 cwd : generationCwd ,
0 commit comments