message.ts 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. import { z } from "zod"
  2. /**
  3. * ClineAsk
  4. */
  5. /**
  6. * Array of possible ask types that the LLM can use to request user interaction or approval.
  7. * These represent different scenarios where the assistant needs user input to proceed.
  8. *
  9. * @constant
  10. * @readonly
  11. *
  12. * Ask type descriptions:
  13. * - `followup`: LLM asks a clarifying question to gather more information needed to complete the task
  14. * - `command`: Permission to execute a terminal/shell command
  15. * - `command_output`: Permission to read the output from a previously executed command
  16. * - `completion_result`: Task has been completed, awaiting user feedback or a new task
  17. * - `tool`: Permission to use a tool for file operations (read, write, search, etc.)
  18. * - `api_req_failed`: API request failed, asking user whether to retry
  19. * - `resume_task`: Confirmation needed to resume a previously paused task
  20. * - `resume_completed_task`: Confirmation needed to resume a task that was already marked as completed
  21. * - `mistake_limit_reached`: Too many errors encountered, needs user guidance on how to proceed
  22. * - `browser_action_launch`: Permission to open or interact with a browser
  23. * - `use_mcp_server`: Permission to use Model Context Protocol (MCP) server functionality
  24. * - `auto_approval_max_req_reached`: Auto-approval limit has been reached, manual approval required
  25. */
  26. export const clineAsks = [
  27. "followup",
  28. "command",
  29. "command_output",
  30. "completion_result",
  31. "tool",
  32. "api_req_failed",
  33. "resume_task",
  34. "resume_completed_task",
  35. "mistake_limit_reached",
  36. "browser_action_launch",
  37. "use_mcp_server",
  38. "auto_approval_max_req_reached",
  39. ] as const
  40. export const clineAskSchema = z.enum(clineAsks)
  41. export type ClineAsk = z.infer<typeof clineAskSchema>
  42. /**
  43. * IdleAsk
  44. *
  45. * Asks that put the task into an "idle" state.
  46. */
  47. export const idleAsks = [
  48. "completion_result",
  49. "api_req_failed",
  50. "resume_completed_task",
  51. "mistake_limit_reached",
  52. "auto_approval_max_req_reached",
  53. ] as const satisfies readonly ClineAsk[]
  54. export type IdleAsk = (typeof idleAsks)[number]
  55. export function isIdleAsk(ask: ClineAsk): ask is IdleAsk {
  56. return (idleAsks as readonly ClineAsk[]).includes(ask)
  57. }
  58. /**
  59. * ResumableAsk
  60. *
  61. * Asks that put the task into an "resumable" state.
  62. */
  63. export const resumableAsks = ["resume_task"] as const satisfies readonly ClineAsk[]
  64. export type ResumableAsk = (typeof resumableAsks)[number]
  65. export function isResumableAsk(ask: ClineAsk): ask is ResumableAsk {
  66. return (resumableAsks as readonly ClineAsk[]).includes(ask)
  67. }
  68. /**
  69. * InteractiveAsk
  70. *
  71. * Asks that put the task into an "user interaction required" state.
  72. */
  73. export const interactiveAsks = [
  74. "followup",
  75. "command",
  76. "tool",
  77. "browser_action_launch",
  78. "use_mcp_server",
  79. ] as const satisfies readonly ClineAsk[]
  80. export type InteractiveAsk = (typeof interactiveAsks)[number]
  81. export function isInteractiveAsk(ask: ClineAsk): ask is InteractiveAsk {
  82. return (interactiveAsks as readonly ClineAsk[]).includes(ask)
  83. }
  84. /**
  85. * NonBlockingAsk
  86. *
  87. * Asks that are not associated with an actual approval, and are only used
  88. * to update chat messages.
  89. */
  90. export const nonBlockingAsks = ["command_output"] as const satisfies readonly ClineAsk[]
  91. export type NonBlockingAsk = (typeof nonBlockingAsks)[number]
  92. export function isNonBlockingAsk(ask: ClineAsk): ask is NonBlockingAsk {
  93. return (nonBlockingAsks as readonly ClineAsk[]).includes(ask)
  94. }
  95. /**
  96. * ClineSay
  97. */
  98. /**
  99. * Array of possible say types that represent different kinds of messages the assistant can send.
  100. * These are used to categorize and handle various types of communication from the LLM to the user.
  101. *
  102. * @constant
  103. * @readonly
  104. *
  105. * Say type descriptions:
  106. * - `error`: General error message
  107. * - `api_req_started`: Indicates an API request has been initiated
  108. * - `api_req_finished`: Indicates an API request has completed successfully
  109. * - `api_req_retried`: Indicates an API request is being retried after a failure
  110. * - `api_req_retry_delayed`: Indicates an API request retry has been delayed
  111. * - `api_req_rate_limit_wait`: Indicates a configured rate-limit wait (not an error)
  112. * - `api_req_deleted`: Indicates an API request has been deleted/cancelled
  113. * - `text`: General text message or assistant response
  114. * - `reasoning`: Assistant's reasoning or thought process (often hidden from user)
  115. * - `completion_result`: Final result of task completion
  116. * - `user_feedback`: Message containing user feedback
  117. * - `user_feedback_diff`: Diff-formatted feedback from user showing requested changes
  118. * - `command_output`: Output from an executed command
  119. * - `shell_integration_warning`: Warning about shell integration issues or limitations
  120. * - `browser_action`: Action performed in the browser
  121. * - `browser_action_result`: Result of a browser action
  122. * - `mcp_server_request_started`: MCP server request has been initiated
  123. * - `mcp_server_response`: Response received from MCP server
  124. * - `subtask_result`: Result of a completed subtask
  125. * - `checkpoint_saved`: Indicates a checkpoint has been saved
  126. * - `rooignore_error`: Error related to .rooignore file processing
  127. * - `diff_error`: Error occurred while applying a diff/patch
  128. * - `condense_context`: Context condensation/summarization has started
  129. * - `condense_context_error`: Error occurred during context condensation
  130. * - `codebase_search_result`: Results from searching the codebase
  131. */
  132. export const clineSays = [
  133. "error",
  134. "api_req_started",
  135. "api_req_finished",
  136. "api_req_retried",
  137. "api_req_retry_delayed",
  138. "api_req_rate_limit_wait",
  139. "api_req_deleted",
  140. "text",
  141. "image",
  142. "reasoning",
  143. "completion_result",
  144. "user_feedback",
  145. "user_feedback_diff",
  146. "command_output",
  147. "shell_integration_warning",
  148. "browser_action",
  149. "browser_action_result",
  150. "browser_session_status",
  151. "mcp_server_request_started",
  152. "mcp_server_response",
  153. "subtask_result",
  154. "checkpoint_saved",
  155. "rooignore_error",
  156. "diff_error",
  157. "condense_context",
  158. "condense_context_error",
  159. "sliding_window_truncation",
  160. "codebase_search_result",
  161. "user_edit_todos",
  162. ] as const
  163. export const clineSaySchema = z.enum(clineSays)
  164. export type ClineSay = z.infer<typeof clineSaySchema>
  165. /**
  166. * ToolProgressStatus
  167. */
  168. export const toolProgressStatusSchema = z.object({
  169. icon: z.string().optional(),
  170. text: z.string().optional(),
  171. })
  172. export type ToolProgressStatus = z.infer<typeof toolProgressStatusSchema>
  173. /**
  174. * ContextCondense
  175. *
  176. * Data associated with a successful context condensation event.
  177. * This is attached to messages with `say: "condense_context"` when
  178. * the condensation operation completes successfully.
  179. *
  180. * @property cost - The API cost incurred for the condensation operation
  181. * @property prevContextTokens - Token count before condensation
  182. * @property newContextTokens - Token count after condensation
  183. * @property summary - The condensed summary that replaced the original context
  184. * @property condenseId - Optional unique identifier for this condensation operation
  185. */
  186. export const contextCondenseSchema = z.object({
  187. cost: z.number(),
  188. prevContextTokens: z.number(),
  189. newContextTokens: z.number(),
  190. summary: z.string(),
  191. condenseId: z.string().optional(),
  192. })
  193. export type ContextCondense = z.infer<typeof contextCondenseSchema>
  194. /**
  195. * ContextTruncation
  196. *
  197. * Data associated with a sliding window truncation event.
  198. * This is attached to messages with `say: "sliding_window_truncation"` when
  199. * messages are removed from the conversation history to stay within token limits.
  200. *
  201. * Unlike condensation, truncation simply removes older messages without
  202. * summarizing them. This is a faster but less context-preserving approach.
  203. *
  204. * @property truncationId - Unique identifier for this truncation operation
  205. * @property messagesRemoved - Number of conversation messages that were removed
  206. * @property prevContextTokens - Token count before truncation occurred
  207. * @property newContextTokens - Token count after truncation occurred
  208. */
  209. export const contextTruncationSchema = z.object({
  210. truncationId: z.string(),
  211. messagesRemoved: z.number(),
  212. prevContextTokens: z.number(),
  213. newContextTokens: z.number(),
  214. })
  215. export type ContextTruncation = z.infer<typeof contextTruncationSchema>
  216. /**
  217. * ClineMessage
  218. *
  219. * The main message type used for communication between the extension and webview.
  220. * Messages can either be "ask" (requiring user response) or "say" (informational).
  221. *
  222. * Context Management Fields:
  223. * - `contextCondense`: Present when `say: "condense_context"` and condensation succeeded
  224. * - `contextTruncation`: Present when `say: "sliding_window_truncation"` and truncation occurred
  225. *
  226. * Note: These fields are mutually exclusive - a message will have at most one of them.
  227. */
  228. export const clineMessageSchema = z.object({
  229. ts: z.number(),
  230. type: z.union([z.literal("ask"), z.literal("say")]),
  231. ask: clineAskSchema.optional(),
  232. say: clineSaySchema.optional(),
  233. text: z.string().optional(),
  234. images: z.array(z.string()).optional(),
  235. partial: z.boolean().optional(),
  236. reasoning: z.string().optional(),
  237. conversationHistoryIndex: z.number().optional(),
  238. checkpoint: z.record(z.string(), z.unknown()).optional(),
  239. progressStatus: toolProgressStatusSchema.optional(),
  240. /**
  241. * Data for successful context condensation.
  242. * Present when `say: "condense_context"` and `partial: false`.
  243. */
  244. contextCondense: contextCondenseSchema.optional(),
  245. /**
  246. * Data for sliding window truncation.
  247. * Present when `say: "sliding_window_truncation"`.
  248. */
  249. contextTruncation: contextTruncationSchema.optional(),
  250. isProtected: z.boolean().optional(),
  251. apiProtocol: z.union([z.literal("openai"), z.literal("anthropic")]).optional(),
  252. isAnswered: z.boolean().optional(),
  253. })
  254. export type ClineMessage = z.infer<typeof clineMessageSchema>
  255. /**
  256. * TokenUsage
  257. */
  258. export const tokenUsageSchema = z.object({
  259. totalTokensIn: z.number(),
  260. totalTokensOut: z.number(),
  261. totalCacheWrites: z.number().optional(),
  262. totalCacheReads: z.number().optional(),
  263. totalCost: z.number(),
  264. contextTokens: z.number(),
  265. })
  266. export type TokenUsage = z.infer<typeof tokenUsageSchema>
  267. /**
  268. * QueuedMessage
  269. */
  270. export const queuedMessageSchema = z.object({
  271. timestamp: z.number(),
  272. id: z.string(),
  273. text: z.string(),
  274. images: z.array(z.string()).optional(),
  275. })
  276. export type QueuedMessage = z.infer<typeof queuedMessageSchema>