@codeany/open-agent-sdk 0.2.1 → 0.2.3

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 (57) hide show
  1. package/dist/engine.d.ts.map +1 -1
  2. package/dist/engine.js +2 -0
  3. package/dist/engine.js.map +1 -1
  4. package/package.json +5 -6
  5. package/src/agent.ts +0 -516
  6. package/src/engine.ts +0 -630
  7. package/src/hooks.ts +0 -261
  8. package/src/index.ts +0 -426
  9. package/src/mcp/client.ts +0 -150
  10. package/src/providers/anthropic.ts +0 -60
  11. package/src/providers/index.ts +0 -34
  12. package/src/providers/openai.ts +0 -315
  13. package/src/providers/types.ts +0 -85
  14. package/src/sdk-mcp-server.ts +0 -78
  15. package/src/session.ts +0 -227
  16. package/src/skills/bundled/commit.ts +0 -38
  17. package/src/skills/bundled/debug.ts +0 -48
  18. package/src/skills/bundled/index.ts +0 -28
  19. package/src/skills/bundled/review.ts +0 -41
  20. package/src/skills/bundled/simplify.ts +0 -51
  21. package/src/skills/bundled/test.ts +0 -43
  22. package/src/skills/index.ts +0 -25
  23. package/src/skills/registry.ts +0 -133
  24. package/src/skills/types.ts +0 -99
  25. package/src/tool-helper.ts +0 -127
  26. package/src/tools/agent-tool.ts +0 -164
  27. package/src/tools/ask-user.ts +0 -79
  28. package/src/tools/bash.ts +0 -75
  29. package/src/tools/config-tool.ts +0 -89
  30. package/src/tools/cron-tools.ts +0 -153
  31. package/src/tools/edit.ts +0 -74
  32. package/src/tools/glob.ts +0 -77
  33. package/src/tools/grep.ts +0 -168
  34. package/src/tools/index.ts +0 -240
  35. package/src/tools/lsp-tool.ts +0 -163
  36. package/src/tools/mcp-resource-tools.ts +0 -125
  37. package/src/tools/notebook-edit.ts +0 -93
  38. package/src/tools/plan-tools.ts +0 -88
  39. package/src/tools/read.ts +0 -73
  40. package/src/tools/send-message.ts +0 -96
  41. package/src/tools/skill-tool.ts +0 -133
  42. package/src/tools/task-tools.ts +0 -290
  43. package/src/tools/team-tools.ts +0 -128
  44. package/src/tools/todo-tool.ts +0 -112
  45. package/src/tools/tool-search.ts +0 -87
  46. package/src/tools/types.ts +0 -66
  47. package/src/tools/web-fetch.ts +0 -66
  48. package/src/tools/web-search.ts +0 -86
  49. package/src/tools/worktree-tools.ts +0 -140
  50. package/src/tools/write.ts +0 -42
  51. package/src/types.ts +0 -486
  52. package/src/utils/compact.ts +0 -207
  53. package/src/utils/context.ts +0 -191
  54. package/src/utils/fileCache.ts +0 -148
  55. package/src/utils/messages.ts +0 -195
  56. package/src/utils/retry.ts +0 -140
  57. package/src/utils/tokens.ts +0 -145
