@samrahimi/smol-js 0.1.0
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/README.md +295 -0
- package/dist/index.d.mts +793 -0
- package/dist/index.d.ts +793 -0
- package/dist/index.js +1771 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1719 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +65 -0
package/README.md
ADDED
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
# smol-js
|
|
2
|
+
|
|
3
|
+
A TypeScript port of the [smolagents](https://github.com/huggingface/smolagents) agentic framework. This library provides a CodeAgent that can solve tasks by generating and executing JavaScript code in a sandboxed environment.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **CodeAgent**: An LLM-powered agent that generates JavaScript code to solve tasks
|
|
8
|
+
- **Multi-step execution**: Variables persist between steps for complex workflows
|
|
9
|
+
- **Tool system**: Extensible tools that the agent can use as functions
|
|
10
|
+
- **Dynamic imports**: Import npm packages on-the-fly via CDN
|
|
11
|
+
- **OpenAI-compatible API**: Works with OpenRouter, OpenAI, Azure, and local servers
|
|
12
|
+
- **Streaming support**: Real-time output streaming from the LLM
|
|
13
|
+
- **Color-coded logging**: Beautiful terminal output with syntax highlighting
|
|
14
|
+
- **Error recovery**: Agent can recover from errors and try different approaches
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @samrahimi/smol-js
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Or with yarn:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
yarn add @samrahimi/smol-js
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { CodeAgent, OpenAIModel } from '@samrahimi/smol-js';
|
|
32
|
+
|
|
33
|
+
// Create the model (uses OPENAI_API_KEY env var)
|
|
34
|
+
const model = new OpenAIModel({
|
|
35
|
+
modelId: 'anthropic/claude-sonnet-4.5', // default, via OpenRouter
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Create the agent
|
|
39
|
+
const agent = new CodeAgent({
|
|
40
|
+
model,
|
|
41
|
+
maxSteps: 10,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Run a task
|
|
45
|
+
const result = await agent.run('Calculate the first 10 prime numbers');
|
|
46
|
+
|
|
47
|
+
console.log(result.output); // [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Configuration
|
|
51
|
+
|
|
52
|
+
### Environment Variables
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Required: API key for LLM provider
|
|
56
|
+
OPENAI_API_KEY=your-api-key
|
|
57
|
+
|
|
58
|
+
# Or use OpenRouter specifically
|
|
59
|
+
OPENROUTER_API_KEY=your-openrouter-key
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Model Configuration
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
const model = new OpenAIModel({
|
|
66
|
+
modelId: 'gpt-4', // Model identifier
|
|
67
|
+
apiKey: 'sk-...', // API key (or use env var)
|
|
68
|
+
baseUrl: 'https://api.openai.com/v1', // API endpoint
|
|
69
|
+
maxTokens: 4096, // Max tokens to generate
|
|
70
|
+
temperature: 0.7, // Generation temperature
|
|
71
|
+
timeout: 120000, // Request timeout in ms
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Agent Configuration
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
const agent = new CodeAgent({
|
|
79
|
+
model,
|
|
80
|
+
tools: [myTool], // Custom tools
|
|
81
|
+
maxSteps: 20, // Max iterations (default: 20)
|
|
82
|
+
codeExecutionDelay: 5000, // Delay before execution in ms (default: 5000)
|
|
83
|
+
customInstructions: '...', // Additional prompt instructions
|
|
84
|
+
verboseLevel: LogLevel.INFO, // Logging level
|
|
85
|
+
streamOutputs: true, // Stream LLM output
|
|
86
|
+
additionalAuthorizedImports: ['lodash', 'dayjs'], // Allowed npm packages
|
|
87
|
+
workingDirectory: '/path/to/dir', // Working dir for fs operations
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Creating Tools
|
|
92
|
+
|
|
93
|
+
Tools extend the agent's capabilities. Create a tool by extending the `Tool` class:
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
import { Tool } from '@samrahimi/smol-js';
|
|
97
|
+
import type { ToolInputs } from '@samrahimi/smol-js';
|
|
98
|
+
|
|
99
|
+
class WeatherTool extends Tool {
|
|
100
|
+
readonly name = 'get_weather';
|
|
101
|
+
readonly description = 'Get current weather for a city';
|
|
102
|
+
readonly inputs: ToolInputs = {
|
|
103
|
+
city: {
|
|
104
|
+
type: 'string',
|
|
105
|
+
description: 'The city name',
|
|
106
|
+
required: true,
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
readonly outputType = 'object';
|
|
110
|
+
|
|
111
|
+
async execute(args: Record<string, unknown>): Promise<unknown> {
|
|
112
|
+
const city = args.city as string;
|
|
113
|
+
// Fetch weather data...
|
|
114
|
+
return { city, temperature: 22, condition: 'sunny' };
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Use with agent
|
|
119
|
+
const agent = new CodeAgent({
|
|
120
|
+
model,
|
|
121
|
+
tools: [new WeatherTool()],
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Or use the `createTool` helper:
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import { createTool } from '@samrahimi/smol-js';
|
|
129
|
+
|
|
130
|
+
const addNumbers = createTool({
|
|
131
|
+
name: 'add',
|
|
132
|
+
description: 'Adds two numbers',
|
|
133
|
+
inputs: {
|
|
134
|
+
a: { type: 'number', description: 'First number' },
|
|
135
|
+
b: { type: 'number', description: 'Second number' },
|
|
136
|
+
},
|
|
137
|
+
outputType: 'number',
|
|
138
|
+
execute: async (args) => (args.a as number) + (args.b as number),
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Dynamic Imports
|
|
143
|
+
|
|
144
|
+
The agent can import npm packages dynamically using `importPackage()`:
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
const agent = new CodeAgent({
|
|
148
|
+
model,
|
|
149
|
+
additionalAuthorizedImports: ['lodash', 'dayjs', 'uuid'],
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// The agent can now use:
|
|
153
|
+
// const _ = await importPackage('lodash');
|
|
154
|
+
// const dayjs = await importPackage('dayjs');
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Packages are fetched from [esm.sh](https://esm.sh) CDN.
|
|
158
|
+
|
|
159
|
+
## Built-in Capabilities
|
|
160
|
+
|
|
161
|
+
The agent has access to:
|
|
162
|
+
|
|
163
|
+
- `console.log()` / `print()` - Output logging
|
|
164
|
+
- `fs` - File system operations (read, write, mkdir, etc.)
|
|
165
|
+
- `path` - Path utilities
|
|
166
|
+
- `fetch()` - HTTP requests
|
|
167
|
+
- `JSON`, `Math`, `Date` - Standard JavaScript globals
|
|
168
|
+
- `final_answer(value)` - Return the final result
|
|
169
|
+
|
|
170
|
+
## Log Levels
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
import { LogLevel } from '@samrahimi/smol-js';
|
|
174
|
+
|
|
175
|
+
LogLevel.OFF // No output
|
|
176
|
+
LogLevel.ERROR // Errors only
|
|
177
|
+
LogLevel.INFO // Normal output (default)
|
|
178
|
+
LogLevel.DEBUG // Detailed debugging
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Session Logging
|
|
182
|
+
|
|
183
|
+
All sessions are logged to `~/.smol-js/session-<timestamp>.log`.
|
|
184
|
+
|
|
185
|
+
## Examples
|
|
186
|
+
|
|
187
|
+
See the `examples/` folder for complete examples:
|
|
188
|
+
|
|
189
|
+
1. **01-simple-math.ts** - Basic calculation task
|
|
190
|
+
2. **02-dynamic-imports.ts** - Using npm packages dynamically
|
|
191
|
+
3. **03-variable-persistence.ts** - Multi-step state management
|
|
192
|
+
4. **04-research-with-tools.ts** - Custom tools for research tasks
|
|
193
|
+
5. **05-error-recovery.ts** - Handling and recovering from errors
|
|
194
|
+
|
|
195
|
+
Run all examples:
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
npm run run-examples
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Or run a specific example:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
npx tsx examples/01-simple-math.ts
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## API Reference
|
|
208
|
+
|
|
209
|
+
### CodeAgent
|
|
210
|
+
|
|
211
|
+
Main agent class that generates and executes JavaScript code.
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
class CodeAgent {
|
|
215
|
+
constructor(config: CodeAgentConfig)
|
|
216
|
+
run(task: string, reset?: boolean): Promise<RunResult>
|
|
217
|
+
stop(): void
|
|
218
|
+
reset(): void
|
|
219
|
+
addTool(tool: Tool): void
|
|
220
|
+
removeTool(name: string): boolean
|
|
221
|
+
getTools(): Map<string, Tool>
|
|
222
|
+
getMemory(): AgentMemory
|
|
223
|
+
getExecutor(): LocalExecutor
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### RunResult
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
interface RunResult {
|
|
231
|
+
output: unknown; // Final answer
|
|
232
|
+
steps: MemoryStep[]; // All execution steps
|
|
233
|
+
tokenUsage: TokenUsage; // Total token usage
|
|
234
|
+
duration: number; // Total time in ms
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Tool
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
abstract class Tool {
|
|
242
|
+
abstract readonly name: string;
|
|
243
|
+
abstract readonly description: string;
|
|
244
|
+
abstract readonly inputs: ToolInputs;
|
|
245
|
+
abstract readonly outputType: string;
|
|
246
|
+
|
|
247
|
+
abstract execute(args: Record<string, unknown>): Promise<unknown>;
|
|
248
|
+
setup(): Promise<void>;
|
|
249
|
+
call(args: Record<string, unknown>): Promise<unknown>;
|
|
250
|
+
toCodePrompt(): string;
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### LocalExecutor
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
class LocalExecutor {
|
|
258
|
+
constructor(config?: ExecutorConfig)
|
|
259
|
+
execute(code: string): Promise<CodeExecutionOutput>
|
|
260
|
+
sendTools(tools: Record<string, Tool>): void
|
|
261
|
+
sendVariables(variables: Record<string, unknown>): void
|
|
262
|
+
reset(): void
|
|
263
|
+
getState(): Record<string, unknown>
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Architectural Differences from Python smolagents
|
|
268
|
+
|
|
269
|
+
| Feature | Python smolagents | smol-js |
|
|
270
|
+
|---------|------------------|---------|
|
|
271
|
+
| Code execution | Python interpreter | Node.js vm module |
|
|
272
|
+
| Imports | `import` statement | `await importPackage()` |
|
|
273
|
+
| Tool definition | `@tool` decorator | Class extending `Tool` |
|
|
274
|
+
| Async support | Optional | All tools are async |
|
|
275
|
+
| Remote executors | E2B, Docker, etc. | Local only (for now) |
|
|
276
|
+
| Agent types | CodeAgent, ToolCallingAgent | CodeAgent only (for now) |
|
|
277
|
+
|
|
278
|
+
## Security Considerations
|
|
279
|
+
|
|
280
|
+
- Code executes in a sandboxed vm context
|
|
281
|
+
- Only authorized npm packages can be imported
|
|
282
|
+
- File system access is restricted to working directory
|
|
283
|
+
- Configurable execution delay allows user interruption
|
|
284
|
+
|
|
285
|
+
## Contributing
|
|
286
|
+
|
|
287
|
+
Contributions are welcome! Please open an issue or PR.
|
|
288
|
+
|
|
289
|
+
## License
|
|
290
|
+
|
|
291
|
+
MIT
|
|
292
|
+
|
|
293
|
+
## Credits
|
|
294
|
+
|
|
295
|
+
This is a TypeScript port of [smolagents](https://github.com/huggingface/smolagents) by Hugging Face.
|