@codeany/open-agent-sdk 0.2.2 → 0.2.4

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 (280) hide show
  1. package/dist/agent.d.ts +113 -0
  2. package/dist/agent.d.ts.map +1 -0
  3. package/dist/agent.js +453 -0
  4. package/dist/agent.js.map +1 -0
  5. package/dist/engine.d.ts +62 -0
  6. package/dist/engine.d.ts.map +1 -0
  7. package/dist/engine.js +496 -0
  8. package/dist/engine.js.map +1 -0
  9. package/dist/hooks.d.ts +111 -0
  10. package/dist/hooks.d.ts.map +1 -0
  11. package/dist/hooks.js +179 -0
  12. package/dist/hooks.js.map +1 -0
  13. package/dist/index.d.ts +66 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +133 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/mcp/client.d.ts +19 -0
  18. package/dist/mcp/client.d.ts.map +1 -0
  19. package/dist/mcp/client.js +126 -0
  20. package/dist/mcp/client.js.map +1 -0
  21. package/dist/providers/anthropic.d.ts +17 -0
  22. package/dist/providers/anthropic.d.ts.map +1 -0
  23. package/dist/providers/anthropic.js +47 -0
  24. package/dist/providers/anthropic.js.map +1 -0
  25. package/dist/providers/index.d.ts +20 -0
  26. package/dist/providers/index.d.ts.map +1 -0
  27. package/dist/providers/index.js +26 -0
  28. package/dist/providers/index.js.map +1 -0
  29. package/dist/providers/openai.d.ts +26 -0
  30. package/dist/providers/openai.d.ts.map +1 -0
  31. package/dist/providers/openai.js +212 -0
  32. package/dist/providers/openai.js.map +1 -0
  33. package/dist/providers/types.d.ts +84 -0
  34. package/dist/providers/types.d.ts.map +1 -0
  35. package/dist/providers/types.js +11 -0
  36. package/dist/providers/types.js.map +1 -0
  37. package/dist/sdk-mcp-server.d.ts +52 -0
  38. package/dist/sdk-mcp-server.d.ts.map +1 -0
  39. package/dist/sdk-mcp-server.js +57 -0
  40. package/dist/sdk-mcp-server.js.map +1 -0
  41. package/dist/session.d.ts +73 -0
  42. package/dist/session.d.ts.map +1 -0
  43. package/dist/session.js +159 -0
  44. package/dist/session.js.map +1 -0
  45. package/dist/skills/bundled/commit.d.ts +7 -0
  46. package/dist/skills/bundled/commit.d.ts.map +1 -0
  47. package/dist/skills/bundled/commit.js +35 -0
  48. package/dist/skills/bundled/commit.js.map +1 -0
  49. package/dist/skills/bundled/debug.d.ts +7 -0
  50. package/dist/skills/bundled/debug.d.ts.map +1 -0
  51. package/{src/skills/bundled/debug.ts → dist/skills/bundled/debug.js} +20 -22
  52. package/dist/skills/bundled/debug.js.map +1 -0
  53. package/dist/skills/bundled/index.d.ts +11 -0
  54. package/dist/skills/bundled/index.d.ts.map +1 -0
  55. package/dist/skills/bundled/index.js +26 -0
  56. package/dist/skills/bundled/index.js.map +1 -0
  57. package/dist/skills/bundled/review.d.ts +7 -0
  58. package/dist/skills/bundled/review.d.ts.map +1 -0
  59. package/{src/skills/bundled/review.ts → dist/skills/bundled/review.js} +18 -21
  60. package/dist/skills/bundled/review.js.map +1 -0
  61. package/dist/skills/bundled/simplify.d.ts +8 -0
  62. package/dist/skills/bundled/simplify.d.ts.map +1 -0
  63. package/{src/skills/bundled/simplify.ts → dist/skills/bundled/simplify.js} +16 -19
  64. package/dist/skills/bundled/simplify.js.map +1 -0
  65. package/dist/skills/bundled/test.d.ts +7 -0
  66. package/dist/skills/bundled/test.d.ts.map +1 -0
  67. package/{src/skills/bundled/test.ts → dist/skills/bundled/test.js} +18 -21
  68. package/dist/skills/bundled/test.js.map +1 -0
  69. package/dist/skills/index.d.ts +7 -0
  70. package/dist/skills/index.d.ts.map +1 -0
  71. package/dist/skills/index.js +8 -0
  72. package/dist/skills/index.js.map +1 -0
  73. package/dist/skills/registry.d.ts +43 -0
  74. package/dist/skills/registry.d.ts.map +1 -0
  75. package/dist/skills/registry.js +111 -0
  76. package/dist/skills/registry.js.map +1 -0
  77. package/dist/skills/types.d.ts +83 -0
  78. package/dist/skills/types.d.ts.map +1 -0
  79. package/dist/skills/types.js +8 -0
  80. package/dist/skills/types.js.map +1 -0
  81. package/dist/tool-helper.d.ts +73 -0
  82. package/dist/tool-helper.d.ts.map +1 -0
  83. package/dist/tool-helper.js +86 -0
  84. package/dist/tool-helper.js.map +1 -0
  85. package/dist/tools/agent-tool.d.ts +17 -0
  86. package/dist/tools/agent-tool.d.ts.map +1 -0
  87. package/dist/tools/agent-tool.js +146 -0
  88. package/dist/tools/agent-tool.js.map +1 -0
  89. package/dist/tools/ask-user.d.ts +18 -0
  90. package/dist/tools/ask-user.d.ts.map +1 -0
  91. package/dist/tools/ask-user.js +72 -0
  92. package/dist/tools/ask-user.js.map +1 -0
  93. package/dist/tools/bash.d.ts +5 -0
  94. package/dist/tools/bash.d.ts.map +1 -0
  95. package/dist/tools/bash.js +67 -0
  96. package/dist/tools/bash.js.map +1 -0
  97. package/dist/tools/config-tool.d.ts +20 -0
  98. package/dist/tools/config-tool.d.ts.map +1 -0
  99. package/dist/tools/config-tool.js +83 -0
  100. package/dist/tools/config-tool.js.map +1 -0
  101. package/dist/tools/cron-tools.d.ts +33 -0
  102. package/dist/tools/cron-tools.d.ts.map +1 -0
  103. package/dist/tools/cron-tools.js +128 -0
  104. package/dist/tools/cron-tools.js.map +1 -0
  105. package/dist/tools/edit.d.ts +5 -0
  106. package/dist/tools/edit.d.ts.map +1 -0
  107. package/dist/tools/edit.js +70 -0
  108. package/dist/tools/edit.js.map +1 -0
  109. package/dist/tools/glob.d.ts +5 -0
  110. package/dist/tools/glob.d.ts.map +1 -0
  111. package/dist/tools/glob.js +75 -0
  112. package/dist/tools/glob.js.map +1 -0
  113. package/dist/tools/grep.d.ts +5 -0
  114. package/dist/tools/grep.d.ts.map +1 -0
  115. package/dist/tools/grep.js +168 -0
  116. package/dist/tools/grep.js.map +1 -0
  117. package/dist/tools/index.d.ts +45 -0
  118. package/dist/tools/index.d.ts.map +1 -0
  119. package/dist/tools/index.js +162 -0
  120. package/dist/tools/index.js.map +1 -0
  121. package/dist/tools/lsp-tool.d.ts +9 -0
  122. package/dist/tools/lsp-tool.d.ts.map +1 -0
  123. package/dist/tools/lsp-tool.js +137 -0
  124. package/dist/tools/lsp-tool.js.map +1 -0
  125. package/dist/tools/mcp-resource-tools.d.ts +14 -0
  126. package/dist/tools/mcp-resource-tools.d.ts.map +1 -0
  127. package/dist/tools/mcp-resource-tools.js +117 -0
  128. package/dist/tools/mcp-resource-tools.js.map +1 -0
  129. package/dist/tools/notebook-edit.d.ts +5 -0
  130. package/dist/tools/notebook-edit.d.ts.map +1 -0
  131. package/dist/tools/notebook-edit.js +85 -0
  132. package/dist/tools/notebook-edit.js.map +1 -0
  133. package/dist/tools/plan-tools.d.ts +12 -0
  134. package/dist/tools/plan-tools.d.ts.map +1 -0
  135. package/dist/tools/plan-tools.js +77 -0
  136. package/dist/tools/plan-tools.js.map +1 -0
  137. package/dist/tools/read.d.ts +5 -0
  138. package/dist/tools/read.d.ts.map +1 -0
  139. package/dist/tools/read.js +66 -0
  140. package/dist/tools/read.js.map +1 -0
  141. package/dist/tools/send-message.d.ts +31 -0
  142. package/dist/tools/send-message.d.ts.map +1 -0
  143. package/dist/tools/send-message.js +77 -0
  144. package/dist/tools/send-message.js.map +1 -0
  145. package/dist/tools/skill-tool.d.ts +9 -0
  146. package/dist/tools/skill-tool.d.ts.map +1 -0
  147. package/dist/tools/skill-tool.js +115 -0
  148. package/dist/tools/skill-tool.js.map +1 -0
  149. package/dist/tools/task-tools.d.ts +48 -0
  150. package/dist/tools/task-tools.d.ts.map +1 -0
  151. package/dist/tools/task-tools.js +242 -0
  152. package/dist/tools/task-tools.js.map +1 -0
  153. package/dist/tools/team-tools.d.ts +34 -0
  154. package/dist/tools/team-tools.d.ts.map +1 -0
  155. package/dist/tools/team-tools.js +103 -0
  156. package/dist/tools/team-tools.js.map +1 -0
  157. package/dist/tools/todo-tool.d.ts +22 -0
  158. package/dist/tools/todo-tool.d.ts.map +1 -0
  159. package/dist/tools/todo-tool.js +93 -0
  160. package/dist/tools/todo-tool.js.map +1 -0
  161. package/dist/tools/tool-search.d.ts +13 -0
  162. package/dist/tools/tool-search.d.ts.map +1 -0
  163. package/dist/tools/tool-search.js +76 -0
  164. package/dist/tools/tool-search.js.map +1 -0
  165. package/dist/tools/types.d.ts +29 -0
  166. package/dist/tools/types.d.ts.map +1 -0
  167. package/dist/tools/types.js +52 -0
  168. package/dist/tools/types.js.map +1 -0
  169. package/dist/tools/web-fetch.d.ts +5 -0
  170. package/dist/tools/web-fetch.d.ts.map +1 -0
  171. package/dist/tools/web-fetch.js +60 -0
  172. package/dist/tools/web-fetch.js.map +1 -0
  173. package/dist/tools/web-search.d.ts +5 -0
  174. package/dist/tools/web-search.d.ts.map +1 -0
  175. package/dist/tools/web-search.js +77 -0
  176. package/dist/tools/web-search.js.map +1 -0
  177. package/dist/tools/worktree-tools.d.ts +10 -0
  178. package/dist/tools/worktree-tools.d.ts.map +1 -0
  179. package/dist/tools/worktree-tools.js +130 -0
  180. package/dist/tools/worktree-tools.js.map +1 -0
  181. package/dist/tools/write.d.ts +5 -0
  182. package/dist/tools/write.d.ts.map +1 -0
  183. package/dist/tools/write.js +40 -0
  184. package/dist/tools/write.js.map +1 -0
  185. package/dist/types.d.ts +432 -0
  186. package/dist/types.d.ts.map +1 -0
  187. package/dist/types.js +5 -0
  188. package/dist/types.js.map +1 -0
  189. package/dist/utils/compact.d.ts +44 -0
  190. package/dist/utils/compact.d.ts.map +1 -0
  191. package/dist/utils/compact.js +162 -0
  192. package/dist/utils/compact.js.map +1 -0
  193. package/dist/utils/context.d.ts +35 -0
  194. package/dist/utils/context.d.ts.map +1 -0
  195. package/dist/utils/context.js +174 -0
  196. package/dist/utils/context.js.map +1 -0
  197. package/dist/utils/fileCache.d.ts +64 -0
  198. package/dist/utils/fileCache.d.ts.map +1 -0
  199. package/dist/utils/fileCache.js +117 -0
  200. package/dist/utils/fileCache.js.map +1 -0
  201. package/dist/utils/messages.d.ts +57 -0
  202. package/dist/utils/messages.d.ts.map +1 -0
  203. package/dist/utils/messages.js +152 -0
  204. package/dist/utils/messages.js.map +1 -0
  205. package/dist/utils/retry.d.ts +48 -0
  206. package/dist/utils/retry.d.ts.map +1 -0
  207. package/dist/utils/retry.js +111 -0
  208. package/dist/utils/retry.js.map +1 -0
  209. package/dist/utils/tokens.d.ts +57 -0
  210. package/dist/utils/tokens.d.ts.map +1 -0
  211. package/dist/utils/tokens.js +134 -0
  212. package/dist/utils/tokens.js.map +1 -0
  213. package/package.json +6 -1
  214. package/.env.example +0 -8
  215. package/examples/01-simple-query.ts +0 -43
  216. package/examples/02-multi-tool.ts +0 -44
  217. package/examples/03-multi-turn.ts +0 -39
  218. package/examples/04-prompt-api.ts +0 -29
  219. package/examples/05-custom-system-prompt.ts +0 -26
  220. package/examples/06-mcp-server.ts +0 -49
  221. package/examples/07-custom-tools.ts +0 -87
  222. package/examples/08-official-api-compat.ts +0 -38
  223. package/examples/09-subagents.ts +0 -48
  224. package/examples/10-permissions.ts +0 -40
  225. package/examples/11-custom-mcp-tools.ts +0 -101
  226. package/examples/12-skills.ts +0 -88
  227. package/examples/13-hooks.ts +0 -88
  228. package/examples/14-openai-compat.ts +0 -71
  229. package/examples/web/index.html +0 -365
  230. package/examples/web/server.ts +0 -157
  231. package/src/agent.ts +0 -516
  232. package/src/engine.ts +0 -633
  233. package/src/hooks.ts +0 -261
  234. package/src/index.ts +0 -426
  235. package/src/mcp/client.ts +0 -150
  236. package/src/providers/anthropic.ts +0 -60
  237. package/src/providers/index.ts +0 -34
  238. package/src/providers/openai.ts +0 -315
  239. package/src/providers/types.ts +0 -85
  240. package/src/sdk-mcp-server.ts +0 -78
  241. package/src/session.ts +0 -227
  242. package/src/skills/bundled/commit.ts +0 -38
  243. package/src/skills/bundled/index.ts +0 -28
  244. package/src/skills/index.ts +0 -25
  245. package/src/skills/registry.ts +0 -133
  246. package/src/skills/types.ts +0 -99
  247. package/src/tool-helper.ts +0 -127
  248. package/src/tools/agent-tool.ts +0 -164
  249. package/src/tools/ask-user.ts +0 -79
  250. package/src/tools/bash.ts +0 -75
  251. package/src/tools/config-tool.ts +0 -89
  252. package/src/tools/cron-tools.ts +0 -153
  253. package/src/tools/edit.ts +0 -74
  254. package/src/tools/glob.ts +0 -77
  255. package/src/tools/grep.ts +0 -168
  256. package/src/tools/index.ts +0 -240
  257. package/src/tools/lsp-tool.ts +0 -163
  258. package/src/tools/mcp-resource-tools.ts +0 -125
  259. package/src/tools/notebook-edit.ts +0 -93
  260. package/src/tools/plan-tools.ts +0 -88
  261. package/src/tools/read.ts +0 -73
  262. package/src/tools/send-message.ts +0 -96
  263. package/src/tools/skill-tool.ts +0 -133
  264. package/src/tools/task-tools.ts +0 -290
  265. package/src/tools/team-tools.ts +0 -128
  266. package/src/tools/todo-tool.ts +0 -112
  267. package/src/tools/tool-search.ts +0 -87
  268. package/src/tools/types.ts +0 -66
  269. package/src/tools/web-fetch.ts +0 -66
  270. package/src/tools/web-search.ts +0 -86
  271. package/src/tools/worktree-tools.ts +0 -140
  272. package/src/tools/write.ts +0 -42
  273. package/src/types.ts +0 -486
  274. package/src/utils/compact.ts +0 -207
  275. package/src/utils/context.ts +0 -191
  276. package/src/utils/fileCache.ts +0 -148
  277. package/src/utils/messages.ts +0 -195
  278. package/src/utils/retry.ts +0 -140
  279. package/src/utils/tokens.ts +0 -145
  280. package/tsconfig.json +0 -19
