Skip to content

Commit 1a7d40c

Browse files
committed
feat(toolbar): add SummaryMessagesAction for conversation summaries #383
Add new action to summarize conversations to memories.md. Includes template files for structured summaries in both English and Chinese. Also refactors CopyAllMessagesAction to use immutable variable.
1 parent 3186387 commit 1a7d40c

File tree

6 files changed

+271
-1
lines changed

6 files changed

+271
-1
lines changed

core/src/main/kotlin/cc/unitmesh/devti/gui/toolbar/CopyAllMessagesAction.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class CopyAllMessagesAction : AnAction("Copy All Messages", "Copy all messages",
4040

4141
private fun copyMessages(project: Project?) {
4242
val agentStateService = project?.getService(AgentStateService::class.java) ?: return
43-
var allText = agentStateService.getAllMessages().joinToString("\n") { it.content }
43+
val allText = agentStateService.getAllMessages().joinToString("\n") { it.content }
4444
val selection = StringSelection(allText)
4545
val clipboard = Toolkit.getDefaultToolkit().systemClipboard
4646
clipboard.setContents(selection, null)
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
package cc.unitmesh.devti.gui.toolbar
2+
3+
import cc.unitmesh.devti.AutoDevIcons
4+
import cc.unitmesh.devti.indexer.DomainDictGenerateAction
5+
import cc.unitmesh.devti.indexer.DomainDictGenerateContext
6+
import cc.unitmesh.devti.indexer.provider.LangDictProvider
7+
import cc.unitmesh.devti.indexer.usage.PromptEnhancer
8+
import cc.unitmesh.devti.llms.LlmFactory
9+
import cc.unitmesh.devti.observer.agent.AgentStateService
10+
import cc.unitmesh.devti.settings.coder.coderSetting
11+
import cc.unitmesh.devti.statusbar.AutoDevStatus
12+
import cc.unitmesh.devti.statusbar.AutoDevStatusService
13+
import cc.unitmesh.devti.template.GENIUS_CODE
14+
import cc.unitmesh.devti.template.TemplateRender
15+
import cc.unitmesh.devti.util.AutoDevCoroutineScope
16+
import com.intellij.icons.AllIcons
17+
import com.intellij.openapi.actionSystem.*
18+
import com.intellij.openapi.actionSystem.ex.CustomComponentAction
19+
import com.intellij.openapi.application.ApplicationManager
20+
import com.intellij.openapi.command.WriteCommandAction
21+
import com.intellij.openapi.diagnostic.logger
22+
import com.intellij.openapi.editor.ScrollType
23+
import com.intellij.openapi.fileEditor.FileEditorManager
24+
import com.intellij.openapi.project.Project
25+
import com.intellij.openapi.project.guessProjectDir
26+
import com.intellij.openapi.vfs.LocalFileSystem
27+
import com.intellij.ui.components.panels.Wrapper
28+
import com.intellij.util.ui.JBInsets
29+
import com.intellij.util.ui.JBUI
30+
import kotlinx.coroutines.flow.Flow
31+
import kotlinx.coroutines.flow.cancellable
32+
import kotlinx.coroutines.launch
33+
import javax.swing.JButton
34+
import javax.swing.JComponent
35+
import kotlin.io.path.createDirectories
36+
import kotlin.io.path.exists
37+
38+
class SummaryMessagesAction : AnAction("Summary Messages", "Summary all current messages to memorize.md", AllIcons.Nodes.Target),
39+
CustomComponentAction {
40+
override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.EDT
41+
override fun actionPerformed(e: AnActionEvent) {
42+
val project = e.project ?: return
43+
val baseDir = project.coderSetting.state.teamPromptsDir
44+
val presentation = e.presentation
45+
46+
copyMessages(project)
47+
48+
AutoDevCoroutineScope.scope(project).launch {
49+
try {
50+
updatePresentation(presentation, AutoDevIcons.LOADING, false)
51+
AutoDevStatusService.notifyApplication(AutoDevStatus.InProgress)
52+
val promptDir = project.guessProjectDir()!!.toNioPath().resolve(baseDir)
53+
if (!promptDir.exists()) {
54+
promptDir.createDirectories()
55+
}
56+
57+
val file = promptDir.resolve("memories.md").toFile()
58+
if (!file.exists()) {
59+
file.createNewFile()
60+
}
61+
62+
val systemPrompt = buildPrompt(project)
63+
val userPrompt = copyMessages(project)
64+
65+
val fileEditorManager = FileEditorManager.getInstance(project)
66+
ApplicationManager.getApplication().invokeAndWait {
67+
val virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file)
68+
if (virtualFile != null) {
69+
fileEditorManager.setSelectedEditor(virtualFile, "text-editor")
70+
}
71+
}
72+
73+
val editor = fileEditorManager.selectedTextEditor
74+
val stream: Flow<String> = LlmFactory.create(project).stream(systemPrompt, userPrompt)
75+
val result = StringBuilder()
76+
77+
stream.cancellable().collect { chunk ->
78+
result.append(chunk)
79+
WriteCommandAction.writeCommandAction(project).compute<Any, RuntimeException> {
80+
editor?.document?.setText(result.toString())
81+
editor?.caretModel?.moveToOffset(editor?.document?.textLength ?: 0)
82+
editor?.scrollingModel?.scrollToCaret(ScrollType.RELATIVE)
83+
}
84+
}
85+
86+
AutoDevStatusService.notifyApplication(AutoDevStatus.Done)
87+
} catch (e: Exception) {
88+
AutoDevStatusService.notifyApplication(AutoDevStatus.Error)
89+
e.printStackTrace()
90+
} finally {
91+
updatePresentation(presentation, AutoDevIcons.AI_COPILOT, true)
92+
}
93+
}
94+
}
95+
96+
override fun createCustomComponent(presentation: Presentation, place: String): JComponent {
97+
val button: JButton = object : JButton() {
98+
init {
99+
putClientProperty("ActionToolbar.smallVariant", true)
100+
putClientProperty("customButtonInsets", JBInsets(1, 1, 1, 1).asUIResource())
101+
102+
setOpaque(false)
103+
addActionListener {
104+
copyMessages(ActionToolbar.getDataContextFor(this).getData(CommonDataKeys.PROJECT))
105+
}
106+
}
107+
}
108+
109+
return Wrapper(button).also {
110+
it.setBorder(JBUI.Borders.empty(0, 10))
111+
}
112+
}
113+
114+
private fun copyMessages(project: Project?): String {
115+
val agentStateService = project?.getService(AgentStateService::class.java) ?: return ""
116+
val allText = agentStateService.getAllMessages().joinToString("\n") { it.content }
117+
return allText
118+
}
119+
120+
private fun updatePresentation(presentation: Presentation, icon: javax.swing.Icon, enabled: Boolean) {
121+
presentation.icon = icon
122+
presentation.isEnabled = enabled
123+
}
124+
125+
private suspend fun buildPrompt(project: Project): String {
126+
val names = LangDictProvider.all(project)
127+
val templateRender = TemplateRender(GENIUS_CODE)
128+
val template = templateRender.getTemplate("memory.vm")
129+
val readmeMe = PromptEnhancer.readmeFile(project)
130+
131+
val context = DomainDictGenerateContext(names.joinToString(", "), readmeMe)
132+
val prompt = templateRender.renderTemplate(template, context)
133+
return prompt
134+
}
135+
}

core/src/main/kotlin/cc/unitmesh/devti/indexer/DomainDictGenerateAction.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import kotlin.io.path.exists
2626
import com.intellij.openapi.application.ApplicationManager
2727
import com.intellij.openapi.command.WriteCommandAction
2828
import com.intellij.openapi.fileEditor.FileEditorManager
29+
import com.intellij.openapi.fileEditor.FileEditor
2930
import com.intellij.openapi.editor.ScrollType
3031
import com.intellij.openapi.vfs.LocalFileSystem
3132

core/src/main/kotlin/cc/unitmesh/devti/sketch/SketchToolWindow.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import cc.unitmesh.devti.gui.chat.ui.AutoDevInputSection
88
import cc.unitmesh.devti.gui.chat.view.MessageView
99
import cc.unitmesh.devti.gui.toolbar.CopyAllMessagesAction
1010
import cc.unitmesh.devti.gui.toolbar.NewSketchAction
11+
import cc.unitmesh.devti.gui.toolbar.SummaryMessagesAction
1112
import cc.unitmesh.devti.inline.AutoDevInlineChatService
1213
import cc.unitmesh.devti.inline.fullHeight
1314
import cc.unitmesh.devti.inline.fullWidth
@@ -158,6 +159,7 @@ open class SketchToolWindow(
158159
buttonBox.add(Box.createHorizontalGlue())
159160
buttonBox.add(createActionButton(NewSketchAction()))
160161
buttonBox.add(createActionButton(CopyAllMessagesAction()))
162+
buttonBox.add(createActionButton(SummaryMessagesAction()))
161163
cell(buttonBox).alignRight()
162164
}
163165
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
Your task is to create a detailed summary of the conversation so far, paying close attention to the user's explicit requests and your previous actions.
2+
This summary should be thorough in capturing technical details, code patterns, and architectural decisions that would be essential for continuing development work without losing context.
3+
4+
Before providing your final summary, wrap your analysis in <analysis> tags to organize your thoughts and ensure you've covered all necessary points. In your analysis process:
5+
6+
1. Chronologically analyze each message and section of the conversation. For each section thoroughly identify:
7+
- The user's explicit requests and intents
8+
- Your approach to addressing the user's requests
9+
- Key decisions, technical concepts and code patterns
10+
- Specific details like file names, full code snippets, function signatures, file edits, etc
11+
2. Double-check for technical accuracy and completeness, addressing each required element thoroughly.
12+
13+
Your summary should include the following sections:
14+
15+
1. Primary Request and Intent: Capture all of the user's explicit requests and intents in detail
16+
2. Key Technical Concepts: List all important technical concepts, technologies, and frameworks discussed.
17+
3. Files and Code Sections: Enumerate specific files and code sections examined, modified, or created. Pay special attention to the most recent messages and include full code snippets where applicable and include a summary of why this file read or edit is important.
18+
4. Problem Solving: Document problems solved and any ongoing troubleshooting efforts.
19+
5. Pending Tasks: Outline any pending tasks that you have explicitly been asked to work on.
20+
6. Current Work: Describe in detail precisely what was being worked on immediately before this summary request, paying special attention to the most recent messages from both user and assistant. Include file names and code snippets where applicable.
21+
7. Optional Next Step: List the next step that you will take that is related to the most recent work you were doing. IMPORTANT: ensure that this step is DIRECTLY in line with the user's explicit requests, and the task you were working on immediately before this summary request. If your last task was concluded, then only list next steps if they are explicitly in line with the users request. Do not start on tangential requests without confirming with the user first.
22+
8. If there is a next step, include direct quotes from the most recent conversation showing exactly what task you were working on and where you left off. This should be verbatim to ensure there's no drift in task interpretation.
23+
24+
Here's an example of how your output should be structured:
25+
26+
<example>
27+
<analysis>
28+
[Your thought process, ensuring all points are covered thoroughly and accurately]
29+
</analysis>
30+
31+
<summary>
32+
1. Primary Request and Intent:
33+
[Detailed description]
34+
35+
2. Key Technical Concepts:
36+
- [Concept 1]
37+
- [Concept 2]
38+
- [...]
39+
40+
3. Files and Code Sections:
41+
- [File Name 1]
42+
- [Summary of why this file is important]
43+
- [Summary of the changes made to this file, if any]
44+
- [Important Code Snippet]
45+
- [File Name 2]
46+
- [Important Code Snippet]
47+
- [...]
48+
49+
4. Problem Solving:
50+
[Description of solved problems and ongoing troubleshooting]
51+
52+
5. Pending Tasks:
53+
- [Task 1]
54+
- [Task 2]
55+
- [...]
56+
57+
6. Current Work:
58+
[Precise description of current work]
59+
60+
7. Optional Next Step:
61+
[Optional Next step to take]
62+
63+
</summary>
64+
</example>
65+
66+
Please provide your summary based on the conversation so far, following this structure and ensuring precision and thoroughness in your response.
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
Your task is to create a detailed summary of the conversation so far, paying close attention to the user's explicit requests and your previous actions.
2+
This summary should be thorough in capturing technical details, code patterns, and architectural decisions that would be essential for continuing development work without losing context.
3+
4+
Before providing your final summary, wrap your analysis in <analysis> tags to organize your thoughts and ensure you've covered all necessary points. In your analysis process:
5+
6+
1. Chronologically analyze each message and section of the conversation. For each section thoroughly identify:
7+
- The user's explicit requests and intents
8+
- Your approach to addressing the user's requests
9+
- Key decisions, technical concepts and code patterns
10+
- Specific details like file names, full code snippets, function signatures, file edits, etc
11+
2. Double-check for technical accuracy and completeness, addressing each required element thoroughly.
12+
13+
Your summary should include the following sections:
14+
15+
1. Primary Request and Intent: Capture all of the user's explicit requests and intents in detail
16+
2. Key Technical Concepts: List all important technical concepts, technologies, and frameworks discussed.
17+
3. Files and Code Sections: Enumerate specific files and code sections examined, modified, or created. Pay special attention to the most recent messages and include full code snippets where applicable and include a summary of why this file read or edit is important.
18+
4. Problem Solving: Document problems solved and any ongoing troubleshooting efforts.
19+
5. Pending Tasks: Outline any pending tasks that you have explicitly been asked to work on.
20+
6. Current Work: Describe in detail precisely what was being worked on immediately before this summary request, paying special attention to the most recent messages from both user and assistant. Include file names and code snippets where applicable.
21+
7. Optional Next Step: List the next step that you will take that is related to the most recent work you were doing. IMPORTANT: ensure that this step is DIRECTLY in line with the user's explicit requests, and the task you were working on immediately before this summary request. If your last task was concluded, then only list next steps if they are explicitly in line with the users request. Do not start on tangential requests without confirming with the user first.
22+
8. If there is a next step, include direct quotes from the most recent conversation showing exactly what task you were working on and where you left off. This should be verbatim to ensure there's no drift in task interpretation.
23+
24+
Here's an example of how your output should be structured:
25+
26+
<example>
27+
<analysis>
28+
[Your thought process, ensuring all points are covered thoroughly and accurately]
29+
</analysis>
30+
31+
<summary>
32+
1. Primary Request and Intent:
33+
[Detailed description]
34+
35+
2. Key Technical Concepts:
36+
- [Concept 1]
37+
- [Concept 2]
38+
- [...]
39+
40+
3. Files and Code Sections:
41+
- [File Name 1]
42+
- [Summary of why this file is important]
43+
- [Summary of the changes made to this file, if any]
44+
- [Important Code Snippet]
45+
- [File Name 2]
46+
- [Important Code Snippet]
47+
- [...]
48+
49+
4. Problem Solving:
50+
[Description of solved problems and ongoing troubleshooting]
51+
52+
5. Pending Tasks:
53+
- [Task 1]
54+
- [Task 2]
55+
- [...]
56+
57+
6. Current Work:
58+
[Precise description of current work]
59+
60+
7. Optional Next Step:
61+
[Optional Next step to take]
62+
63+
</summary>
64+
</example>
65+
66+
Please provide your summary based on the conversation so far, following this structure and ensuring precision and thoroughness in your response.

0 commit comments

Comments
 (0)