goatchain 0.0.16 → 0.0.18
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 +151 -42
- package/dist/index.js +139 -139
- package/dist/lib/access-control/controller.d.ts +1 -1
- package/dist/lib/access-control/index.d.ts +3 -3
- package/dist/lib/access-control/validators/index.d.ts +1 -1
- package/dist/tool/builtin/index.d.ts +2 -2
- package/dist/tool/builtin/task.d.ts +1 -1
- package/dist/tool/builtin/webSearch.d.ts +7 -3
- package/package.json +3 -4
package/README.md
CHANGED
|
@@ -74,9 +74,10 @@ const session = await agent.createSession({ id: 'my-session-id' })
|
|
|
74
74
|
|
|
75
75
|
// Create session with configuration overrides
|
|
76
76
|
const session = await agent.createSession({
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
maxIterations: 10,
|
|
78
|
+
requestParams: {
|
|
79
|
+
temperature: 0.7,
|
|
80
|
+
maxTokens: 2000,
|
|
80
81
|
},
|
|
81
82
|
})
|
|
82
83
|
```
|
|
@@ -84,12 +85,14 @@ const session = await agent.createSession({
|
|
|
84
85
|
### Session Configuration Options
|
|
85
86
|
|
|
86
87
|
```typescript
|
|
87
|
-
interface
|
|
88
|
+
interface CreateSessionOptions {
|
|
89
|
+
id?: string // Custom session ID
|
|
88
90
|
maxIterations?: number // Max agent loop iterations (default: 5)
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
requestParams?: {
|
|
92
|
+
temperature?: number // Model temperature
|
|
93
|
+
maxTokens?: number // Max output tokens
|
|
94
|
+
topP?: number // Nucleus sampling parameter
|
|
95
|
+
}
|
|
93
96
|
}
|
|
94
97
|
```
|
|
95
98
|
|
|
@@ -103,12 +106,6 @@ session.send('What is the weather today?')
|
|
|
103
106
|
session.send('First question')
|
|
104
107
|
// Wait for response...
|
|
105
108
|
session.send('Follow-up question')
|
|
106
|
-
|
|
107
|
-
// Message with options
|
|
108
|
-
session.send('Analyze this data', {
|
|
109
|
-
temperature: 0.7,
|
|
110
|
-
maxTokens: 2000,
|
|
111
|
-
})
|
|
112
109
|
```
|
|
113
110
|
|
|
114
111
|
### Receiving Events
|
|
@@ -291,7 +288,7 @@ const agent = new Agent({
|
|
|
291
288
|
name: 'MyAgent',
|
|
292
289
|
systemPrompt: 'You are a helpful assistant.',
|
|
293
290
|
model,
|
|
294
|
-
tools
|
|
291
|
+
tools, // Optional: ToolRegistry instance
|
|
295
292
|
stateStore, // Optional: for persistence
|
|
296
293
|
maxIterations: 5, // Optional: max loop iterations
|
|
297
294
|
maxConcurrentToolCalls: 5, // Optional: parallel tool calls
|
|
@@ -305,7 +302,7 @@ interface AgentOptions {
|
|
|
305
302
|
name: string // Agent name
|
|
306
303
|
systemPrompt: string // System instructions
|
|
307
304
|
model: ModelClient | ModelRef // LLM client or reference
|
|
308
|
-
tools?:
|
|
305
|
+
tools?: ToolRegistry // Tool registry (not an array)
|
|
309
306
|
stateStore?: StateStore // Persistence layer
|
|
310
307
|
maxIterations?: number // Max agent loop iterations (default: 5)
|
|
311
308
|
maxConcurrentToolCalls?: number // Max parallel tool calls (default: 5)
|
|
@@ -348,6 +345,8 @@ GoatChain includes 23 built-in tools:
|
|
|
348
345
|
|
|
349
346
|
```typescript
|
|
350
347
|
import {
|
|
348
|
+
Agent,
|
|
349
|
+
ToolRegistry,
|
|
351
350
|
ReadTool,
|
|
352
351
|
WriteTool,
|
|
353
352
|
EditTool,
|
|
@@ -358,27 +357,72 @@ import {
|
|
|
358
357
|
WebFetchTool,
|
|
359
358
|
} from 'goatchain'
|
|
360
359
|
|
|
360
|
+
// Create a tool registry and register tools
|
|
361
|
+
const tools = new ToolRegistry()
|
|
362
|
+
tools.register(new ReadTool())
|
|
363
|
+
tools.register(new WriteTool())
|
|
364
|
+
tools.register(new EditTool())
|
|
365
|
+
tools.register(new BashTool())
|
|
366
|
+
tools.register(new GrepTool())
|
|
367
|
+
tools.register(new GlobTool())
|
|
368
|
+
tools.register(new WebSearchTool({ apiKey: process.env.SERPER_API_KEY }))
|
|
369
|
+
tools.register(new WebFetchTool())
|
|
370
|
+
|
|
361
371
|
const agent = new Agent({
|
|
362
372
|
name: 'MyAgent',
|
|
363
373
|
systemPrompt: 'You are helpful.',
|
|
364
374
|
model,
|
|
365
|
-
tools
|
|
366
|
-
new ReadTool(),
|
|
367
|
-
new WriteTool(),
|
|
368
|
-
new EditTool(),
|
|
369
|
-
new BashTool(),
|
|
370
|
-
new GrepTool(),
|
|
371
|
-
new GlobTool(),
|
|
372
|
-
new WebSearchTool({ apiKey: process.env.SERPER_API_KEY }),
|
|
373
|
-
new WebFetchTool(),
|
|
374
|
-
],
|
|
375
|
+
tools,
|
|
375
376
|
})
|
|
376
377
|
```
|
|
377
378
|
|
|
379
|
+
### Configuring File Tool Working Directory
|
|
380
|
+
|
|
381
|
+
File-related tools (`ReadTool`, `WriteTool`, `EditTool`, `GlobTool`, `GrepTool`, `BashTool`) support configuring the working directory:
|
|
382
|
+
|
|
383
|
+
```typescript
|
|
384
|
+
import path from 'node:path'
|
|
385
|
+
|
|
386
|
+
// Define output directory
|
|
387
|
+
const OUTPUT_DIR = path.resolve(import.meta.dirname, 'output')
|
|
388
|
+
|
|
389
|
+
// Option 1: Set working directory only
|
|
390
|
+
const tools = new ToolRegistry()
|
|
391
|
+
tools.register(new ReadTool({ cwd: OUTPUT_DIR }))
|
|
392
|
+
tools.register(new WriteTool({ cwd: OUTPUT_DIR }))
|
|
393
|
+
tools.register(new GlobTool({ cwd: OUTPUT_DIR }))
|
|
394
|
+
tools.register(new GrepTool({ cwd: OUTPUT_DIR }))
|
|
395
|
+
tools.register(new BashTool({ cwd: OUTPUT_DIR }))
|
|
396
|
+
|
|
397
|
+
// Option 2: Restrict to specific directory (security sandbox)
|
|
398
|
+
// This prevents access to files outside the allowed directory
|
|
399
|
+
const tools = new ToolRegistry()
|
|
400
|
+
tools.register(new ReadTool({
|
|
401
|
+
cwd: OUTPUT_DIR,
|
|
402
|
+
allowedDirectory: OUTPUT_DIR // Only allow reads within OUTPUT_DIR
|
|
403
|
+
}))
|
|
404
|
+
tools.register(new WriteTool({
|
|
405
|
+
cwd: OUTPUT_DIR,
|
|
406
|
+
allowedDirectory: OUTPUT_DIR // Only allow writes within OUTPUT_DIR
|
|
407
|
+
}))
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
**Directory Configuration Options:**
|
|
411
|
+
|
|
412
|
+
| Option | Description | Example |
|
|
413
|
+
|--------|-------------|---------|
|
|
414
|
+
| `cwd` | Working directory for resolving relative paths | `{ cwd: '/app/output' }` |
|
|
415
|
+
| `allowedDirectory` | Restrict file access to this directory only (blocks path traversal) | `{ allowedDirectory: '/app/output' }` |
|
|
416
|
+
|
|
417
|
+
**When to use `allowedDirectory`:**
|
|
418
|
+
- When you want to sandbox the agent to a specific directory
|
|
419
|
+
- To prevent accidental access to sensitive files
|
|
420
|
+
- For production environments with security requirements
|
|
421
|
+
|
|
378
422
|
### Creating Custom Tools
|
|
379
423
|
|
|
380
424
|
```typescript
|
|
381
|
-
import { BaseTool } from 'goatchain'
|
|
425
|
+
import { BaseTool, ToolRegistry } from 'goatchain'
|
|
382
426
|
|
|
383
427
|
class MyCustomTool extends BaseTool {
|
|
384
428
|
name = 'my_tool'
|
|
@@ -402,11 +446,14 @@ class MyCustomTool extends BaseTool {
|
|
|
402
446
|
}
|
|
403
447
|
|
|
404
448
|
// Use it
|
|
449
|
+
const tools = new ToolRegistry()
|
|
450
|
+
tools.register(new MyCustomTool())
|
|
451
|
+
|
|
405
452
|
const agent = new Agent({
|
|
406
453
|
name: 'MyAgent',
|
|
407
454
|
systemPrompt: 'You are helpful.',
|
|
408
455
|
model,
|
|
409
|
-
tools
|
|
456
|
+
tools,
|
|
410
457
|
})
|
|
411
458
|
```
|
|
412
459
|
|
|
@@ -614,7 +661,7 @@ const model = createModel({
|
|
|
614
661
|
adapter: createOpenAIAdapter({
|
|
615
662
|
defaultModelId: 'gpt-4o',
|
|
616
663
|
apiKey: process.env.OPENAI_API_KEY!,
|
|
617
|
-
|
|
664
|
+
baseUrl: 'https://api.openai.com/v1', // Optional
|
|
618
665
|
organization: 'org-xxx', // Optional
|
|
619
666
|
}),
|
|
620
667
|
})
|
|
@@ -626,7 +673,7 @@ const model = createModel({
|
|
|
626
673
|
interface OpenAIAdapterOptions {
|
|
627
674
|
defaultModelId?: string // Default model ID
|
|
628
675
|
apiKey?: string // OpenAI API key
|
|
629
|
-
|
|
676
|
+
baseUrl?: string // Custom API endpoint (note: lowercase 'u')
|
|
630
677
|
organization?: string // OpenAI organization ID
|
|
631
678
|
defaultHeaders?: Record<string, string> // Custom headers
|
|
632
679
|
timeout?: number // Request timeout (ms)
|
|
@@ -650,7 +697,7 @@ const deepseek = createModel({
|
|
|
650
697
|
adapter: createOpenAIAdapter({
|
|
651
698
|
defaultModelId: 'deepseek-chat',
|
|
652
699
|
apiKey: process.env.DEEPSEEK_API_KEY!,
|
|
653
|
-
|
|
700
|
+
baseUrl: 'https://api.deepseek.com/v1',
|
|
654
701
|
}),
|
|
655
702
|
})
|
|
656
703
|
```
|
|
@@ -799,6 +846,7 @@ import {
|
|
|
799
846
|
Agent,
|
|
800
847
|
createModel,
|
|
801
848
|
createOpenAIAdapter,
|
|
849
|
+
ToolRegistry,
|
|
802
850
|
ReadTool,
|
|
803
851
|
WriteTool,
|
|
804
852
|
BashTool,
|
|
@@ -811,11 +859,16 @@ const model = createModel({
|
|
|
811
859
|
}),
|
|
812
860
|
})
|
|
813
861
|
|
|
862
|
+
const tools = new ToolRegistry()
|
|
863
|
+
tools.register(new ReadTool())
|
|
864
|
+
tools.register(new WriteTool())
|
|
865
|
+
tools.register(new BashTool())
|
|
866
|
+
|
|
814
867
|
const agent = new Agent({
|
|
815
868
|
name: 'File Assistant',
|
|
816
869
|
systemPrompt: 'You help users manage their files.',
|
|
817
870
|
model,
|
|
818
|
-
tools
|
|
871
|
+
tools,
|
|
819
872
|
})
|
|
820
873
|
|
|
821
874
|
const session = await agent.createSession()
|
|
@@ -971,6 +1024,65 @@ console.log(`Total messages: ${session.messages.length}`)
|
|
|
971
1024
|
console.log(`Total tokens: ${session.usage.totalTokens}`)
|
|
972
1025
|
```
|
|
973
1026
|
|
|
1027
|
+
### Example 6: File Operations with Directory Configuration
|
|
1028
|
+
|
|
1029
|
+
```typescript
|
|
1030
|
+
import path from 'node:path'
|
|
1031
|
+
import {
|
|
1032
|
+
Agent,
|
|
1033
|
+
createModel,
|
|
1034
|
+
createOpenAIAdapter,
|
|
1035
|
+
ToolRegistry,
|
|
1036
|
+
ReadTool,
|
|
1037
|
+
WriteTool,
|
|
1038
|
+
GlobTool,
|
|
1039
|
+
GrepTool,
|
|
1040
|
+
} from 'goatchain'
|
|
1041
|
+
|
|
1042
|
+
const model = createModel({
|
|
1043
|
+
adapter: createOpenAIAdapter({
|
|
1044
|
+
defaultModelId: 'gpt-4o',
|
|
1045
|
+
apiKey: process.env.OPENAI_API_KEY!,
|
|
1046
|
+
}),
|
|
1047
|
+
})
|
|
1048
|
+
|
|
1049
|
+
// Define output directory for agent's file operations
|
|
1050
|
+
const OUTPUT_DIR = path.resolve(process.cwd(), 'output')
|
|
1051
|
+
|
|
1052
|
+
// Configure tools with working directory and restrictions
|
|
1053
|
+
const tools = new ToolRegistry()
|
|
1054
|
+
tools.register(new ReadTool({
|
|
1055
|
+
cwd: OUTPUT_DIR,
|
|
1056
|
+
allowedDirectory: OUTPUT_DIR // Sandbox: only allow reads in OUTPUT_DIR
|
|
1057
|
+
}))
|
|
1058
|
+
tools.register(new WriteTool({
|
|
1059
|
+
cwd: OUTPUT_DIR,
|
|
1060
|
+
allowedDirectory: OUTPUT_DIR // Sandbox: only allow writes in OUTPUT_DIR
|
|
1061
|
+
}))
|
|
1062
|
+
tools.register(new GlobTool({ cwd: OUTPUT_DIR }))
|
|
1063
|
+
tools.register(new GrepTool({ cwd: OUTPUT_DIR }))
|
|
1064
|
+
|
|
1065
|
+
const agent = new Agent({
|
|
1066
|
+
name: 'Sandboxed File Agent',
|
|
1067
|
+
systemPrompt: `You are a file management assistant.
|
|
1068
|
+
All your file operations are restricted to the output directory.
|
|
1069
|
+
You can create, read, and modify files within this sandbox.`,
|
|
1070
|
+
model,
|
|
1071
|
+
tools,
|
|
1072
|
+
})
|
|
1073
|
+
|
|
1074
|
+
const session = await agent.createSession()
|
|
1075
|
+
session.send('Create a report.md file with a summary of today\'s tasks')
|
|
1076
|
+
|
|
1077
|
+
for await (const event of session.receive()) {
|
|
1078
|
+
if (event.type === 'text_delta') {
|
|
1079
|
+
process.stdout.write(event.delta)
|
|
1080
|
+
} else if (event.type === 'tool_call_start') {
|
|
1081
|
+
console.log(`\n[Tool] ${event.name}`)
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
```
|
|
1085
|
+
|
|
974
1086
|
## 📖 API Reference
|
|
975
1087
|
|
|
976
1088
|
### Agent Class
|
|
@@ -986,7 +1098,7 @@ new Agent(options: AgentOptions)
|
|
|
986
1098
|
- `name: string` - Agent name (required)
|
|
987
1099
|
- `systemPrompt: string` - System instructions (required)
|
|
988
1100
|
- `model: ModelClient | ModelRef` - LLM client (required)
|
|
989
|
-
- `tools?:
|
|
1101
|
+
- `tools?: ToolRegistry` - Tool registry (not an array)
|
|
990
1102
|
- `stateStore?: StateStore` - Persistence layer
|
|
991
1103
|
- `maxIterations?: number` - Max loop iterations (default: 5)
|
|
992
1104
|
- `maxConcurrentToolCalls?: number` - Max parallel tools (default: 5)
|
|
@@ -1001,10 +1113,11 @@ Create a new session.
|
|
|
1001
1113
|
```typescript
|
|
1002
1114
|
const session = await agent.createSession({
|
|
1003
1115
|
id: 'custom-id', // Optional custom ID
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1116
|
+
maxIterations: 10, // Optional max iterations
|
|
1117
|
+
requestParams: {
|
|
1118
|
+
// Optional request parameters
|
|
1007
1119
|
temperature: 0.7,
|
|
1120
|
+
maxTokens: 2000,
|
|
1008
1121
|
},
|
|
1009
1122
|
})
|
|
1010
1123
|
```
|
|
@@ -1062,15 +1175,12 @@ agent.setModel({ type: 'ref', ref: 'the-model' })
|
|
|
1062
1175
|
|
|
1063
1176
|
#### Methods
|
|
1064
1177
|
|
|
1065
|
-
**`send(input
|
|
1178
|
+
**`send(input): void`**
|
|
1066
1179
|
|
|
1067
1180
|
Send a message to the session.
|
|
1068
1181
|
|
|
1069
1182
|
```typescript
|
|
1070
|
-
session.send('Hello!'
|
|
1071
|
-
temperature: 0.8,
|
|
1072
|
-
maxTokens: 1000,
|
|
1073
|
-
})
|
|
1183
|
+
session.send('Hello!')
|
|
1074
1184
|
```
|
|
1075
1185
|
|
|
1076
1186
|
**`receive(options?): AsyncGenerator<AgentEvent>`**
|
|
@@ -1124,7 +1234,6 @@ session.restoreFromSnapshot(snapshot)
|
|
|
1124
1234
|
- `status: SessionStatus` - Session status ('idle' | 'running' | 'completed' | 'error')
|
|
1125
1235
|
- `messages: Message[]` - Message history
|
|
1126
1236
|
- `usage: Usage` - Token usage statistics
|
|
1127
|
-
- `configOverride?: SessionConfigOverride` - Config overrides
|
|
1128
1237
|
- `createdAt: number` - Creation timestamp
|
|
1129
1238
|
- `updatedAt: number` - Last update timestamp
|
|
1130
1239
|
|