index.ts 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. import type {
  2. Event,
  3. createOpencodeClient,
  4. Project,
  5. Model,
  6. Provider,
  7. Permission,
  8. UserMessage,
  9. Part,
  10. Auth,
  11. Config,
  12. } from "@opencode-ai/sdk"
  13. import type { BunShell } from "./shell"
  14. import { type ToolDefinition } from "./tool"
  15. export * from "./tool"
  16. export type ProviderContext = {
  17. source: "env" | "config" | "custom" | "api"
  18. info: Provider
  19. options: Record<string, any>
  20. }
  21. export type PluginInput = {
  22. client: ReturnType<typeof createOpencodeClient>
  23. project: Project
  24. directory: string
  25. worktree: string
  26. $: BunShell
  27. }
  28. export type Plugin = (input: PluginInput) => Promise<Hooks>
  29. export type AuthHook = {
  30. provider: string
  31. loader?: (auth: () => Promise<Auth>, provider: Provider) => Promise<Record<string, any>>
  32. methods: (
  33. | {
  34. type: "oauth"
  35. label: string
  36. prompts?: Array<
  37. | {
  38. type: "text"
  39. key: string
  40. message: string
  41. placeholder?: string
  42. validate?: (value: string) => string | undefined
  43. condition?: (inputs: Record<string, string>) => boolean
  44. }
  45. | {
  46. type: "select"
  47. key: string
  48. message: string
  49. options: Array<{
  50. label: string
  51. value: string
  52. hint?: string
  53. }>
  54. condition?: (inputs: Record<string, string>) => boolean
  55. }
  56. >
  57. authorize(inputs?: Record<string, string>): Promise<AuthOuathResult>
  58. }
  59. | {
  60. type: "api"
  61. label: string
  62. prompts?: Array<
  63. | {
  64. type: "text"
  65. key: string
  66. message: string
  67. placeholder?: string
  68. validate?: (value: string) => string | undefined
  69. condition?: (inputs: Record<string, string>) => boolean
  70. }
  71. | {
  72. type: "select"
  73. key: string
  74. message: string
  75. options: Array<{
  76. label: string
  77. value: string
  78. hint?: string
  79. }>
  80. condition?: (inputs: Record<string, string>) => boolean
  81. }
  82. >
  83. authorize?(inputs?: Record<string, string>): Promise<
  84. | {
  85. type: "success"
  86. key: string
  87. provider?: string
  88. }
  89. | {
  90. type: "failed"
  91. }
  92. >
  93. }
  94. )[]
  95. }
  96. export type AuthOuathResult = { url: string; instructions: string } & (
  97. | {
  98. method: "auto"
  99. callback(): Promise<
  100. | ({
  101. type: "success"
  102. provider?: string
  103. } & (
  104. | {
  105. refresh: string
  106. access: string
  107. expires: number
  108. }
  109. | { key: string }
  110. ))
  111. | {
  112. type: "failed"
  113. }
  114. >
  115. }
  116. | {
  117. method: "code"
  118. callback(code: string): Promise<
  119. | ({
  120. type: "success"
  121. provider?: string
  122. } & (
  123. | {
  124. refresh: string
  125. access: string
  126. expires: number
  127. }
  128. | { key: string }
  129. ))
  130. | {
  131. type: "failed"
  132. }
  133. >
  134. }
  135. )
  136. export interface Hooks {
  137. event?: (input: { event: Event }) => Promise<void>
  138. config?: (input: Config) => Promise<void>
  139. tool?: {
  140. [key: string]: ToolDefinition
  141. }
  142. auth?: AuthHook
  143. /**
  144. * Called when a new message is received
  145. */
  146. "chat.message"?: (
  147. input: { sessionID: string; agent?: string; model?: { providerID: string; modelID: string }; messageID?: string },
  148. output: { message: UserMessage; parts: Part[] },
  149. ) => Promise<void>
  150. /**
  151. * Modify parameters sent to LLM
  152. */
  153. "chat.params"?: (
  154. input: { sessionID: string; agent: string; model: Model; provider: ProviderContext; message: UserMessage },
  155. output: { temperature: number; topP: number; options: Record<string, any> },
  156. ) => Promise<void>
  157. "permission.ask"?: (input: Permission, output: { status: "ask" | "deny" | "allow" }) => Promise<void>
  158. "tool.execute.before"?: (
  159. input: { tool: string; sessionID: string; callID: string },
  160. output: { args: any },
  161. ) => Promise<void>
  162. "tool.execute.after"?: (
  163. input: { tool: string; sessionID: string; callID: string },
  164. output: {
  165. title: string
  166. output: string
  167. metadata: any
  168. },
  169. ) => Promise<void>
  170. "experimental.text.complete"?: (
  171. input: { sessionID: string; messageID: string; partID: string },
  172. output: { text: string },
  173. ) => Promise<void>
  174. }