-
-
Notifications
You must be signed in to change notification settings - Fork 6
fix(resolution-search): preserve chat context and make search non-blo… #447
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
Changes from all commits
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 | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -58,7 +58,8 @@ async function submit(formData?: FormData, skip?: boolean) { | |||||||||||||||||||
| message.role !== 'tool' && | ||||||||||||||||||||
| message.type !== 'followup' && | ||||||||||||||||||||
| message.type !== 'related' && | ||||||||||||||||||||
| message.type !== 'end' | ||||||||||||||||||||
| message.type !== 'end' && | ||||||||||||||||||||
| message.type !== 'resolution_search_result' | ||||||||||||||||||||
| ); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // The user's prompt for this action is static. | ||||||||||||||||||||
|
|
@@ -75,79 +76,94 @@ async function submit(formData?: FormData, skip?: boolean) { | |||||||||||||||||||
| ...aiState.get(), | ||||||||||||||||||||
| messages: [ | ||||||||||||||||||||
| ...aiState.get().messages, | ||||||||||||||||||||
| { id: nanoid(), role: 'user', content } | ||||||||||||||||||||
| { id: nanoid(), role: 'user', content, type: 'input' } | ||||||||||||||||||||
| ] | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| messages.push({ role: 'user', content }); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Call the simplified agent, which now returns data directly. | ||||||||||||||||||||
| const analysisResult = await resolutionSearch(messages) as any; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Create a streamable value for the summary and mark it as done. | ||||||||||||||||||||
| // Create a streamable value for the summary. | ||||||||||||||||||||
| const summaryStream = createStreamableValue<string>(); | ||||||||||||||||||||
| summaryStream.done(analysisResult.summary || 'Analysis complete.'); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Update the UI stream with the BotMessage component. | ||||||||||||||||||||
| uiStream.update( | ||||||||||||||||||||
| <BotMessage content={summaryStream.value} /> | ||||||||||||||||||||
| ); | ||||||||||||||||||||
| async function processResolutionSearch() { | ||||||||||||||||||||
| try { | ||||||||||||||||||||
| // Call the simplified agent, which now returns data directly. | ||||||||||||||||||||
| const analysisResult = await resolutionSearch(messages) as any; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| messages.push({ role: 'assistant', content: analysisResult.summary || 'Analysis complete.' }); | ||||||||||||||||||||
| // Mark the summary stream as done with the result. | ||||||||||||||||||||
| summaryStream.done(analysisResult.summary || 'Analysis complete.'); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| const sanitizedMessages: CoreMessage[] = messages.map(m => { | ||||||||||||||||||||
| if (Array.isArray(m.content)) { | ||||||||||||||||||||
| return { | ||||||||||||||||||||
| ...m, | ||||||||||||||||||||
| content: m.content.filter(part => part.type !== 'image') | ||||||||||||||||||||
| } as CoreMessage | ||||||||||||||||||||
| } | ||||||||||||||||||||
| return m | ||||||||||||||||||||
| }) | ||||||||||||||||||||
| messages.push({ role: 'assistant', content: analysisResult.summary || 'Analysis complete.' }); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| const relatedQueries = await querySuggestor(uiStream, sanitizedMessages); | ||||||||||||||||||||
| uiStream.append( | ||||||||||||||||||||
| <Section title="Follow-up"> | ||||||||||||||||||||
| const sanitizedMessages: CoreMessage[] = messages.map(m => { | ||||||||||||||||||||
| if (Array.isArray(m.content)) { | ||||||||||||||||||||
| return { | ||||||||||||||||||||
| ...m, | ||||||||||||||||||||
| content: m.content.filter(part => part.type !== 'image') | ||||||||||||||||||||
| } as CoreMessage | ||||||||||||||||||||
| } | ||||||||||||||||||||
| return m | ||||||||||||||||||||
| }) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| const relatedQueries = await querySuggestor(uiStream, sanitizedMessages); | ||||||||||||||||||||
| uiStream.append( | ||||||||||||||||||||
| <Section title="Follow-up"> | ||||||||||||||||||||
| <FollowupPanel /> | ||||||||||||||||||||
| </Section> | ||||||||||||||||||||
| ); | ||||||||||||||||||||
| </Section> | ||||||||||||||||||||
| ); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| await new Promise(resolve => setTimeout(resolve, 500)); | ||||||||||||||||||||
| await new Promise(resolve => setTimeout(resolve, 500)); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| const groupeId = nanoid(); | ||||||||||||||||||||
| const groupeId = nanoid(); | ||||||||||||||||||||
|
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. 🧹 Nitpick | 🔵 Trivial Typo: This appears throughout the file (lines 116, 184, 227, etc.). If intentional (perhaps French?), consider adding a comment; otherwise, a codebase-wide rename would improve clarity. 🤖 Prompt for AI Agents |
||||||||||||||||||||
|
|
||||||||||||||||||||
| aiState.done({ | ||||||||||||||||||||
| ...aiState.get(), | ||||||||||||||||||||
| messages: [ | ||||||||||||||||||||
| aiState.done({ | ||||||||||||||||||||
| ...aiState.get(), | ||||||||||||||||||||
| messages: [ | ||||||||||||||||||||
| ...aiState.get().messages, | ||||||||||||||||||||
| { | ||||||||||||||||||||
| id: groupeId, | ||||||||||||||||||||
| role: 'assistant', | ||||||||||||||||||||
| content: analysisResult.summary || 'Analysis complete.', | ||||||||||||||||||||
| type: 'response' | ||||||||||||||||||||
| id: groupeId, | ||||||||||||||||||||
| role: 'assistant', | ||||||||||||||||||||
| content: analysisResult.summary || 'Analysis complete.', | ||||||||||||||||||||
| type: 'response' | ||||||||||||||||||||
| }, | ||||||||||||||||||||
| { | ||||||||||||||||||||
| id: groupeId, | ||||||||||||||||||||
| role: 'assistant', | ||||||||||||||||||||
| content: JSON.stringify(analysisResult), | ||||||||||||||||||||
| type: 'resolution_search_result' | ||||||||||||||||||||
| id: groupeId, | ||||||||||||||||||||
| role: 'assistant', | ||||||||||||||||||||
| content: JSON.stringify(analysisResult), | ||||||||||||||||||||
| type: 'resolution_search_result' | ||||||||||||||||||||
| }, | ||||||||||||||||||||
| { | ||||||||||||||||||||
| id: groupeId, | ||||||||||||||||||||
| role: 'assistant', | ||||||||||||||||||||
| content: JSON.stringify(relatedQueries), | ||||||||||||||||||||
| type: 'related' | ||||||||||||||||||||
| id: groupeId, | ||||||||||||||||||||
| role: 'assistant', | ||||||||||||||||||||
| content: JSON.stringify(relatedQueries), | ||||||||||||||||||||
| type: 'related' | ||||||||||||||||||||
| }, | ||||||||||||||||||||
|
Comment on lines
+118
to
139
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 code writes If you only need a subset for UI/tooling, consider storing a reduced shape (e.g., SuggestionPersist a minimal, stable schema instead of the full const persisted = {
summary: analysisResult.summary,
// keep only what you actually render/use later
results: analysisResult.results?.slice(0, 20),
};
content: JSON.stringify(persisted)Reply with "@CharlieHelps yes please" if you’d like me to add a commit that trims the persisted payload and adds a small helper for shaping it. |
||||||||||||||||||||
| { | ||||||||||||||||||||
| id: groupeId, | ||||||||||||||||||||
| role: 'assistant', | ||||||||||||||||||||
| content: 'followup', | ||||||||||||||||||||
| type: 'followup' | ||||||||||||||||||||
| id: groupeId, | ||||||||||||||||||||
| role: 'assistant', | ||||||||||||||||||||
| content: 'followup', | ||||||||||||||||||||
| type: 'followup' | ||||||||||||||||||||
| } | ||||||||||||||||||||
| ] | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| ] | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| } catch (error) { | ||||||||||||||||||||
| console.error('Error in resolution search:', error); | ||||||||||||||||||||
| summaryStream.error(error); | ||||||||||||||||||||
| } finally { | ||||||||||||||||||||
| isGenerating.done(false); | ||||||||||||||||||||
| uiStream.done(); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
Comment on lines
+148
to
+154
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. Error path leaves AI state unfinalized. When an error occurs, 🐛 Proposed fix } catch (error) {
console.error('Error in resolution search:', error);
summaryStream.error(error);
+ aiState.done({
+ ...aiState.get(),
+ messages: [
+ ...aiState.get().messages,
+ {
+ id: nanoid(),
+ role: 'assistant',
+ content: 'An error occurred during analysis.',
+ type: 'response'
+ }
+ ]
+ });
} finally {
isGenerating.done(false);
uiStream.done();
}🤖 Prompt for AI Agents
Comment on lines
+151
to
+154
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. Missing The 🐛 Proposed fix } finally {
isGenerating.done(false);
uiStream.done();
+ isCollapsed.done(true);
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
Comment on lines
+148
to
+154
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.
Since this code is user-facing and runs in the background, it’s worth normalizing the error value before streaming it. SuggestionNormalize the caught value into an } catch (err) {
const error = err instanceof Error ? err : new Error(String(err));
console.error('Error in resolution search:', error);
summaryStream.error(error);
}Reply with "@CharlieHelps yes please" if you'd like me to add a commit with this change. |
||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Start the background process without awaiting it. | ||||||||||||||||||||
| processResolutionSearch(); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Immediately update the UI stream with the BotMessage component. | ||||||||||||||||||||
| uiStream.update( | ||||||||||||||||||||
| <Section title="response"> | ||||||||||||||||||||
| <BotMessage content={summaryStream.value} /> | ||||||||||||||||||||
| </Section> | ||||||||||||||||||||
| ); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| isGenerating.done(false); | ||||||||||||||||||||
| uiStream.done(); | ||||||||||||||||||||
| return { | ||||||||||||||||||||
| id: nanoid(), | ||||||||||||||||||||
| isGenerating: isGenerating.value, | ||||||||||||||||||||
|
|
@@ -161,7 +177,8 @@ async function submit(formData?: FormData, skip?: boolean) { | |||||||||||||||||||
| message.role !== 'tool' && | ||||||||||||||||||||
| message.type !== 'followup' && | ||||||||||||||||||||
| message.type !== 'related' && | ||||||||||||||||||||
| message.type !== 'end' | ||||||||||||||||||||
| message.type !== 'end' && | ||||||||||||||||||||
| message.type !== 'resolution_search_result' | ||||||||||||||||||||
| ) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| const groupeId = nanoid() | ||||||||||||||||||||
|
|
||||||||||||||||||||
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.
🧹 Nitpick | 🔵 Trivial
Clarify purpose of 500ms delay.
The
setTimeoutdelay before finalizing AI state is also present in the main flow (line 451), but its purpose isn't documented. If this is to allow UI animations to complete, consider adding a comment explaining the rationale for maintainability.🤖 Prompt for AI Agents