Skip to content

Commit 55ef837

Browse files
authored
Merge pull request #105 from 7df-lab/dev/goal_title_fix_0616
Fix goal session title generation
2 parents 60b5c1b + aee30b3 commit 55ef837

4 files changed

Lines changed: 435 additions & 25 deletions

File tree

crates/server/src/runtime/goal_handlers.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ impl ServerRuntime {
2020
};
2121
let session_id = params.session_id;
2222
let replace_existing = params.replace_existing;
23+
let title_input = params.objective.trim().to_string();
24+
if !self.sessions.lock().await.contains_key(&session_id) {
25+
return self.error_response(
26+
request_id,
27+
ProtocolErrorCode::SessionNotFound,
28+
"session does not exist",
29+
);
30+
}
2331

2432
let mut stores = self.goal_stores.lock().await;
2533
let store = stores.entry(session_id).or_insert_with(GoalStore::new);
@@ -43,6 +51,8 @@ impl ServerRuntime {
4351
tracing::warn!(session_id = %session_id, error = %error, "failed to persist goal create record");
4452
}
4553
self.sync_core_session_goal(session_id, session_goal).await;
54+
self.maybe_start_title_generation_from_user_input(session_id, &title_input)
55+
.await;
4656
if replace_existing {
4757
self.interrupt_active_goal_continuation_turn(session_id, "goal replaced")
4858
.await;
@@ -77,10 +87,23 @@ impl ServerRuntime {
7787
};
7888
let session_id = params.session_id;
7989
let requested_status = params.status;
90+
let title_input = params
91+
.objective
92+
.as_deref()
93+
.map(str::trim)
94+
.filter(|objective| !objective.is_empty())
95+
.map(str::to_string);
8096
let only_pause_budget_limited = requested_status
8197
== Some(devo_protocol::ThreadGoalStatus::Paused)
8298
&& params.objective.is_none()
8399
&& params.token_budget.is_none();
100+
if !self.sessions.lock().await.contains_key(&session_id) {
101+
return self.error_response(
102+
request_id,
103+
ProtocolErrorCode::SessionNotFound,
104+
"session does not exist",
105+
);
106+
}
84107

85108
let mut stores = self.goal_stores.lock().await;
86109
let store = stores.entry(session_id).or_insert_with(GoalStore::new);
@@ -146,6 +169,10 @@ impl ServerRuntime {
146169
)
147170
.await;
148171
}
172+
if let Some(title_input) = title_input {
173+
self.maybe_start_title_generation_from_user_input(session_id, &title_input)
174+
.await;
175+
}
149176
if should_continue {
150177
self.maybe_start_goal_continuation_turn(session_id).await;
151178
}

crates/server/src/runtime/handlers/turn.rs

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -304,32 +304,8 @@ impl ServerRuntime {
304304
)
305305
.await;
306306
}
307-
self.maybe_assign_provisional_title(params.session_id, &display_input)
307+
self.maybe_start_title_generation_from_user_input(params.session_id, &display_input)
308308
.await;
309-
{
310-
let mut session = session_arc.lock().await;
311-
if session.first_user_input.is_none() {
312-
session.first_user_input = Some(display_input.clone());
313-
}
314-
}
315-
let needs_title = {
316-
let session = session_arc.lock().await;
317-
let first_input = session.first_user_input.clone();
318-
let needs = matches!(
319-
session.summary.title_state,
320-
SessionTitleState::Unset | SessionTitleState::Provisional
321-
);
322-
(needs, first_input)
323-
};
324-
if needs_title.0
325-
&& let Some(first_input) = needs_title.1
326-
{
327-
let runtime = Arc::clone(self);
328-
let sid = params.session_id;
329-
tokio::spawn(async move {
330-
runtime.maybe_generate_final_title(sid, first_input).await;
331-
});
332-
}
333309
let (record, session_context, turn_context) = {
334310
let session = session_arc.lock().await;
335311
let core_session = session.core_session.lock().await;

crates/server/src/runtime/items.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,41 @@
11
use super::*;
22

33
impl ServerRuntime {
4+
pub(super) async fn maybe_start_title_generation_from_user_input(
5+
self: &Arc<Self>,
6+
session_id: SessionId,
7+
user_input: &str,
8+
) {
9+
self.maybe_assign_provisional_title(session_id, user_input)
10+
.await;
11+
12+
let needs_title = {
13+
let Some(session_arc) = self.sessions.lock().await.get(&session_id).cloned() else {
14+
return;
15+
};
16+
let mut session = session_arc.lock().await;
17+
if session.first_user_input.is_none() {
18+
session.first_user_input = Some(user_input.to_string());
19+
}
20+
let first_input = session.first_user_input.clone();
21+
let needs = matches!(
22+
session.summary.title_state,
23+
SessionTitleState::Unset | SessionTitleState::Provisional
24+
);
25+
(needs, first_input)
26+
};
27+
if needs_title.0
28+
&& let Some(first_input) = needs_title.1
29+
{
30+
let runtime = Arc::clone(self);
31+
tokio::spawn(async move {
32+
runtime
33+
.maybe_generate_final_title(session_id, first_input)
34+
.await;
35+
});
36+
}
37+
}
38+
439
pub(super) async fn maybe_assign_provisional_title(
540
&self,
641
session_id: SessionId,

0 commit comments

Comments
 (0)