message.ts 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. import z from "zod"
  2. import { SessionID } from "./schema"
  3. import { NamedError } from "@opencode-ai/util/error"
  4. export namespace Message {
  5. export const OutputLengthError = NamedError.create("MessageOutputLengthError", z.object({}))
  6. export const AuthError = NamedError.create(
  7. "ProviderAuthError",
  8. z.object({
  9. providerID: z.string(),
  10. message: z.string(),
  11. }),
  12. )
  13. export const ToolCall = z
  14. .object({
  15. state: z.literal("call"),
  16. step: z.number().optional(),
  17. toolCallId: z.string(),
  18. toolName: z.string(),
  19. args: z.custom<Required<unknown>>(),
  20. })
  21. .meta({
  22. ref: "ToolCall",
  23. })
  24. export type ToolCall = z.infer<typeof ToolCall>
  25. export const ToolPartialCall = z
  26. .object({
  27. state: z.literal("partial-call"),
  28. step: z.number().optional(),
  29. toolCallId: z.string(),
  30. toolName: z.string(),
  31. args: z.custom<Required<unknown>>(),
  32. })
  33. .meta({
  34. ref: "ToolPartialCall",
  35. })
  36. export type ToolPartialCall = z.infer<typeof ToolPartialCall>
  37. export const ToolResult = z
  38. .object({
  39. state: z.literal("result"),
  40. step: z.number().optional(),
  41. toolCallId: z.string(),
  42. toolName: z.string(),
  43. args: z.custom<Required<unknown>>(),
  44. result: z.string(),
  45. })
  46. .meta({
  47. ref: "ToolResult",
  48. })
  49. export type ToolResult = z.infer<typeof ToolResult>
  50. export const ToolInvocation = z.discriminatedUnion("state", [ToolCall, ToolPartialCall, ToolResult]).meta({
  51. ref: "ToolInvocation",
  52. })
  53. export type ToolInvocation = z.infer<typeof ToolInvocation>
  54. export const TextPart = z
  55. .object({
  56. type: z.literal("text"),
  57. text: z.string(),
  58. })
  59. .meta({
  60. ref: "TextPart",
  61. })
  62. export type TextPart = z.infer<typeof TextPart>
  63. export const ReasoningPart = z
  64. .object({
  65. type: z.literal("reasoning"),
  66. text: z.string(),
  67. providerMetadata: z.record(z.string(), z.any()).optional(),
  68. })
  69. .meta({
  70. ref: "ReasoningPart",
  71. })
  72. export type ReasoningPart = z.infer<typeof ReasoningPart>
  73. export const ToolInvocationPart = z
  74. .object({
  75. type: z.literal("tool-invocation"),
  76. toolInvocation: ToolInvocation,
  77. })
  78. .meta({
  79. ref: "ToolInvocationPart",
  80. })
  81. export type ToolInvocationPart = z.infer<typeof ToolInvocationPart>
  82. export const SourceUrlPart = z
  83. .object({
  84. type: z.literal("source-url"),
  85. sourceId: z.string(),
  86. url: z.string(),
  87. title: z.string().optional(),
  88. providerMetadata: z.record(z.string(), z.any()).optional(),
  89. })
  90. .meta({
  91. ref: "SourceUrlPart",
  92. })
  93. export type SourceUrlPart = z.infer<typeof SourceUrlPart>
  94. export const FilePart = z
  95. .object({
  96. type: z.literal("file"),
  97. mediaType: z.string(),
  98. filename: z.string().optional(),
  99. url: z.string(),
  100. })
  101. .meta({
  102. ref: "FilePart",
  103. })
  104. export type FilePart = z.infer<typeof FilePart>
  105. export const StepStartPart = z
  106. .object({
  107. type: z.literal("step-start"),
  108. })
  109. .meta({
  110. ref: "StepStartPart",
  111. })
  112. export type StepStartPart = z.infer<typeof StepStartPart>
  113. export const MessagePart = z
  114. .discriminatedUnion("type", [TextPart, ReasoningPart, ToolInvocationPart, SourceUrlPart, FilePart, StepStartPart])
  115. .meta({
  116. ref: "MessagePart",
  117. })
  118. export type MessagePart = z.infer<typeof MessagePart>
  119. export const Info = z
  120. .object({
  121. id: z.string(),
  122. role: z.enum(["user", "assistant"]),
  123. parts: z.array(MessagePart),
  124. metadata: z
  125. .object({
  126. time: z.object({
  127. created: z.number(),
  128. completed: z.number().optional(),
  129. }),
  130. error: z
  131. .discriminatedUnion("name", [AuthError.Schema, NamedError.Unknown.Schema, OutputLengthError.Schema])
  132. .optional(),
  133. sessionID: SessionID.zod,
  134. tool: z.record(
  135. z.string(),
  136. z
  137. .object({
  138. title: z.string(),
  139. snapshot: z.string().optional(),
  140. time: z.object({
  141. start: z.number(),
  142. end: z.number(),
  143. }),
  144. })
  145. .catchall(z.any()),
  146. ),
  147. assistant: z
  148. .object({
  149. system: z.string().array(),
  150. modelID: z.string(),
  151. providerID: z.string(),
  152. path: z.object({
  153. cwd: z.string(),
  154. root: z.string(),
  155. }),
  156. cost: z.number(),
  157. summary: z.boolean().optional(),
  158. tokens: z.object({
  159. input: z.number(),
  160. output: z.number(),
  161. reasoning: z.number(),
  162. cache: z.object({
  163. read: z.number(),
  164. write: z.number(),
  165. }),
  166. }),
  167. })
  168. .optional(),
  169. snapshot: z.string().optional(),
  170. })
  171. .meta({ ref: "MessageMetadata" }),
  172. })
  173. .meta({
  174. ref: "Message",
  175. })
  176. export type Info = z.infer<typeof Info>
  177. }