@levelcode/sdk 0.0.1
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.
- package/CHANGELOG.md +109 -0
- package/README.md +266 -0
- package/dist/index.cjs +41014 -0
- package/dist/index.cjs.map +342 -0
- package/dist/index.mjs +41023 -0
- package/dist/index.mjs.map +342 -0
- package/package.json +84 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to the @levelcode/sdk package will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [0.10.1]
|
|
6
|
+
|
|
7
|
+
More reliable tool calls!
|
|
8
|
+
|
|
9
|
+
## [0.10.0]
|
|
10
|
+
|
|
11
|
+
Lots of changes in the implementation, including native tool calls under the hood. Minimal changes in the public API.
|
|
12
|
+
|
|
13
|
+
## [0.4.3]
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- Exported `processToolCallBuffer` and state helpers so SDK consumers can strip `<levelcode_tool_call>` segments mid-stream.
|
|
18
|
+
- CLI now consumes the shared helper to avoid leaking XML when responses arrive without token streaming.
|
|
19
|
+
- Extra regression tests covering multi-chunk tool-call payloads based on the CLI log case ("I'll help you commit").
|
|
20
|
+
|
|
21
|
+
## [0.4.2]
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- XML tool call filtering in stream chunks - filters out `<levelcode_tool_call>` tags while preserving response text
|
|
26
|
+
- Stateful parser handles tags split across chunk boundaries
|
|
27
|
+
- 50-character safety buffer for split tag detection
|
|
28
|
+
- Comprehensive unit tests (17 test cases)
|
|
29
|
+
|
|
30
|
+
## [0.3.1]
|
|
31
|
+
|
|
32
|
+
- `LevelCodeClient.run` now does not return `null`. Instead, the `LevelCodeClient.run(...).output.type` will be `'error'`.
|
|
33
|
+
|
|
34
|
+
## [0.3.0]
|
|
35
|
+
|
|
36
|
+
- New more intuitive interface for `LevelCodeClient` and `LevelCodeClient.run`.
|
|
37
|
+
|
|
38
|
+
## [0.1.30]
|
|
39
|
+
|
|
40
|
+
Types updates.
|
|
41
|
+
|
|
42
|
+
## [0.1.20]
|
|
43
|
+
|
|
44
|
+
- You can now retrieve the output of an agent in `result.output` if result is the output of an awaited `client.run(...)` call.
|
|
45
|
+
- cwd is optional in the LevelCodeClient constructor.
|
|
46
|
+
- You can pass in `extraToolResults` into a run() call to include more info to the agent.
|
|
47
|
+
|
|
48
|
+
## [0.1.17]
|
|
49
|
+
|
|
50
|
+
### Added
|
|
51
|
+
|
|
52
|
+
- You can now get an API key from the [LevelCode website](https://www.levelcode.com/profile?tab=api-keys)!
|
|
53
|
+
- You can provide your own custom tools!
|
|
54
|
+
|
|
55
|
+
### Updated
|
|
56
|
+
|
|
57
|
+
- Updated types and docs
|
|
58
|
+
|
|
59
|
+
## [0.1.9] - 2025-08-13
|
|
60
|
+
|
|
61
|
+
### Added
|
|
62
|
+
|
|
63
|
+
- `closeConnection` method in `LevelCodeClient`
|
|
64
|
+
|
|
65
|
+
### Changed
|
|
66
|
+
|
|
67
|
+
- Automatic parsing of `knowledgeFiles` if not provided
|
|
68
|
+
|
|
69
|
+
### Fixed
|
|
70
|
+
|
|
71
|
+
- `maxAgentSteps` resets every run
|
|
72
|
+
- `LevelCodeClient` no longer requires binary to be installed
|
|
73
|
+
|
|
74
|
+
## [0.1.8] - 2025-08-13
|
|
75
|
+
|
|
76
|
+
### Added
|
|
77
|
+
|
|
78
|
+
- `withAdditionalMessage` and `withMessageHistory` functions
|
|
79
|
+
- Add images, files, or other messages to a previous run
|
|
80
|
+
- Modify the history of any run
|
|
81
|
+
- `initialSessionState` and `generateInitialRunState` functions
|
|
82
|
+
- Create a SessionState or RunState object from scratch
|
|
83
|
+
|
|
84
|
+
### Removed
|
|
85
|
+
|
|
86
|
+
- `getInitialSessionState` function
|
|
87
|
+
|
|
88
|
+
## [0.1.7] - 2025-08-12
|
|
89
|
+
|
|
90
|
+
### Updated types! AgentConfig has been renamed to AgentDefinition.
|
|
91
|
+
|
|
92
|
+
## [0.1.5] - 2025-08-09
|
|
93
|
+
|
|
94
|
+
### Added
|
|
95
|
+
|
|
96
|
+
- Complete `LevelCodeClient`
|
|
97
|
+
- Better docs
|
|
98
|
+
- New `run()` api
|
|
99
|
+
|
|
100
|
+
## [0.0.1] - 2025-08-05
|
|
101
|
+
|
|
102
|
+
### Added
|
|
103
|
+
|
|
104
|
+
- Initial release of the LevelCode SDK
|
|
105
|
+
- `LevelCodeClient` class for interacting with LevelCode agents
|
|
106
|
+
- `runNewChat` method for starting new chat sessions
|
|
107
|
+
- TypeScript support with full type definitions
|
|
108
|
+
- Support for all LevelCode agent types
|
|
109
|
+
- Event streaming for real-time responses
|
package/README.md
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# @levelcode/sdk
|
|
2
|
+
|
|
3
|
+
Official SDK for LevelCode - AI coding agent and framework
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @levelcode/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Prerequisites
|
|
12
|
+
|
|
13
|
+
- Create a LevelCode account and get your [LevelCode API key here](https://www.levelcode.com/api-keys).
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Basic Example
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { LevelCodeClient } from '@levelcode/sdk'
|
|
21
|
+
|
|
22
|
+
async function main() {
|
|
23
|
+
const client = new LevelCodeClient({
|
|
24
|
+
// You need to pass in your own API key here.
|
|
25
|
+
// Get one here: https://www.levelcode.com/api-keys
|
|
26
|
+
apiKey: process.env.LEVELCODE_API_KEY,
|
|
27
|
+
cwd: process.cwd(),
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
// First run
|
|
31
|
+
const runState1 = await client.run({
|
|
32
|
+
// The agent id. Any agent on the store (https://levelcode.com/store)
|
|
33
|
+
agent: 'levelcode/base@0.0.16',
|
|
34
|
+
prompt: 'Create a simple calculator class',
|
|
35
|
+
handleEvent: (event) => {
|
|
36
|
+
// All events that happen during the run: agent start/finish, tool calls/results, text responses, errors.
|
|
37
|
+
console.log('LevelCode Event', JSON.stringify(event))
|
|
38
|
+
},
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
// Continue the same session with a follow-up
|
|
42
|
+
const runOrError2 = await client.run({
|
|
43
|
+
agent: 'levelcode/base@0.0.16',
|
|
44
|
+
prompt: 'Add unit tests for the calculator',
|
|
45
|
+
previousRun: runState1, // <-- this is where your next run differs from the previous run
|
|
46
|
+
handleEvent: (event) => {
|
|
47
|
+
console.log('LevelCode Event', JSON.stringify(event))
|
|
48
|
+
},
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
main()
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Example 2: Custom Agents and Tools
|
|
56
|
+
|
|
57
|
+
Here, we create a full agent and custom tools that can be reused between runs.
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import { z } from 'zod/v4'
|
|
61
|
+
|
|
62
|
+
import { LevelCodeClient, getCustomToolDefinition } from '@levelcode/sdk'
|
|
63
|
+
|
|
64
|
+
import type { AgentDefinition } from '@levelcode/sdk'
|
|
65
|
+
|
|
66
|
+
async function main() {
|
|
67
|
+
const client = new LevelCodeClient({
|
|
68
|
+
// Note: You need to pass in your own API key.
|
|
69
|
+
// Get it here: https://www.levelcode.com/profile?tab=api-keys
|
|
70
|
+
apiKey: process.env.LEVELCODE_API_KEY,
|
|
71
|
+
// Optional directory agent runs from (if applicable).
|
|
72
|
+
cwd: process.cwd(),
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
// Define your own custom agents!
|
|
76
|
+
const myCustomAgent: AgentDefinition = {
|
|
77
|
+
id: 'my-custom-agent',
|
|
78
|
+
model: 'x-ai/grok-4-fast',
|
|
79
|
+
displayName: 'Sentiment analyzer',
|
|
80
|
+
toolNames: ['fetch_api_data'], // Defined below!
|
|
81
|
+
instructionsPrompt: `
|
|
82
|
+
1. Describe the different sentiments in the given prompt.
|
|
83
|
+
2. Score the prompt along the following 5 dimensions:
|
|
84
|
+
happiness, sadness, anger, fear, and surprise.`,
|
|
85
|
+
// ... other AgentDefinition properties
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// And define your own custom tools!
|
|
89
|
+
const myCustomTool = getCustomToolDefinition({
|
|
90
|
+
toolName: 'fetch_api_data',
|
|
91
|
+
description: 'Fetch data from an API endpoint',
|
|
92
|
+
inputSchema: z.object({
|
|
93
|
+
url: z.url(),
|
|
94
|
+
method: z.enum(['GET', 'POST']).default('GET'),
|
|
95
|
+
headers: z.record(z.string(), z.string()).optional(),
|
|
96
|
+
}),
|
|
97
|
+
exampleInputs: [{ url: 'https://api.example.com/data', method: 'GET' }],
|
|
98
|
+
execute: async ({ url, method, headers }) => {
|
|
99
|
+
const response = await fetch(url, { method, headers })
|
|
100
|
+
const data = await response.text()
|
|
101
|
+
return [
|
|
102
|
+
{
|
|
103
|
+
type: 'json' as const,
|
|
104
|
+
value: {
|
|
105
|
+
message: `API Response: ${data.slice(0, 5000)}...`,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
]
|
|
109
|
+
},
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
const { output } = await client.run({
|
|
113
|
+
// Run a custom agent by id. Must match an id in the agentDefinitions field below.
|
|
114
|
+
agent: 'my-custom-agent',
|
|
115
|
+
prompt: "Today I'm feeling very happy!",
|
|
116
|
+
|
|
117
|
+
// Provide custom agent and tool definitions:
|
|
118
|
+
agentDefinitions: [myCustomAgent],
|
|
119
|
+
customToolDefinitions: [myCustomTool],
|
|
120
|
+
|
|
121
|
+
handleEvent: (event) => {
|
|
122
|
+
// All events that happen during the run: agent start/finish, tool calls/results, text responses, errors.
|
|
123
|
+
console.log('LevelCode Event', JSON.stringify(event))
|
|
124
|
+
},
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
if (output.type === 'error') {
|
|
128
|
+
console.error(`The run failed:\n${output.message}`)
|
|
129
|
+
} else {
|
|
130
|
+
console.log('The run succeeded with output:', output)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
main()
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## API Reference
|
|
138
|
+
|
|
139
|
+
### Knowledge Files
|
|
140
|
+
|
|
141
|
+
Knowledge files provide project context to the agent. The SDK auto-discovers:
|
|
142
|
+
|
|
143
|
+
- **Project files**: `knowledge.md`, `AGENTS.md`, or `CLAUDE.md` in each directory (priority order)
|
|
144
|
+
- **User files**: `~/.knowledge.md`, `~/.AGENTS.md`, or `~/.CLAUDE.md` (case-insensitive)
|
|
145
|
+
|
|
146
|
+
Override with `knowledgeFiles` (replaces project files) or `userKnowledgeFiles` (merges with home directory files):
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
await client.run({
|
|
150
|
+
agent: 'levelcode/base@0.0.16',
|
|
151
|
+
prompt: 'Help me refactor',
|
|
152
|
+
knowledgeFiles: { 'knowledge.md': '# Guidelines\n- Use TypeScript' },
|
|
153
|
+
userKnowledgeFiles: { '~/.knowledge.md': '# Preferences\n- Be concise' },
|
|
154
|
+
})
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### File Filtering
|
|
158
|
+
|
|
159
|
+
The `fileFilter` option controls which files the agent can read:
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
const client = new LevelCodeClient({
|
|
163
|
+
apiKey: process.env.LEVELCODE_API_KEY,
|
|
164
|
+
fileFilter: (filePath) => {
|
|
165
|
+
if (filePath === '.env') return { status: 'blocked' }
|
|
166
|
+
if (filePath.endsWith('.env.example')) return { status: 'allow-example' }
|
|
167
|
+
return { status: 'allow' }
|
|
168
|
+
},
|
|
169
|
+
})
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**Statuses:** `'blocked'` (returns `[BLOCKED]`), `'allow-example'` (prefixes content with `[TEMPLATE]`), `'allow'` (normal read).
|
|
173
|
+
|
|
174
|
+
**Default behavior:** When no `fileFilter` is provided, gitignore checking is applied automatically. When a `fileFilter` IS provided, the caller owns all filtering.
|
|
175
|
+
|
|
176
|
+
### `loadLocalAgents(options)`
|
|
177
|
+
|
|
178
|
+
Loads agent definitions from `.agents` directories on disk.
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
import { loadLocalAgents, LevelCodeClient } from '@levelcode/sdk'
|
|
182
|
+
|
|
183
|
+
// Load from default locations (.agents in cwd, parent, or home)
|
|
184
|
+
const agents = await loadLocalAgents({ verbose: true })
|
|
185
|
+
|
|
186
|
+
// Or load from a specific directory
|
|
187
|
+
// const agents = await loadLocalAgents({ agentsPath: './my-agents' })
|
|
188
|
+
|
|
189
|
+
// Or load and validate agents (invalid agents are filtered out)
|
|
190
|
+
// const agents = await loadLocalAgents({ validate: true, verbose: true })
|
|
191
|
+
|
|
192
|
+
// Access source file path for debugging
|
|
193
|
+
for (const agent of Object.values(agents)) {
|
|
194
|
+
console.log(`${agent.id} loaded from ${agent._sourceFilePath}`)
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Use the loaded agents with client.run()
|
|
198
|
+
const client = new LevelCodeClient({ apiKey: process.env.LEVELCODE_API_KEY })
|
|
199
|
+
const result = await client.run({
|
|
200
|
+
agent: 'my-custom-agent',
|
|
201
|
+
agentDefinitions: Object.values(agents),
|
|
202
|
+
prompt: 'Hello',
|
|
203
|
+
})
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
#### Parameters
|
|
207
|
+
|
|
208
|
+
- **`agentsPath`** (string, optional): Path to a specific agents directory. If omitted, searches in `{cwd}/.agents`, `{cwd}/../.agents`, and `{homedir}/.agents`.
|
|
209
|
+
- **`verbose`** (boolean, optional): Whether to log errors during loading. Defaults to `false`.
|
|
210
|
+
- **`validate`** (boolean, optional): Whether to validate agents after loading. Invalid agents are filtered out. Defaults to `false`.
|
|
211
|
+
|
|
212
|
+
#### Returns
|
|
213
|
+
|
|
214
|
+
Returns a `Promise<LoadedAgents>` - a `Record<string, LoadedAgentDefinition>` of agent definitions keyed by their ID.
|
|
215
|
+
|
|
216
|
+
Each `LoadedAgentDefinition` extends `AgentDefinition` with:
|
|
217
|
+
- **`_sourceFilePath`** (string): The file path the agent was loaded from
|
|
218
|
+
|
|
219
|
+
#### Supported File Types
|
|
220
|
+
|
|
221
|
+
- `.ts`, `.tsx` - TypeScript files (automatically transpiled)
|
|
222
|
+
- `.js`, `.mjs`, `.cjs` - JavaScript files
|
|
223
|
+
|
|
224
|
+
Files ending in `.d.ts` or `.test.ts` are excluded.
|
|
225
|
+
|
|
226
|
+
### `client.run(options)`
|
|
227
|
+
|
|
228
|
+
Runs a LevelCode agent with the specified options.
|
|
229
|
+
|
|
230
|
+
#### Parameters
|
|
231
|
+
|
|
232
|
+
- **`agent`** (string, required): The agent to run. Use `'base'` for the default agent, or specify a custom agent ID if you made your own agent definition (passed with the `agentDefinitions` param).
|
|
233
|
+
|
|
234
|
+
- **`prompt`** (string, required): The user prompt describing what you want the agent to do.
|
|
235
|
+
|
|
236
|
+
- **`params`** (object, optional): Additional parameters for the agent. Most agents don't use this, but some custom agents can take a JSON object as input in addition to the user prompt string.
|
|
237
|
+
|
|
238
|
+
- **`handleEvent`** (function, optional): Callback function that receives every event during execution (assistant messages, tool calls, etc.). This allows you to stream the agent's progress in real-time. We will likely add a token-by-token streaming callback in the future.
|
|
239
|
+
|
|
240
|
+
- **`previousRun`** (object, optional): JSON state returned from a previous `run()` call. Use this to continue a conversation or session with the agent, maintaining context from previous interactions.
|
|
241
|
+
|
|
242
|
+
- **`projectFiles`** (object, optional): All the files in your project as a plain JavaScript object. Keys should be the full path from your current directory to each file, and values should be the string contents of the file. Example: `{ "src/index.ts": "console.log('hi')" }`. This helps LevelCode pick good source files for context. Note: This parameter was previously named `allFiles` but has been renamed for clarity.
|
|
243
|
+
|
|
244
|
+
- **`knowledgeFiles`** (object, optional): Knowledge files to inject into every `run()` call. Uses the same schema as `projectFiles` - keys are file paths and values are file contents. These files are added directly to the agent's context.
|
|
245
|
+
|
|
246
|
+
- **`agentDefinitions`** (array, optional): Array of custom agent definitions. Each object should satisfy the AgentDefinition type.
|
|
247
|
+
|
|
248
|
+
- **`customToolDefinitions`** (array, optional): Array of custom tool definitions that extend the agent's capabilities. Each tool definition includes a name, Zod schema for input validation, and a handler function. These tools can be called by the agent during execution.
|
|
249
|
+
|
|
250
|
+
- **`maxAgentSteps`** (number, optional): Maximum number of steps the agent can take before stopping. Use this as a safety measure in case your agent starts going off the rails. A reasonable number is around 20.
|
|
251
|
+
|
|
252
|
+
#### Returns
|
|
253
|
+
|
|
254
|
+
Returns a Promise that resolves to either a "success" or a "failure" object.
|
|
255
|
+
|
|
256
|
+
- The "success" object contains a `RunState` object which can be passed into subsequent runs via the `previousRun` parameter to resume the conversation.
|
|
257
|
+
- The "failure" object contains an `Error` object with a `name`, `message`, and `stack` properties.
|
|
258
|
+
|
|
259
|
+
The `RunState` object contains:
|
|
260
|
+
|
|
261
|
+
- `sessionState`: Internal state to be passed to the next run
|
|
262
|
+
- `output`: The agent's output (text, error, or other types)
|
|
263
|
+
|
|
264
|
+
## License
|
|
265
|
+
|
|
266
|
+
MIT
|