index.ts 4.3 KB

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