package/src/mcp/client.ts DELETED
@@ -1,150 +0,0 @@
1
- /**
2
- * MCP Client - Connect to Model Context Protocol servers
3
- */
4
-
5
- import type { ToolDefinition, McpServerConfig, ToolContext, ToolResult } from '../types.js'
6
-
7
- export interface MCPConnection {
8
- name: string
9
- status: 'connected' | 'disconnected' | 'error'
10
- tools: ToolDefinition[]
11
- close: () => Promise<void>
12
- }
13
-
14
- /**
15
- * Connect to an MCP server and fetch its tools.
16
- */
17
- export async function connectMCPServer(
18
- name: string,
19
- config: McpServerConfig,
20
- ): Promise<MCPConnection> {
21
- try {
22
- const { Client } = await import('@modelcontextprotocol/sdk/client/index.js')
23
-
24
- let transport: any
25
-
26
- if (!config.type || config.type === 'stdio') {
27
- const stdioConfig = config as { command: string; args?: string[]; env?: Record<string, string> }
28
- const { StdioClientTransport } = await import('@modelcontextprotocol/sdk/client/stdio.js')
29
- transport = new StdioClientTransport({
30
- command: stdioConfig.command,
31
- args: stdioConfig.args || [],
32
- env: { ...process.env, ...stdioConfig.env } as Record<string, string>,
33
- })
34
- } else if (config.type === 'sse') {
35
- const sseConfig = config as { url: string; headers?: Record<string, string> }
36
- const { SSEClientTransport } = await import('@modelcontextprotocol/sdk/client/sse.js')
37
- transport = new SSEClientTransport(new URL(sseConfig.url), {
38
- requestInit: sseConfig.headers ? { headers: sseConfig.headers } : undefined,
39
- } as any)
40
- } else if (config.type === 'http') {
41
- const httpConfig = config as { url: string; headers?: Record<string, string> }
42
- const { StreamableHTTPClientTransport } = await import('@modelcontextprotocol/sdk/client/streamableHttp.js')
43
- transport = new StreamableHTTPClientTransport(new URL(httpConfig.url), {
44
- requestInit: httpConfig.headers ? { headers: httpConfig.headers } : undefined,
45
- } as any)
46
- } else {
47
- throw new Error(`Unsupported MCP transport type: ${(config as any).type}`)
48
- }
49
-
50
- const client = new Client(
51
- { name: `agent-sdk-${name}`, version: '1.0.0' },
52
- { capabilities: {} },
53
- )
54
-
55
- await client.connect(transport)
56
-
57
- // Fetch available tools
58
- const toolList = await client.listTools()
59
- const tools: ToolDefinition[] = (toolList.tools || []).map((mcpTool: any) =>
60
- createMCPToolDefinition(name, mcpTool, client),
61
- )
62
-
63
- return {
64
- name,
65
- status: 'connected',
66
- tools,
67
- async close() {
68
- try {
69
- await client.close()
70
- } catch {
71
- // ignore close errors
72
- }
73
- },
74
- }
75
- } catch (err: any) {
76
- console.error(`[MCP] Failed to connect to "${name}": ${err.message}`)
77
- return {
78
- name,
79
- status: 'error',
80
- tools: [],
81
- async close() {},
82
- }
83
- }
84
- }
85
-
86
- /**
87
- * Create a ToolDefinition wrapping an MCP server tool.
88
- */
89
- function createMCPToolDefinition(
90
- serverName: string,
91
- mcpTool: { name: string; description?: string; inputSchema?: any },
92
- client: any,
93
- ): ToolDefinition {
94
- const toolName = `mcp__${serverName}__${mcpTool.name}`
95
-
96
- return {
97
- name: toolName,
98
- description: mcpTool.description || `MCP tool: ${mcpTool.name} from ${serverName}`,
99
- inputSchema: mcpTool.inputSchema || { type: 'object', properties: {} },
100
- isReadOnly: () => false,
101
- isConcurrencySafe: () => false,
102
- isEnabled: () => true,
103
- async prompt() {
104
- return mcpTool.description || ''
105
- },
106
- async call(input: any): Promise<ToolResult> {
107
- try {
108
- const result = await client.callTool({
109
- name: mcpTool.name,
110
- arguments: input,
111
- })
112
-
113
- // Extract text content from MCP result
114
- let output = ''
115
- if (result.content) {
116
- for (const block of result.content) {
117
- if (block.type === 'text') {
118
- output += block.text
119
- } else {
120
- output += JSON.stringify(block)
121
- }
122
- }
123
- } else {
124
- output = JSON.stringify(result)
125
- }
126
-
127
- return {
128
- type: 'tool_result',
129
- tool_use_id: '',
130
- content: output,
131
- is_error: result.isError || false,
132
- }
133
- } catch (err: any) {
134
- return {
135
- type: 'tool_result',
136
- tool_use_id: '',
137
- content: `MCP tool error: ${err.message}`,
138
- is_error: true,
139
- }
140
- }
141
- },
142
- }
143
- }
144
-
145
- /**
146
- * Close all MCP connections.
147
- */
148
- export async function closeAllConnections(connections: MCPConnection[]): Promise<void> {
149
- await Promise.allSettled(connections.map((c) => c.close()))
150
- }
@@ -1,60 +0,0 @@
1
- /**
2
- * Anthropic Messages API Provider
3
- *
4
- * Wraps the @anthropic-ai/sdk client. Since our internal format is
5
- * Anthropic-like, this is mostly a thin pass-through.
6
- */
7
-
8
- import Anthropic from '@anthropic-ai/sdk'
9
- import type {
10
- LLMProvider,
11
- CreateMessageParams,
12
- CreateMessageResponse,
13
- } from './types.js'
14
-
15
- export class AnthropicProvider implements LLMProvider {
16
- readonly apiType = 'anthropic-messages' as const
17
- private client: Anthropic
18
-
19
- constructor(opts: { apiKey?: string; baseURL?: string }) {
20
- this.client = new Anthropic({
21
- apiKey: opts.apiKey,
22
- baseURL: opts.baseURL,
23
- })
24
- }
25
-
26
- async createMessage(params: CreateMessageParams): Promise<CreateMessageResponse> {
27
- const requestParams: Anthropic.MessageCreateParamsNonStreaming = {
28
- model: params.model,
29
- max_tokens: params.maxTokens,
30
- system: params.system,
31
- messages: params.messages as Anthropic.MessageParam[],
32
- tools: params.tools
33
- ? (params.tools as Anthropic.Tool[])
34
- : undefined,
35
- }
36
-
37
- // Add extended thinking if configured
38
- if (params.thinking?.type === 'enabled' && params.thinking.budget_tokens) {
39
- (requestParams as any).thinking = {
40
- type: 'enabled',
41
- budget_tokens: params.thinking.budget_tokens,
42
- }
43
- }
44
-
45
- const response = await this.client.messages.create(requestParams)
46
-
47
- return {
48
- content: response.content as CreateMessageResponse['content'],
49
- stopReason: response.stop_reason || 'end_turn',
50
- usage: {
51
- input_tokens: response.usage.input_tokens,
52
- output_tokens: response.usage.output_tokens,
53
- cache_creation_input_tokens:
54
- (response.usage as any).cache_creation_input_tokens,
55
- cache_read_input_tokens:
56
- (response.usage as any).cache_read_input_tokens,
57
- },
58
- }
59
- }
60
- }
@@ -1,34 +0,0 @@
1
- /**
2
- * LLM Provider Factory
3
- *
4
- * Creates the appropriate provider based on API type configuration.
5
- */
6
-
7
- export type { ApiType, LLMProvider, CreateMessageParams, CreateMessageResponse, NormalizedMessageParam, NormalizedContentBlock, NormalizedTool, NormalizedResponseBlock } from './types.js'
8
-
9
- export { AnthropicProvider } from './anthropic.js'
10
- export { OpenAIProvider } from './openai.js'
11
-
12
- import type { ApiType, LLMProvider } from './types.js'
13
- import { AnthropicProvider } from './anthropic.js'
14
- import { OpenAIProvider } from './openai.js'
15
-
16
- /**
17
- * Create an LLM provider based on the API type.
18
- *
19
- * @param apiType - 'anthropic-messages' or 'openai-completions'
20
- * @param opts - API credentials
21
- */
22
- export function createProvider(
23
- apiType: ApiType,
24
- opts: { apiKey?: string; baseURL?: string },
25
- ): LLMProvider {
26
- switch (apiType) {
27
- case 'anthropic-messages':
28
- return new AnthropicProvider(opts)
29
- case 'openai-completions':
30
- return new OpenAIProvider(opts)
31
- default:
32
- throw new Error(`Unsupported API type: ${apiType}. Use 'anthropic-messages' or 'openai-completions'.`)
33
- }
34
- }
@@ -1,315 +0,0 @@
1
- /**
2
- * OpenAI Chat Completions API Provider
3
- *
4
- * Converts between the SDK's internal Anthropic-like message format
5
- * and OpenAI's Chat Completions API format.
6
- *
7
- * Uses native fetch (no openai SDK dependency required).
8
- */
9
-
10
- import type {
11
- LLMProvider,
12
- CreateMessageParams,
13
- CreateMessageResponse,
14
- NormalizedMessageParam,
15
- NormalizedContentBlock,
16
- NormalizedTool,
17
- NormalizedResponseBlock,
18
- } from './types.js'
19
-
20
- // --------------------------------------------------------------------------
21
- // OpenAI-specific types (minimal, just what we need)
22
- // --------------------------------------------------------------------------
23
-
24
- interface OpenAIChatMessage {
25
- role: 'system' | 'user' | 'assistant' | 'tool'
26
- content?: string | null
27
- tool_calls?: OpenAIToolCall[]
28
- tool_call_id?: string
29
- }
30
-
31
- interface OpenAIToolCall {
32
- id: string
33
- type: 'function'
34
- function: {
35
- name: string
36
- arguments: string
37
- }
38
- }
39
-
40
- interface OpenAITool {
41
- type: 'function'
42
- function: {
43
- name: string
44
- description: string
45
- parameters: Record<string, any>
46
- }
47
- }
48
-
49
- interface OpenAIChatResponse {
50
- id: string
51
- choices: Array<{
52
- index: number
53
- message: {
54
- role: 'assistant'
55
- content: string | null
56
- tool_calls?: OpenAIToolCall[]
57
- }
58
- finish_reason: 'stop' | 'length' | 'tool_calls' | 'content_filter' | string
59
- }>
60
- usage?: {
61
- prompt_tokens: number
62
- completion_tokens: number
63
- total_tokens: number
64
- }
65
- }
66
-
67
- // --------------------------------------------------------------------------
68
- // Provider
69
- // --------------------------------------------------------------------------
70
-
71
- export class OpenAIProvider implements LLMProvider {
72
- readonly apiType = 'openai-completions' as const
73
- private apiKey: string
74
- private baseURL: string
75
-
76
- constructor(opts: { apiKey?: string; baseURL?: string }) {
77
- this.apiKey = opts.apiKey || ''
78
- this.baseURL = (opts.baseURL || 'https://api.openai.com/v1').replace(/\/$/, '')
79
- }
80
-
81
- async createMessage(params: CreateMessageParams): Promise<CreateMessageResponse> {
82
- // Convert to OpenAI format
83
- const messages = this.convertMessages(params.system, params.messages)
84
- const tools = params.tools ? this.convertTools(params.tools) : undefined
85
-
86
- const body: Record<string, any> = {
87
- model: params.model,
88
- max_tokens: params.maxTokens,
89
- messages,
90
- }
91
-
92
- if (tools && tools.length > 0) {
93
- body.tools = tools
94
- }
95
-
96
- // Make API call
97
- const response = await fetch(`${this.baseURL}/chat/completions`, {
98
- method: 'POST',
99
- headers: {
100
- 'Content-Type': 'application/json',
101
- Authorization: `Bearer ${this.apiKey}`,
102
- },
103
- body: JSON.stringify(body),
104
- })
105
-
106
- if (!response.ok) {
107
- const errBody = await response.text().catch(() => '')
108
- const err: any = new Error(
109
- `OpenAI API error: ${response.status} ${response.statusText}: ${errBody}`,
110
- )
111
- err.status = response.status
112
- throw err
113
- }
114
-
115
- const data = (await response.json()) as OpenAIChatResponse
116
-
117
- // Convert response back to normalized format
118
- return this.convertResponse(data)
119
- }
120
-
121
- // --------------------------------------------------------------------------
122
- // Message Conversion: Internal → OpenAI
123
- // --------------------------------------------------------------------------
124
-
125
- private convertMessages(
126
- system: string,
127
- messages: NormalizedMessageParam[],
128
- ): OpenAIChatMessage[] {
129
- const result: OpenAIChatMessage[] = []
130
-
131
- // System prompt as first message
132
- if (system) {
133
- result.push({ role: 'system', content: system })
134
- }
135
-
136
- for (const msg of messages) {
137
- if (msg.role === 'user') {
138
- this.convertUserMessage(msg, result)
139
- } else if (msg.role === 'assistant') {
140
- this.convertAssistantMessage(msg, result)
141
- }
142
- }
143
-
144
- return result
145
- }
146
-
147
- private convertUserMessage(
148
- msg: NormalizedMessageParam,
149
- result: OpenAIChatMessage[],
150
- ): void {
151
- if (typeof msg.content === 'string') {
152
- result.push({ role: 'user', content: msg.content })
153
- return
154
- }
155
-
156
- // Content blocks may contain text and/or tool_result blocks
157
- const textParts: string[] = []
158
- const toolResults: Array<{ tool_use_id: string; content: string }> = []
159
-
160
- for (const block of msg.content) {
161
- if (block.type === 'text') {
162
- textParts.push(block.text)
163
- } else if (block.type === 'tool_result') {
164
- toolResults.push({
165
- tool_use_id: block.tool_use_id,
166
- content: block.content,
167
- })
168
- }
169
- }
170
-
171
- // Tool results become separate tool messages
172
- for (const tr of toolResults) {
173
- result.push({
174
- role: 'tool',
175
- tool_call_id: tr.tool_use_id,
176
- content: tr.content,
177
- })
178
- }
179
-
180
- // Text parts become a user message
181
- if (textParts.length > 0) {
182
- result.push({ role: 'user', content: textParts.join('\n') })
183
- }
184
- }
185
-
186
- private convertAssistantMessage(
187
- msg: NormalizedMessageParam,
188
- result: OpenAIChatMessage[],
189
- ): void {
190
- if (typeof msg.content === 'string') {
191
- result.push({ role: 'assistant', content: msg.content })
192
- return
193
- }
194
-
195
- // Extract text and tool_use blocks
196
- const textParts: string[] = []
197
- const toolCalls: OpenAIToolCall[] = []
198
-
199
- for (const block of msg.content) {
200
- if (block.type === 'text') {
201
- textParts.push(block.text)
202
- } else if (block.type === 'tool_use') {
203
- toolCalls.push({
204
- id: block.id,
205
- type: 'function',
206
- function: {
207
- name: block.name,
208
- arguments: typeof block.input === 'string'
209
- ? block.input
210
- : JSON.stringify(block.input),
211
- },
212
- })
213
- }
214
- }
215
-
216
- const assistantMsg: OpenAIChatMessage = {
217
- role: 'assistant',
218
- content: textParts.length > 0 ? textParts.join('\n') : null,
219
- }
220
-
221
- if (toolCalls.length > 0) {
222
- assistantMsg.tool_calls = toolCalls
223
- }
224
-
225
- result.push(assistantMsg)
226
- }
227
-
228
- // --------------------------------------------------------------------------
229
- // Tool Conversion: Internal → OpenAI
230
- // --------------------------------------------------------------------------
231
-
232
- private convertTools(tools: NormalizedTool[]): OpenAITool[] {
233
- return tools.map((t) => ({
234
- type: 'function' as const,
235
- function: {
236
- name: t.name,
237
- description: t.description,
238
- parameters: t.input_schema,
239
- },
240
- }))
241
- }
242
-
243
- // --------------------------------------------------------------------------
244
- // Response Conversion: OpenAI → Internal
245
- // --------------------------------------------------------------------------
246
-
247
- private convertResponse(data: OpenAIChatResponse): CreateMessageResponse {
248
- const choice = data.choices[0]
249
- if (!choice) {
250
- return {
251
- content: [{ type: 'text', text: '' }],
252
- stopReason: 'end_turn',
253
- usage: { input_tokens: 0, output_tokens: 0 },
254
- }
255
- }
256
-
257
- const content: NormalizedResponseBlock[] = []
258
-
259
- // Add text content
260
- if (choice.message.content) {
261
- content.push({ type: 'text', text: choice.message.content })
262
- }
263
-
264
- // Add tool calls
265
- if (choice.message.tool_calls) {
266
- for (const tc of choice.message.tool_calls) {
267
- let input: any
268
- try {
269
- input = JSON.parse(tc.function.arguments)
270
- } catch {
271
- input = tc.function.arguments
272
- }
273
-
274
- content.push({
275
- type: 'tool_use',
276
- id: tc.id,
277
- name: tc.function.name,
278
- input,
279
- })
280
- }
281
- }
282
-
283
- // If no content at all, add empty text
284
- if (content.length === 0) {
285
- content.push({ type: 'text', text: '' })
286
- }
287
-
288
- // Map finish_reason to our normalized stop reasons
289
- const stopReason = this.mapFinishReason(choice.finish_reason)
290
-
291
- return {
292
- content,
293
- stopReason,
294
- usage: {
295
- input_tokens: data.usage?.prompt_tokens || 0,
296
- output_tokens: data.usage?.completion_tokens || 0,
297
- },
298
- }
299
- }
300
-
301
- private mapFinishReason(
302
- reason: string,
303
- ): 'end_turn' | 'max_tokens' | 'tool_use' | string {
304
- switch (reason) {
305
- case 'stop':
306
- return 'end_turn'
307
- case 'length':
308
- return 'max_tokens'
309
- case 'tool_calls':
310
- return 'tool_use'
311
- default:
312
- return reason
313
- }
314
- }
315
- }
@@ -1,85 +0,0 @@
1
- /**
2
- * LLM Provider Abstraction Types
3
- *
4
- * Defines a provider interface that normalizes API differences between
5
- * Anthropic Messages API and OpenAI Chat Completions API.
6
- *
7
- * Internally the SDK uses Anthropic-like message format as the canonical
8
- * representation. Providers convert to/from their native API format.
9
- */
10
-
11
- // --------------------------------------------------------------------------
12
- // API Type
13
- // --------------------------------------------------------------------------
14
-
15
- export type ApiType = 'anthropic-messages' | 'openai-completions'
16
-
17
- // --------------------------------------------------------------------------
18
- // Normalized Request
19
- // --------------------------------------------------------------------------
20
-
21
- export interface CreateMessageParams {
22
- model: string
23
- maxTokens: number
24
- system: string
25
- messages: NormalizedMessageParam[]
26
- tools?: NormalizedTool[]
27
- thinking?: { type: string; budget_tokens?: number }
28
- }
29
-
30
- /**
31
- * Normalized message format (Anthropic-like).
32
- * This is the internal representation used throughout the SDK.
33
- */
34
- export interface NormalizedMessageParam {
35
- role: 'user' | 'assistant'
36
- content: string | NormalizedContentBlock[]
37
- }
38
-
39
- export type NormalizedContentBlock =
40
- | { type: 'text'; text: string }
41
- | { type: 'tool_use'; id: string; name: string; input: any }
42
- | { type: 'tool_result'; tool_use_id: string; content: string; is_error?: boolean }
43
- | { type: 'image'; source: any }
44
- | { type: 'thinking'; thinking: string }
45
-
46
- export interface NormalizedTool {
47
- name: string
48
- description: string
49
- input_schema: {
50
- type: 'object'
51
- properties: Record<string, any>
52
- required?: string[]
53
- }
54
- }
55
-
56
- // --------------------------------------------------------------------------
57
- // Normalized Response
58
- // --------------------------------------------------------------------------
59
-
60
- export interface CreateMessageResponse {
61
- content: NormalizedResponseBlock[]
62
- stopReason: 'end_turn' | 'max_tokens' | 'tool_use' | string
63
- usage: {
64
- input_tokens: number
65
- output_tokens: number
66
- cache_creation_input_tokens?: number
67
- cache_read_input_tokens?: number
68
- }
69
- }
70
-
71
- export type NormalizedResponseBlock =
72
- | { type: 'text'; text: string }
73
- | { type: 'tool_use'; id: string; name: string; input: any }
74
-
75
- // --------------------------------------------------------------------------
76
- // Provider Interface
77
- // --------------------------------------------------------------------------
78
-
79
- export interface LLMProvider {
80
- /** The API type this provider implements. */
81
- readonly apiType: ApiType
82
-
83
- /** Send a message and get a response. */
84
- createMessage(params: CreateMessageParams): Promise<CreateMessageResponse>
85
- }