@shareai-lab/kode 1.0.70 → 1.0.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (278) hide show
  1. package/README.md +342 -75
  2. package/README.zh-CN.md +292 -0
  3. package/cli.js +62 -0
  4. package/package.json +49 -25
  5. package/scripts/postinstall.js +56 -0
  6. package/src/ProjectOnboarding.tsx +198 -0
  7. package/src/Tool.ts +82 -0
  8. package/src/commands/agents.tsx +3401 -0
  9. package/src/commands/approvedTools.ts +53 -0
  10. package/src/commands/bug.tsx +20 -0
  11. package/src/commands/clear.ts +43 -0
  12. package/src/commands/compact.ts +120 -0
  13. package/src/commands/config.tsx +19 -0
  14. package/src/commands/cost.ts +18 -0
  15. package/src/commands/ctx_viz.ts +209 -0
  16. package/src/commands/doctor.ts +24 -0
  17. package/src/commands/help.tsx +19 -0
  18. package/src/commands/init.ts +37 -0
  19. package/src/commands/listen.ts +42 -0
  20. package/src/commands/login.tsx +51 -0
  21. package/src/commands/logout.tsx +40 -0
  22. package/src/commands/mcp.ts +41 -0
  23. package/src/commands/model.tsx +40 -0
  24. package/src/commands/modelstatus.tsx +20 -0
  25. package/src/commands/onboarding.tsx +34 -0
  26. package/src/commands/pr_comments.ts +59 -0
  27. package/src/commands/refreshCommands.ts +54 -0
  28. package/src/commands/release-notes.ts +34 -0
  29. package/src/commands/resume.tsx +31 -0
  30. package/src/commands/review.ts +49 -0
  31. package/src/commands/terminalSetup.ts +221 -0
  32. package/src/commands.ts +139 -0
  33. package/src/components/ApproveApiKey.tsx +93 -0
  34. package/src/components/AsciiLogo.tsx +13 -0
  35. package/src/components/AutoUpdater.tsx +148 -0
  36. package/src/components/Bug.tsx +367 -0
  37. package/src/components/Config.tsx +293 -0
  38. package/src/components/ConsoleOAuthFlow.tsx +327 -0
  39. package/src/components/Cost.tsx +23 -0
  40. package/src/components/CostThresholdDialog.tsx +46 -0
  41. package/src/components/CustomSelect/option-map.ts +42 -0
  42. package/src/components/CustomSelect/select-option.tsx +78 -0
  43. package/src/components/CustomSelect/select.tsx +152 -0
  44. package/src/components/CustomSelect/theme.ts +45 -0
  45. package/src/components/CustomSelect/use-select-state.ts +414 -0
  46. package/src/components/CustomSelect/use-select.ts +35 -0
  47. package/src/components/FallbackToolUseRejectedMessage.tsx +15 -0
  48. package/src/components/FileEditToolUpdatedMessage.tsx +66 -0
  49. package/src/components/Help.tsx +215 -0
  50. package/src/components/HighlightedCode.tsx +33 -0
  51. package/src/components/InvalidConfigDialog.tsx +113 -0
  52. package/src/components/Link.tsx +32 -0
  53. package/src/components/LogSelector.tsx +86 -0
  54. package/src/components/Logo.tsx +145 -0
  55. package/src/components/MCPServerApprovalDialog.tsx +100 -0
  56. package/src/components/MCPServerDialogCopy.tsx +25 -0
  57. package/src/components/MCPServerMultiselectDialog.tsx +109 -0
  58. package/src/components/Message.tsx +221 -0
  59. package/src/components/MessageResponse.tsx +15 -0
  60. package/src/components/MessageSelector.tsx +211 -0
  61. package/src/components/ModeIndicator.tsx +88 -0
  62. package/src/components/ModelConfig.tsx +301 -0
  63. package/src/components/ModelListManager.tsx +227 -0
  64. package/src/components/ModelSelector.tsx +3386 -0
  65. package/src/components/ModelStatusDisplay.tsx +230 -0
  66. package/src/components/Onboarding.tsx +274 -0
  67. package/src/components/PressEnterToContinue.tsx +11 -0
  68. package/src/components/PromptInput.tsx +740 -0
  69. package/src/components/SentryErrorBoundary.ts +33 -0
  70. package/src/components/Spinner.tsx +129 -0
  71. package/src/components/StickerRequestForm.tsx +16 -0
  72. package/src/components/StructuredDiff.tsx +191 -0
  73. package/src/components/TextInput.tsx +259 -0
  74. package/src/components/TodoItem.tsx +11 -0
  75. package/src/components/TokenWarning.tsx +31 -0
  76. package/src/components/ToolUseLoader.tsx +40 -0
  77. package/src/components/TrustDialog.tsx +106 -0
  78. package/src/components/binary-feedback/BinaryFeedback.tsx +63 -0
  79. package/src/components/binary-feedback/BinaryFeedbackOption.tsx +111 -0
  80. package/src/components/binary-feedback/BinaryFeedbackView.tsx +172 -0
  81. package/src/components/binary-feedback/utils.ts +220 -0
  82. package/src/components/messages/AssistantBashOutputMessage.tsx +22 -0
  83. package/src/components/messages/AssistantLocalCommandOutputMessage.tsx +49 -0
  84. package/src/components/messages/AssistantRedactedThinkingMessage.tsx +19 -0
  85. package/src/components/messages/AssistantTextMessage.tsx +144 -0
  86. package/src/components/messages/AssistantThinkingMessage.tsx +40 -0
  87. package/src/components/messages/AssistantToolUseMessage.tsx +133 -0
  88. package/src/components/messages/TaskProgressMessage.tsx +32 -0
  89. package/src/components/messages/TaskToolMessage.tsx +58 -0
  90. package/src/components/messages/UserBashInputMessage.tsx +28 -0
  91. package/src/components/messages/UserCommandMessage.tsx +30 -0
  92. package/src/components/messages/UserKodingInputMessage.tsx +28 -0
  93. package/src/components/messages/UserPromptMessage.tsx +35 -0
  94. package/src/components/messages/UserTextMessage.tsx +39 -0
  95. package/src/components/messages/UserToolResultMessage/UserToolCanceledMessage.tsx +12 -0
  96. package/src/components/messages/UserToolResultMessage/UserToolErrorMessage.tsx +36 -0
  97. package/src/components/messages/UserToolResultMessage/UserToolRejectMessage.tsx +31 -0
  98. package/src/components/messages/UserToolResultMessage/UserToolResultMessage.tsx +57 -0
  99. package/src/components/messages/UserToolResultMessage/UserToolSuccessMessage.tsx +35 -0
  100. package/src/components/messages/UserToolResultMessage/utils.tsx +56 -0
  101. package/src/components/permissions/BashPermissionRequest/BashPermissionRequest.tsx +121 -0
  102. package/src/components/permissions/FallbackPermissionRequest.tsx +153 -0
  103. package/src/components/permissions/FileEditPermissionRequest/FileEditPermissionRequest.tsx +182 -0
  104. package/src/components/permissions/FileEditPermissionRequest/FileEditToolDiff.tsx +77 -0
  105. package/src/components/permissions/FileWritePermissionRequest/FileWritePermissionRequest.tsx +164 -0
  106. package/src/components/permissions/FileWritePermissionRequest/FileWriteToolDiff.tsx +83 -0
  107. package/src/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.tsx +240 -0
  108. package/src/components/permissions/PermissionRequest.tsx +101 -0
  109. package/src/components/permissions/PermissionRequestTitle.tsx +69 -0
  110. package/src/components/permissions/hooks.ts +44 -0
  111. package/src/components/permissions/toolUseOptions.ts +59 -0
  112. package/src/components/permissions/utils.ts +23 -0
  113. package/src/constants/betas.ts +5 -0
  114. package/src/constants/claude-asterisk-ascii-art.tsx +238 -0
  115. package/src/constants/figures.ts +4 -0
  116. package/src/constants/keys.ts +3 -0
  117. package/src/constants/macros.ts +8 -0
  118. package/src/constants/modelCapabilities.ts +179 -0
  119. package/src/constants/models.ts +1025 -0
  120. package/src/constants/oauth.ts +18 -0
  121. package/src/constants/product.ts +17 -0
  122. package/src/constants/prompts.ts +177 -0
  123. package/src/constants/releaseNotes.ts +7 -0
  124. package/src/context/PermissionContext.tsx +149 -0
  125. package/src/context.ts +278 -0
  126. package/src/cost-tracker.ts +84 -0
  127. package/src/entrypoints/cli.tsx +1518 -0
  128. package/src/entrypoints/mcp.ts +176 -0
  129. package/src/history.ts +25 -0
  130. package/src/hooks/useApiKeyVerification.ts +59 -0
  131. package/src/hooks/useArrowKeyHistory.ts +55 -0
  132. package/src/hooks/useCanUseTool.ts +138 -0
  133. package/src/hooks/useCancelRequest.ts +39 -0
  134. package/src/hooks/useDoublePress.ts +42 -0
  135. package/src/hooks/useExitOnCtrlCD.ts +31 -0
  136. package/src/hooks/useInterval.ts +25 -0
  137. package/src/hooks/useLogMessages.ts +16 -0
  138. package/src/hooks/useLogStartupTime.ts +12 -0
  139. package/src/hooks/useNotifyAfterTimeout.ts +65 -0
  140. package/src/hooks/usePermissionRequestLogging.ts +44 -0
  141. package/src/hooks/useTerminalSize.ts +49 -0
  142. package/src/hooks/useTextInput.ts +318 -0
  143. package/src/hooks/useUnifiedCompletion.ts +1404 -0
  144. package/src/messages.ts +38 -0
  145. package/src/permissions.ts +268 -0
  146. package/src/query.ts +707 -0
  147. package/src/screens/ConfigureNpmPrefix.tsx +197 -0
  148. package/src/screens/Doctor.tsx +219 -0
  149. package/src/screens/LogList.tsx +68 -0
  150. package/src/screens/REPL.tsx +798 -0
  151. package/src/screens/ResumeConversation.tsx +68 -0
  152. package/src/services/adapters/base.ts +38 -0
  153. package/src/services/adapters/chatCompletions.ts +90 -0
  154. package/src/services/adapters/responsesAPI.ts +170 -0
  155. package/src/services/browserMocks.ts +66 -0
  156. package/src/services/claude.ts +2083 -0
  157. package/src/services/customCommands.ts +704 -0
  158. package/src/services/fileFreshness.ts +377 -0
  159. package/src/services/gpt5ConnectionTest.ts +340 -0
  160. package/src/services/mcpClient.ts +564 -0
  161. package/src/services/mcpServerApproval.tsx +50 -0
  162. package/src/services/mentionProcessor.ts +273 -0
  163. package/src/services/modelAdapterFactory.ts +69 -0
  164. package/src/services/notifier.ts +40 -0
  165. package/src/services/oauth.ts +357 -0
  166. package/src/services/openai.ts +1305 -0
  167. package/src/services/responseStateManager.ts +90 -0
  168. package/src/services/sentry.ts +3 -0
  169. package/src/services/statsig.ts +171 -0
  170. package/src/services/statsigStorage.ts +86 -0
  171. package/src/services/systemReminder.ts +507 -0
  172. package/src/services/vcr.ts +161 -0
  173. package/src/test/testAdapters.ts +96 -0
  174. package/src/tools/ArchitectTool/ArchitectTool.tsx +122 -0
  175. package/src/tools/ArchitectTool/prompt.ts +15 -0
  176. package/src/tools/AskExpertModelTool/AskExpertModelTool.tsx +569 -0
  177. package/src/tools/BashTool/BashTool.tsx +243 -0
  178. package/src/tools/BashTool/BashToolResultMessage.tsx +38 -0
  179. package/src/tools/BashTool/OutputLine.tsx +49 -0
  180. package/src/tools/BashTool/prompt.ts +174 -0
  181. package/src/tools/BashTool/utils.ts +56 -0
  182. package/src/tools/FileEditTool/FileEditTool.tsx +315 -0
  183. package/src/tools/FileEditTool/prompt.ts +51 -0
  184. package/src/tools/FileEditTool/utils.ts +58 -0
  185. package/src/tools/FileReadTool/FileReadTool.tsx +404 -0
  186. package/src/tools/FileReadTool/prompt.ts +7 -0
  187. package/src/tools/FileWriteTool/FileWriteTool.tsx +297 -0
  188. package/src/tools/FileWriteTool/prompt.ts +10 -0
  189. package/src/tools/GlobTool/GlobTool.tsx +119 -0
  190. package/src/tools/GlobTool/prompt.ts +8 -0
  191. package/src/tools/GrepTool/GrepTool.tsx +147 -0
  192. package/src/tools/GrepTool/prompt.ts +11 -0
  193. package/src/tools/MCPTool/MCPTool.tsx +107 -0
  194. package/src/tools/MCPTool/prompt.ts +3 -0
  195. package/src/tools/MemoryReadTool/MemoryReadTool.tsx +127 -0
  196. package/src/tools/MemoryReadTool/prompt.ts +3 -0
  197. package/src/tools/MemoryWriteTool/MemoryWriteTool.tsx +89 -0
  198. package/src/tools/MemoryWriteTool/prompt.ts +3 -0
  199. package/src/tools/MultiEditTool/MultiEditTool.tsx +366 -0
  200. package/src/tools/MultiEditTool/prompt.ts +45 -0
  201. package/src/tools/NotebookEditTool/NotebookEditTool.tsx +298 -0
  202. package/src/tools/NotebookEditTool/prompt.ts +3 -0
  203. package/src/tools/NotebookReadTool/NotebookReadTool.tsx +258 -0
  204. package/src/tools/NotebookReadTool/prompt.ts +3 -0
  205. package/src/tools/StickerRequestTool/StickerRequestTool.tsx +93 -0
  206. package/src/tools/StickerRequestTool/prompt.ts +19 -0
  207. package/src/tools/TaskTool/TaskTool.tsx +466 -0
  208. package/src/tools/TaskTool/constants.ts +1 -0
  209. package/src/tools/TaskTool/prompt.ts +92 -0
  210. package/src/tools/ThinkTool/ThinkTool.tsx +54 -0
  211. package/src/tools/ThinkTool/prompt.ts +12 -0
  212. package/src/tools/TodoWriteTool/TodoWriteTool.tsx +290 -0
  213. package/src/tools/TodoWriteTool/prompt.ts +63 -0
  214. package/src/tools/lsTool/lsTool.tsx +272 -0
  215. package/src/tools/lsTool/prompt.ts +2 -0
  216. package/src/tools.ts +63 -0
  217. package/src/types/PermissionMode.ts +120 -0
  218. package/src/types/RequestContext.ts +72 -0
  219. package/src/types/conversation.ts +51 -0
  220. package/src/types/logs.ts +58 -0
  221. package/src/types/modelCapabilities.ts +64 -0
  222. package/src/types/notebook.ts +87 -0
  223. package/src/utils/Cursor.ts +436 -0
  224. package/src/utils/PersistentShell.ts +373 -0
  225. package/src/utils/advancedFuzzyMatcher.ts +290 -0
  226. package/src/utils/agentLoader.ts +284 -0
  227. package/src/utils/agentStorage.ts +97 -0
  228. package/src/utils/array.ts +3 -0
  229. package/src/utils/ask.tsx +99 -0
  230. package/src/utils/auth.ts +13 -0
  231. package/src/utils/autoCompactCore.ts +223 -0
  232. package/src/utils/autoUpdater.ts +318 -0
  233. package/src/utils/betas.ts +20 -0
  234. package/src/utils/browser.ts +14 -0
  235. package/src/utils/cleanup.ts +72 -0
  236. package/src/utils/commands.ts +261 -0
  237. package/src/utils/commonUnixCommands.ts +161 -0
  238. package/src/utils/config.ts +942 -0
  239. package/src/utils/conversationRecovery.ts +55 -0
  240. package/src/utils/debugLogger.ts +1123 -0
  241. package/src/utils/diff.ts +42 -0
  242. package/src/utils/env.ts +57 -0
  243. package/src/utils/errors.ts +21 -0
  244. package/src/utils/exampleCommands.ts +109 -0
  245. package/src/utils/execFileNoThrow.ts +51 -0
  246. package/src/utils/expertChatStorage.ts +136 -0
  247. package/src/utils/file.ts +402 -0
  248. package/src/utils/fileRecoveryCore.ts +71 -0
  249. package/src/utils/format.tsx +44 -0
  250. package/src/utils/fuzzyMatcher.ts +328 -0
  251. package/src/utils/generators.ts +62 -0
  252. package/src/utils/git.ts +92 -0
  253. package/src/utils/globalLogger.ts +77 -0
  254. package/src/utils/http.ts +10 -0
  255. package/src/utils/imagePaste.ts +38 -0
  256. package/src/utils/json.ts +13 -0
  257. package/src/utils/log.ts +382 -0
  258. package/src/utils/markdown.ts +213 -0
  259. package/src/utils/messageContextManager.ts +289 -0
  260. package/src/utils/messages.tsx +939 -0
  261. package/src/utils/model.ts +836 -0
  262. package/src/utils/permissions/filesystem.ts +118 -0
  263. package/src/utils/responseState.ts +23 -0
  264. package/src/utils/ripgrep.ts +167 -0
  265. package/src/utils/secureFile.ts +559 -0
  266. package/src/utils/sessionState.ts +49 -0
  267. package/src/utils/state.ts +25 -0
  268. package/src/utils/style.ts +29 -0
  269. package/src/utils/terminal.ts +50 -0
  270. package/src/utils/theme.ts +133 -0
  271. package/src/utils/thinking.ts +144 -0
  272. package/src/utils/todoStorage.ts +431 -0
  273. package/src/utils/tokens.ts +43 -0
  274. package/src/utils/toolExecutionController.ts +163 -0
  275. package/src/utils/unaryLogging.ts +26 -0
  276. package/src/utils/user.ts +37 -0
  277. package/src/utils/validate.ts +165 -0
  278. package/cli.mjs +0 -1803