@@ -1,78 +0,0 @@
1
- /**
2
- * In-Process MCP Server
3
- *
4
- * createSdkMcpServer() creates an in-process MCP server from tool() definitions.
5
- * Compatible with open-agent-sdk's createSdkMcpServer().
6
- *
7
- * Usage:
8
- * import { tool, createSdkMcpServer } from 'open-agent-sdk'
9
- * import { z } from 'zod'
10
- *
11
- * const weatherTool = tool('get_weather', 'Get weather', { city: z.string() },
12
- * async ({ city }) => ({ content: [{ type: 'text', text: `22°C in ${city}` }] })
13
- * )
14
- *
15
- * const server = createSdkMcpServer({
16
- * name: 'weather',
17
- * tools: [weatherTool],
18
- * })
19
- *
20
- * // Use as MCP server config:
21
- * const agent = createAgent({
22
- * mcpServers: { weather: server },
23
- * })
24
- */
25
-
26
- import type { SdkMcpToolDefinition } from './tool-helper.js'
27
- import { sdkToolToToolDefinition } from './tool-helper.js'
28
- import type { ToolDefinition, McpServerConfig } from './types.js'
29
-
30
- /**
31
- * SDK MCP server config that includes the in-process server instance.
32
- */
33
- export interface McpSdkServerConfig {
34
- type: 'sdk'
35
- name: string
36
- version: string
37
- tools: ToolDefinition[]
38
- _sdkTools: SdkMcpToolDefinition<any>[]
39
- }
40
-
41
- /**
42
- * Create an in-process MCP server from tool definitions.
43
- *
44
- * The server runs in the same process as the agent, avoiding
45
- * subprocess overhead. Tools are directly callable.
46
- */
47
- export function createSdkMcpServer(options: {
48
- name: string
49
- version?: string
50
- tools?: SdkMcpToolDefinition<any>[]
51
- }): McpSdkServerConfig {
52
- const sdkTools = options.tools || []
53
-
54
- // Convert SDK tools to engine-compatible tool definitions
55
- // Prefix tool names with mcp__{server_name}__ for namespace isolation
56
- const toolDefinitions: ToolDefinition[] = sdkTools.map((sdkTool) => {
57
- const toolDef = sdkToolToToolDefinition(sdkTool)
58
- return {
59
- ...toolDef,
60
- name: `mcp__${options.name}__${sdkTool.name}`,
61
- }
62
- })
63
-
64
- return {
65
- type: 'sdk',
66
- name: options.name,
67
- version: options.version || '1.0.0',
68
- tools: toolDefinitions,
69
- _sdkTools: sdkTools,
70
- }
71
- }
72
-
73
- /**
74
- * Check if a server config is an in-process SDK server.
75
- */
76
- export function isSdkServerConfig(config: any): config is McpSdkServerConfig {
77
- return config?.type === 'sdk' && Array.isArray(config.tools)
78
- }
package/src/session.ts DELETED
@@ -1,227 +0,0 @@
1
- /**
2
- * Session Storage & Management
3
- *
4
- * Persists conversation transcripts to disk for resumption.
5
- * Manages session lifecycle (create, resume, list, fork).
6
- */
7
-
8
- import { readFile, writeFile, mkdir, readdir, stat } from 'fs/promises'
9
- import { join } from 'path'
10
- import type { Message } from './types.js'
11
- import type { NormalizedMessageParam } from './providers/types.js'
12
-
13
- /**
14
- * Session metadata.
15
- */
16
- export interface SessionMetadata {
17
- id: string
18
- cwd: string
19
- model: string
20
- createdAt: string
21
- updatedAt: string
22
- messageCount: number
23
- summary?: string
24
- }
25
-
26
- /**
27
- * Session data on disk.
28
- */
29
- export interface SessionData {
30
- metadata: SessionMetadata
31
- messages: NormalizedMessageParam[]
32
- }
33
-
34
- /**
35
- * Get the sessions directory path.
36
- */
37
- function getSessionsDir(): string {
38
- const home = process.env.HOME || process.env.USERPROFILE || '/tmp'
39
- return join(home, '.open-agent-sdk', 'sessions')
40
- }
41
-
42
- /**
43
- * Get the path for a specific session.
44
- */
45
- function getSessionPath(sessionId: string): string {
46
- return join(getSessionsDir(), sessionId)
47
- }
48
-
49
- /**
50
- * Save session to disk.
51
- */
52
- export async function saveSession(
53
- sessionId: string,
54
- messages: NormalizedMessageParam[],
55
- metadata: Partial<SessionMetadata>,
56
- ): Promise<void> {
57
- const dir = getSessionPath(sessionId)
58
- await mkdir(dir, { recursive: true })
59
-
60
- const data: SessionData = {
61
- metadata: {
62
- id: sessionId,
63
- cwd: metadata.cwd || process.cwd(),
64
- model: metadata.model || 'claude-sonnet-4-6',
65
- createdAt: metadata.createdAt || new Date().toISOString(),
66
- updatedAt: new Date().toISOString(),
67
- messageCount: messages.length,
68
- summary: metadata.summary,
69
- },
70
- messages,
71
- }
72
-
73
- await writeFile(
74
- join(dir, 'transcript.json'),
75
- JSON.stringify(data, null, 2),
76
- 'utf-8',
77
- )
78
- }
79
-
80
- /**
81
- * Load session from disk.
82
- */
83
- export async function loadSession(sessionId: string): Promise<SessionData | null> {
84
- try {
85
- const filePath = join(getSessionPath(sessionId), 'transcript.json')
86
- const content = await readFile(filePath, 'utf-8')
87
- return JSON.parse(content) as SessionData
88
- } catch {
89
- return null
90
- }
91
- }
92
-
93
- /**
94
- * List all sessions.
95
- */
96
- export async function listSessions(): Promise<SessionMetadata[]> {
97
- try {
98
- const dir = getSessionsDir()
99
- const entries = await readdir(dir)
100
- const sessions: SessionMetadata[] = []
101
-
102
- for (const entry of entries) {
103
- try {
104
- const data = await loadSession(entry)
105
- if (data?.metadata) {
106
- sessions.push(data.metadata)
107
- }
108
- } catch {
109
- // Skip invalid sessions
110
- }
111
- }
112
-
113
- // Sort by updatedAt descending
114
- sessions.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt))
115
-
116
- return sessions
117
- } catch {
118
- return []
119
- }
120
- }
121
-
122
- /**
123
- * Fork a session (create a copy with a new ID).
124
- */
125
- export async function forkSession(
126
- sourceSessionId: string,
127
- newSessionId?: string,
128
- ): Promise<string | null> {
129
- const data = await loadSession(sourceSessionId)
130
- if (!data) return null
131
-
132
- const forkId = newSessionId || crypto.randomUUID()
133
-
134
- await saveSession(forkId, data.messages, {
135
- ...data.metadata,
136
- id: forkId,
137
- createdAt: new Date().toISOString(),
138
- summary: `Forked from session ${sourceSessionId}`,
139
- })
140
-
141
- return forkId
142
- }
143
-
144
- /**
145
- * Get session messages.
146
- */
147
- export async function getSessionMessages(
148
- sessionId: string,
149
- ): Promise<NormalizedMessageParam[]> {
150
- const data = await loadSession(sessionId)
151
- return data?.messages || []
152
- }
153
-
154
- /**
155
- * Append a message to a session transcript.
156
- */
157
- export async function appendToSession(
158
- sessionId: string,
159
- message: NormalizedMessageParam,
160
- ): Promise<void> {
161
- const data = await loadSession(sessionId)
162
- if (!data) return
163
-
164
- data.messages.push(message)
165
- data.metadata.updatedAt = new Date().toISOString()
166
- data.metadata.messageCount = data.messages.length
167
-
168
- await saveSession(sessionId, data.messages, data.metadata)
169
- }
170
-
171
- /**
172
- * Delete a session.
173
- */
174
- export async function deleteSession(sessionId: string): Promise<boolean> {
175
- try {
176
- const { rm } = await import('fs/promises')
177
- await rm(getSessionPath(sessionId), { recursive: true, force: true })
178
- return true
179
- } catch {
180
- return false
181
- }
182
- }
183
-
184
- /**
185
- * Get info about a specific session.
186
- */
187
- export async function getSessionInfo(
188
- sessionId: string,
189
- options?: { dir?: string },
190
- ): Promise<SessionMetadata | null> {
191
- const data = await loadSession(sessionId)
192
- return data?.metadata || null
193
- }
194
-
195
- /**
196
- * Rename a session.
197
- */
198
- export async function renameSession(
199
- sessionId: string,
200
- title: string,
201
- options?: { dir?: string },
202
- ): Promise<void> {
203
- const data = await loadSession(sessionId)
204
- if (!data) return
205
-
206
- data.metadata.summary = title
207
- data.metadata.updatedAt = new Date().toISOString()
208
-
209
- await saveSession(sessionId, data.messages, data.metadata)
210
- }
211
-
212
- /**
213
- * Tag a session.
214
- */
215
- export async function tagSession(
216
- sessionId: string,
217
- tag: string | null,
218
- options?: { dir?: string },
219
- ): Promise<void> {
220
- const data = await loadSession(sessionId)
221
- if (!data) return
222
-
223
- ;(data.metadata as any).tag = tag
224
- data.metadata.updatedAt = new Date().toISOString()
225
-
226
- await saveSession(sessionId, data.messages, data.metadata)
227
- }
@@ -1,38 +0,0 @@
1
- /**
2
- * Bundled Skill: commit
3
- *
4
- * Create a git commit with a well-crafted message based on staged changes.
5
- */
6
-
7
- import { registerSkill } from '../registry.js'
8
- import type { SkillContentBlock } from '../types.js'
9
-
10
- const COMMIT_PROMPT = `Create a git commit for the current changes. Follow these steps:
11
-
12
- 1. Run \`git status\` and \`git diff --cached\` to understand what's staged
13
- 2. If nothing is staged, run \`git diff\` to see unstaged changes and suggest what to stage
14
- 3. Analyze the changes and draft a concise commit message that:
15
- - Uses imperative mood ("Add feature" not "Added feature")
16
- - Summarizes the "why" not just the "what"
17
- - Keeps the first line under 72 characters
18
- - Adds a body with details if the change is complex
19
- 4. Create the commit
20
-
21
- Do NOT push to remote unless explicitly asked.`
22
-
23
- export function registerCommitSkill(): void {
24
- registerSkill({
25
- name: 'commit',
26
- description: 'Create a git commit with a well-crafted message based on staged changes.',
27
- aliases: ['ci'],
28
- allowedTools: ['Bash', 'Read', 'Glob', 'Grep'],
29
- userInvocable: true,
30
- async getPrompt(args): Promise<SkillContentBlock[]> {
31
- let prompt = COMMIT_PROMPT
32
- if (args.trim()) {
33
- prompt += `\n\nAdditional instructions: ${args}`
34
- }
35
- return [{ type: 'text', text: prompt }]
36
- },
37
- })
38
- }
@@ -1,48 +0,0 @@
1
- /**
2
- * Bundled Skill: debug
3
- *
4
- * Systematic debugging of an issue using structured investigation.
5
- */
6
-
7
- import { registerSkill } from '../registry.js'
8
- import type { SkillContentBlock } from '../types.js'
9
-
10
- const DEBUG_PROMPT = `Debug the described issue using a systematic approach:
11
-
12
- 1. **Reproduce**: Understand and reproduce the issue
13
- - Read relevant error messages or logs
14
- - Identify the failing component
15
-
16
- 2. **Investigate**: Trace the root cause
17
- - Read the relevant source code
18
- - Add logging or use debugging tools if needed
19
- - Check recent changes that might have introduced the issue (\`git log --oneline -20\`)
20
-
21
- 3. **Hypothesize**: Form a theory about the cause
22
- - State your hypothesis clearly before attempting a fix
23
-
24
- 4. **Fix**: Implement the minimal fix
25
- - Make the smallest change that resolves the issue
26
- - Don't refactor unrelated code
27
-
28
- 5. **Verify**: Confirm the fix works
29
- - Run relevant tests
30
- - Check for regressions`
31
-
32
- export function registerDebugSkill(): void {
33
- registerSkill({
34
- name: 'debug',
35
- description: 'Systematic debugging of an issue using structured investigation.',
36
- aliases: ['investigate', 'diagnose'],
37
- userInvocable: true,
38
- async getPrompt(args): Promise<SkillContentBlock[]> {
39
- let prompt = DEBUG_PROMPT
40
- if (args.trim()) {
41
- prompt += `\n\n## Issue Description\n${args}`
42
- } else {
43
- prompt += `\n\nAsk the user to describe the issue they're experiencing.`
44
- }
45
- return [{ type: 'text', text: prompt }]
46
- },
47
- })
48
- }
@@ -1,28 +0,0 @@
1
- /**
2
- * Bundled Skills Initialization
3
- *
4
- * Registers all built-in skills at SDK startup.
5
- */
6
-
7
- import { registerSimplifySkill } from './simplify.js'
8
- import { registerCommitSkill } from './commit.js'
9
- import { registerReviewSkill } from './review.js'
10
- import { registerDebugSkill } from './debug.js'
11
- import { registerTestSkill } from './test.js'
12
-
13
- let initialized = false
14
-
15
- /**
16
- * Initialize all bundled skills.
17
- * Safe to call multiple times (idempotent).
18
- */
19
- export function initBundledSkills(): void {
20
- if (initialized) return
21
- initialized = true
22
-
23
- registerSimplifySkill()
24
- registerCommitSkill()
25
- registerReviewSkill()
26
- registerDebugSkill()
27
- registerTestSkill()
28
- }
@@ -1,41 +0,0 @@
1
- /**
2
- * Bundled Skill: review
3
- *
4
- * Review code changes (PR or local diff) for issues and improvements.
5
- */
6
-
7
- import { registerSkill } from '../registry.js'
8
- import type { SkillContentBlock } from '../types.js'
9
-
10
- const REVIEW_PROMPT = `Review the current code changes for potential issues. Follow these steps:
11
-
12
- 1. Run \`git diff\` to see uncommitted changes, or \`git diff main...HEAD\` for branch changes
13
- 2. For each changed file, analyze:
14
- - **Correctness**: Logic errors, edge cases, off-by-one errors
15
- - **Security**: Injection vulnerabilities, auth issues, data exposure
16
- - **Performance**: N+1 queries, unnecessary allocations, blocking I/O
17
- - **Style**: Naming, consistency with surrounding code, readability
18
- - **Testing**: Are the changes adequately tested?
19
- 3. Provide a summary with:
20
- - Critical issues (must fix)
21
- - Suggestions (nice to have)
22
- - Questions (need clarification)
23
-
24
- Be specific: reference file names, line numbers, and suggest fixes.`
25
-
26
- export function registerReviewSkill(): void {
27
- registerSkill({
28
- name: 'review',
29
- description: 'Review code changes for correctness, security, performance, and style issues.',
30
- aliases: ['review-pr', 'cr'],
31
- allowedTools: ['Bash', 'Read', 'Glob', 'Grep'],
32
- userInvocable: true,
33
- async getPrompt(args): Promise<SkillContentBlock[]> {
34
- let prompt = REVIEW_PROMPT
35
- if (args.trim()) {
36
- prompt += `\n\nFocus area: ${args}`
37
- }
38
- return [{ type: 'text', text: prompt }]
39
- },
40
- })
41
- }
@@ -1,51 +0,0 @@
1
- /**
2
- * Bundled Skill: simplify
3
- *
4
- * Reviews changed code for reuse opportunities, code quality issues,
5
- * and efficiency improvements, then fixes any issues found.
6
- */
7
-
8
- import { registerSkill } from '../registry.js'
9
- import type { SkillContentBlock } from '../types.js'
10
-
11
- const SIMPLIFY_PROMPT = `Review the recently changed code for three categories of improvements. Launch 3 parallel Agent sub-tasks:
12
-
13
- ## Task 1: Reuse Analysis
14
- Look for:
15
- - Duplicated code that could be consolidated
16
- - Existing utilities or helpers that could replace new code
17
- - Patterns that should be extracted into shared functions
18
- - Re-implementations of functionality that already exists elsewhere
19
-
20
- ## Task 2: Code Quality
21
- Look for:
22
- - Overly complex logic that could be simplified
23
- - Poor naming or unclear intent
24
- - Missing edge case handling
25
- - Unnecessary abstractions or over-engineering
26
- - Dead code or unused imports
27
-
28
- ## Task 3: Efficiency
29
- Look for:
30
- - Unnecessary allocations or copies
31
- - N+1 query patterns or redundant I/O
32
- - Blocking operations that could be async
33
- - Inefficient data structures for the access pattern
34
- - Unnecessary re-computation
35
-
36
- After all three analyses complete, fix any issues found. Prioritize by impact.`
37
-
38
- export function registerSimplifySkill(): void {
39
- registerSkill({
40
- name: 'simplify',
41
- description: 'Review changed code for reuse, quality, and efficiency, then fix any issues found.',
42
- userInvocable: true,
43
- async getPrompt(args): Promise<SkillContentBlock[]> {
44
- let prompt = SIMPLIFY_PROMPT
45
- if (args.trim()) {
46
- prompt += `\n\n## Additional Focus\n${args}`
47
- }
48
- return [{ type: 'text', text: prompt }]
49
- },
50
- })
51
- }
@@ -1,43 +0,0 @@
1
- /**
2
- * Bundled Skill: test
3
- *
4
- * Run tests and analyze failures.
5
- */
6
-
7
- import { registerSkill } from '../registry.js'
8
- import type { SkillContentBlock } from '../types.js'
9
-
10
- const TEST_PROMPT = `Run the project's test suite and analyze the results:
11
-
12
- 1. **Discover**: Find the test runner configuration
13
- - Look for package.json scripts, jest.config, vitest.config, pytest.ini, etc.
14
- - Identify the appropriate test command
15
-
16
- 2. **Execute**: Run the tests
17
- - Run the full test suite or specific tests if specified
18
- - Capture output including failures and errors
19
-
20
- 3. **Analyze**: If tests fail:
21
- - Read the failing test to understand what it expects
22
- - Read the source code being tested
23
- - Identify why the test is failing
24
- - Fix the issue (in tests or source as appropriate)
25
-
26
- 4. **Re-verify**: Run the failing tests again to confirm the fix`
27
-
28
- export function registerTestSkill(): void {
29
- registerSkill({
30
- name: 'test',
31
- description: 'Run tests and analyze failures, fixing any issues found.',
32
- aliases: ['run-tests'],
33
- allowedTools: ['Bash', 'Read', 'Write', 'Edit', 'Glob', 'Grep'],
34
- userInvocable: true,
35
- async getPrompt(args): Promise<SkillContentBlock[]> {
36
- let prompt = TEST_PROMPT
37
- if (args.trim()) {
38
- prompt += `\n\nSpecific test target: ${args}`
39
- }
40
- return [{ type: 'text', text: prompt }]
41
- },
42
- })
43
- }
@@ -1,25 +0,0 @@
1
- /**
2
- * Skills Module - Public API
3
- */
4
-
5
- // Types
6
- export type {
7
- SkillDefinition,
8
- SkillContentBlock,
9
- SkillResult,
10
- } from './types.js'
11
-
12
- // Registry
13
- export {
14
- registerSkill,
15
- getSkill,
16
- getAllSkills,
17
- getUserInvocableSkills,
18
- hasSkill,
19
- unregisterSkill,
20
- clearSkills,
21
- formatSkillsForPrompt,
22
- } from './registry.js'
23
-
24
- // Bundled skills
25
- export { initBundledSkills } from './bundled/index.js'