@@ -0,0 +1,289 @@
1
+ import { Message } from '../query'
2
+ import { countTokens } from './tokens'
3
+
4
+ export interface MessageRetentionStrategy {
5
+ type:
6
+ | 'preserve_recent'
7
+ | 'preserve_important'
8
+ | 'smart_compression'
9
+ | 'auto_compact'
10
+ maxTokens: number
11
+ preserveCount?: number
12
+ importanceThreshold?: number
13
+ }
14
+
15
+ export interface MessageTruncationResult {
16
+ truncatedMessages: Message[]
17
+ removedCount: number
18
+ preservedTokens: number
19
+ strategy: string
20
+ summary?: string
21
+ }
22
+
23
+ /**
24
+ * Smart message truncation for context-limited models
25
+ * Implements multiple strategies for preserving important conversation content
26
+ */
27
+ export class MessageContextManager {
28
+ /**
29
+ * Truncate messages intelligently based on strategy and token limit
30
+ */
31
+ async truncateMessages(
32
+ messages: Message[],
33
+ strategy: MessageRetentionStrategy,
34
+ ): Promise<MessageTruncationResult> {
35
+ switch (strategy.type) {
36
+ case 'preserve_recent':
37
+ return this.preserveRecentMessages(messages, strategy)
38
+ case 'preserve_important':
39
+ return this.preserveImportantMessages(messages, strategy)
40
+ case 'smart_compression':
41
+ return this.smartCompressionStrategy(messages, strategy)
42
+ case 'auto_compact':
43
+ return this.autoCompactStrategy(messages, strategy)
44
+ default:
45
+ return this.preserveRecentMessages(messages, strategy)
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Strategy 1: Preserve most recent messages
51
+ */
52
+ private preserveRecentMessages(
53
+ messages: Message[],
54
+ strategy: MessageRetentionStrategy,
55
+ ): MessageTruncationResult {
56
+ const preserveCount =
57
+ strategy.preserveCount || this.estimateMessageCount(strategy.maxTokens)
58
+ const truncatedMessages = messages.slice(-preserveCount)
59
+ const removedCount = messages.length - truncatedMessages.length
60
+
61
+ return {
62
+ truncatedMessages,
63
+ removedCount,
64
+ preservedTokens: countTokens(truncatedMessages),
65
+ strategy: `Preserved last ${preserveCount} messages`,
66
+ summary:
67
+ removedCount > 0
68
+ ? `Removed ${removedCount} older messages to fit context window`
69
+ : 'No messages removed',
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Strategy 2: Preserve important messages (errors, user queries, recent context)
75
+ */
76
+ private preserveImportantMessages(
77
+ messages: Message[],
78
+ strategy: MessageRetentionStrategy,
79
+ ): MessageTruncationResult {
80
+ const importantMessages: Message[] = []
81
+ const recentMessages: Message[] = []
82
+
83
+ // Always preserve the last few messages for context continuity
84
+ const recentCount = Math.min(5, messages.length)
85
+ recentMessages.push(...messages.slice(-recentCount))
86
+
87
+ // Identify important messages (errors, tool failures, user decisions)
88
+ for (let i = 0; i < messages.length - recentCount; i++) {
89
+ const message = messages[i]
90
+ if (this.isImportantMessage(message)) {
91
+ importantMessages.push(message)
92
+ }
93
+ }
94
+
95
+ // Combine and deduplicate
96
+ const combinedMessages = [
97
+ ...importantMessages,
98
+ ...recentMessages.filter(
99
+ msg => !importantMessages.some(imp => this.messagesEqual(imp, msg)),
100
+ ),
101
+ ]
102
+
103
+ // Sort by original order
104
+ const truncatedMessages = combinedMessages.sort((a, b) => {
105
+ const aIndex = messages.indexOf(a)
106
+ const bIndex = messages.indexOf(b)
107
+ return aIndex - bIndex
108
+ })
109
+
110
+ const removedCount = messages.length - truncatedMessages.length
111
+
112
+ return {
113
+ truncatedMessages,
114
+ removedCount,
115
+ preservedTokens: countTokens(truncatedMessages),
116
+ strategy: `Preserved ${importantMessages.length} important + ${recentMessages.length} recent messages`,
117
+ summary: `Kept critical errors, user decisions, and recent context (${removedCount} messages archived)`,
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Strategy 3: Smart compression with summary
123
+ */
124
+ private async smartCompressionStrategy(
125
+ messages: Message[],
126
+ strategy: MessageRetentionStrategy,
127
+ ): Promise<MessageTruncationResult> {
128
+ const recentCount = Math.min(10, Math.floor(messages.length * 0.3))
129
+ const recentMessages = messages.slice(-recentCount)
130
+ const olderMessages = messages.slice(0, -recentCount)
131
+
132
+ // Create a summary of older messages
133
+ const summary = this.createMessagesSummary(olderMessages)
134
+
135
+ // Create a summary message
136
+ const summaryMessage: Message = {
137
+ type: 'assistant',
138
+ message: {
139
+ role: 'assistant',
140
+ content: [
141
+ {
142
+ type: 'text',
143
+ text: `[CONVERSATION SUMMARY - ${olderMessages.length} messages compressed]\n\n${summary}\n\n[END SUMMARY - Recent context follows...]`,
144
+ },
145
+ ],
146
+ },
147
+ }
148
+
149
+ const truncatedMessages = [summaryMessage, ...recentMessages]
150
+
151
+ return {
152
+ truncatedMessages,
153
+ removedCount: olderMessages.length,
154
+ preservedTokens: countTokens(truncatedMessages),
155
+ strategy: `Compressed ${olderMessages.length} messages + preserved ${recentCount} recent`,
156
+ summary: `Created intelligent summary of conversation history`,
157
+ }
158
+ }
159
+
160
+ /**
161
+ * Strategy 4: Use existing auto-compact mechanism
162
+ */
163
+ private async autoCompactStrategy(
164
+ messages: Message[],
165
+ strategy: MessageRetentionStrategy,
166
+ ): Promise<MessageTruncationResult> {
167
+ // This would integrate with the existing autoCompactCore.ts
168
+ // For now, fallback to preserve_recent
169
+ return this.preserveRecentMessages(messages, strategy)
170
+ }
171
+
172
+ /**
173
+ * Helper: Estimate how many messages fit in token budget
174
+ */
175
+ private estimateMessageCount(maxTokens: number): number {
176
+ const avgTokensPerMessage = 150 // Conservative estimate
177
+ return Math.max(3, Math.floor(maxTokens / avgTokensPerMessage))
178
+ }
179
+
180
+ /**
181
+ * Helper: Determine if a message is important
182
+ */
183
+ private isImportantMessage(message: Message): boolean {
184
+ if (message.type === 'user') return true // User messages are always important
185
+
186
+ if (message.type === 'assistant') {
187
+ const content = message.message.content
188
+ if (Array.isArray(content)) {
189
+ const textContent = content
190
+ .filter(c => c.type === 'text')
191
+ .map(c => c.text)
192
+ .join(' ')
193
+ .toLowerCase()
194
+
195
+ // Mark as important if contains error keywords
196
+ return (
197
+ textContent.includes('error') ||
198
+ textContent.includes('failed') ||
199
+ textContent.includes('warning') ||
200
+ textContent.includes('critical') ||
201
+ textContent.includes('issue')
202
+ )
203
+ }
204
+ }
205
+
206
+ return false
207
+ }
208
+
209
+ /**
210
+ * Helper: Check if two messages are equal
211
+ */
212
+ private messagesEqual(a: Message, b: Message): boolean {
213
+ return JSON.stringify(a) === JSON.stringify(b)
214
+ }
215
+
216
+ /**
217
+ * Helper: Create summary of message sequence
218
+ */
219
+ private createMessagesSummary(messages: Message[]): string {
220
+ const userMessages = messages.filter(m => m.type === 'user').length
221
+ const assistantMessages = messages.filter(
222
+ m => m.type === 'assistant',
223
+ ).length
224
+ const toolUses = messages.filter(
225
+ m =>
226
+ m.type === 'assistant' &&
227
+ Array.isArray(m.message.content) &&
228
+ m.message.content.some(c => c.type === 'tool_use'),
229
+ ).length
230
+
231
+ const topics: string[] = []
232
+
233
+ // Extract key topics from user messages
234
+ messages.forEach(msg => {
235
+ if (msg.type === 'user' && Array.isArray(msg.message.content)) {
236
+ const text = msg.message.content
237
+ .filter(c => c.type === 'text')
238
+ .map(c => c.text)
239
+ .join(' ')
240
+
241
+ // Simple keyword extraction (could be enhanced with NLP)
242
+ if (text.includes('error') || text.includes('bug'))
243
+ topics.push('debugging')
244
+ if (text.includes('implement') || text.includes('create'))
245
+ topics.push('implementation')
246
+ if (text.includes('explain') || text.includes('understand'))
247
+ topics.push('explanation')
248
+ if (text.includes('fix') || text.includes('solve'))
249
+ topics.push('problem-solving')
250
+ }
251
+ })
252
+
253
+ const uniqueTopics = [...new Set(topics)]
254
+
255
+ return `Previous conversation included ${userMessages} user messages and ${assistantMessages} assistant responses, with ${toolUses} tool invocations. Key topics: ${uniqueTopics.join(', ') || 'general discussion'}.`
256
+ }
257
+ }
258
+
259
+ /**
260
+ * Factory function to create appropriate retention strategy
261
+ */
262
+ export function createRetentionStrategy(
263
+ targetContextLength: number,
264
+ currentTokens: number,
265
+ userPreference: 'aggressive' | 'balanced' | 'conservative' = 'balanced',
266
+ ): MessageRetentionStrategy {
267
+ const maxTokens = Math.floor(targetContextLength * 0.7) // Leave room for new conversation
268
+
269
+ switch (userPreference) {
270
+ case 'aggressive':
271
+ return {
272
+ type: 'preserve_recent',
273
+ maxTokens,
274
+ preserveCount: Math.max(3, Math.floor(maxTokens / 200)),
275
+ }
276
+ case 'conservative':
277
+ return {
278
+ type: 'smart_compression',
279
+ maxTokens,
280
+ }
281
+ case 'balanced':
282
+ default:
283
+ return {
284
+ type: 'preserve_important',
285
+ maxTokens,
286
+ preserveCount: Math.max(5, Math.floor(maxTokens / 150)),
287
+ }
288
+ }
289
+ }