@castari/sdk 0.0.6 → 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/LICENSE +21 -0
- package/README.md +116 -8
- package/dist/client.js +9 -7
- package/dist/server.js +1 -1
- package/package.json +2 -2
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Castari
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,39 +1,147 @@
|
|
|
1
1
|
# @castari/sdk
|
|
2
2
|
|
|
3
|
-
The SDK for building Castari agents.
|
|
3
|
+
The SDK for building and connecting to Castari agents.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npm install @castari/sdk
|
|
9
|
+
# or
|
|
10
|
+
bun add @castari/sdk
|
|
9
11
|
```
|
|
10
12
|
|
|
11
|
-
##
|
|
13
|
+
## Building Agents
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
### `serve(options)`
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
Starts the agent server. This should be the entrypoint of your agent.
|
|
16
18
|
|
|
17
19
|
```typescript
|
|
18
20
|
import { serve, tool } from '@castari/sdk'
|
|
19
21
|
|
|
20
|
-
const myTool = tool({ ... })
|
|
21
|
-
|
|
22
22
|
serve({
|
|
23
23
|
tools: [myTool],
|
|
24
24
|
systemPrompt: 'You are a helpful assistant.'
|
|
25
25
|
})
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
#### Options
|
|
29
|
+
|
|
30
|
+
| Property | Type | Description |
|
|
31
|
+
|----------|------|-------------|
|
|
32
|
+
| `tools` | `Tool[]` | Array of tools exposed by the agent |
|
|
33
|
+
| `systemPrompt` | `string` | The system prompt defining the agent's behavior |
|
|
34
|
+
| `allowedTools` | `string[]` | (Optional) Restrict which tools the agent can use |
|
|
35
|
+
| `port` | `number` | (Optional) Port to listen on. Defaults to `3000` |
|
|
36
|
+
|
|
37
|
+
By default, agents have access to all system tools (Bash, File Editing, etc.) plus any custom tools you define. Use `allowedTools` to restrict access:
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
serve({
|
|
41
|
+
tools: [myCustomTool],
|
|
42
|
+
allowedTools: ['my_custom_tool', 'Bash'] // Only these tools available
|
|
43
|
+
})
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### `tool(definition)`
|
|
47
|
+
|
|
48
|
+
Defines a custom tool for the agent.
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
import { tool } from '@castari/sdk'
|
|
52
|
+
|
|
53
|
+
const weatherTool = tool({
|
|
54
|
+
name: 'get_weather',
|
|
55
|
+
description: 'Get the weather for a location',
|
|
56
|
+
inputSchema: {
|
|
57
|
+
type: 'object',
|
|
58
|
+
properties: {
|
|
59
|
+
location: { type: 'string' }
|
|
60
|
+
},
|
|
61
|
+
required: ['location']
|
|
62
|
+
},
|
|
63
|
+
handler: async ({ location }) => {
|
|
64
|
+
return `The weather in ${location} is sunny.`
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Connecting to Agents
|
|
70
|
+
|
|
71
|
+
### `CastariClient`
|
|
72
|
+
|
|
73
|
+
A client for connecting to Castari agents.
|
|
29
74
|
|
|
30
75
|
```typescript
|
|
31
76
|
import { CastariClient } from '@castari/sdk/client'
|
|
32
77
|
|
|
33
78
|
const client = new CastariClient({
|
|
34
79
|
snapshot: 'my-agent',
|
|
35
|
-
|
|
80
|
+
platformUrl: process.env.CASTARI_PLATFORM_URL
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
await client.start()
|
|
84
|
+
|
|
85
|
+
client.onMessage((msg) => {
|
|
86
|
+
console.log('Agent:', msg)
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
client.send({
|
|
90
|
+
type: 'user_message',
|
|
91
|
+
data: { message: 'Hello!' }
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
// When done
|
|
95
|
+
await client.stop()
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
#### Constructor Options
|
|
99
|
+
|
|
100
|
+
| Property | Type | Description |
|
|
101
|
+
|----------|------|-------------|
|
|
102
|
+
| `platformUrl` | `string` | URL of the Castari Platform |
|
|
103
|
+
| `snapshot` | `string` | Name of the snapshot to use |
|
|
104
|
+
| `volume` | `string` | (Optional) Volume name for persistent storage |
|
|
105
|
+
| `connectionUrl` | `string` | (Optional) Direct URL for local development |
|
|
106
|
+
| `labels` | `Record<string, string>` | (Optional) Labels for sandbox reuse |
|
|
107
|
+
|
|
108
|
+
#### Methods
|
|
109
|
+
|
|
110
|
+
- `start()` - Creates a sandbox and connects to the agent
|
|
111
|
+
- `stop(options?)` - Disconnects and cleans up
|
|
112
|
+
- `{ delete: false }` - Stop but preserve sandbox for reuse
|
|
113
|
+
- `send(message)` - Send a message to the agent
|
|
114
|
+
- `onMessage(callback)` - Register a callback for incoming messages
|
|
115
|
+
|
|
116
|
+
### Sandbox Reuse
|
|
117
|
+
|
|
118
|
+
Use labels to reuse sandboxes across sessions:
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
const client = new CastariClient({
|
|
122
|
+
snapshot: 'my-agent',
|
|
123
|
+
volume: `user-${userId}`,
|
|
124
|
+
labels: {
|
|
125
|
+
userId,
|
|
126
|
+
app: 'my-app'
|
|
127
|
+
}
|
|
36
128
|
})
|
|
37
129
|
|
|
130
|
+
// First call creates, subsequent calls reuse
|
|
38
131
|
await client.start()
|
|
132
|
+
|
|
133
|
+
// Stop but preserve for later
|
|
134
|
+
await client.stop({ delete: false })
|
|
39
135
|
```
|
|
136
|
+
|
|
137
|
+
## Environment Variables
|
|
138
|
+
|
|
139
|
+
| Variable | Description |
|
|
140
|
+
|----------|-------------|
|
|
141
|
+
| `ANTHROPIC_API_KEY` | Your Anthropic API key |
|
|
142
|
+
| `CASTARI_PLATFORM_URL` | URL of the Castari Platform |
|
|
143
|
+
| `CASTARI_CLIENT_ID` | Your Castari client ID |
|
|
144
|
+
|
|
145
|
+
## License
|
|
146
|
+
|
|
147
|
+
MIT
|
package/dist/client.js
CHANGED
|
@@ -40,10 +40,8 @@ export class CastariClient {
|
|
|
40
40
|
}
|
|
41
41
|
const configHeaders = {
|
|
42
42
|
'Content-Type': 'application/json',
|
|
43
|
+
...connection.authHeaders,
|
|
43
44
|
};
|
|
44
|
-
if (connection.previewToken) {
|
|
45
|
-
configHeaders['x-daytona-preview-token'] = connection.previewToken;
|
|
46
|
-
}
|
|
47
45
|
let configResponse = null;
|
|
48
46
|
const maxConfigAttempts = 5;
|
|
49
47
|
for (let attempt = 1; attempt <= maxConfigAttempts; attempt++) {
|
|
@@ -80,8 +78,11 @@ export class CastariClient {
|
|
|
80
78
|
}
|
|
81
79
|
const wsUrlParams = new URLSearchParams();
|
|
82
80
|
wsUrlParams.set('token', connectionToken);
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
// Add any auth params from platform (for sandbox proxy auth)
|
|
82
|
+
if (connection.authParams) {
|
|
83
|
+
for (const [key, value] of Object.entries(connection.authParams)) {
|
|
84
|
+
wsUrlParams.set(key, value);
|
|
85
|
+
}
|
|
85
86
|
}
|
|
86
87
|
const wsUrlJoiner = connection.wsUrl.includes('?') ? '&' : '?';
|
|
87
88
|
const wsUrl = `${connection.wsUrl}${wsUrlJoiner}${wsUrlParams.toString()}`;
|
|
@@ -148,7 +149,7 @@ export class CastariClient {
|
|
|
148
149
|
const errorText = await response.text();
|
|
149
150
|
throw new Error(`Failed to start sandbox: ${errorText}`);
|
|
150
151
|
}
|
|
151
|
-
const { id, url,
|
|
152
|
+
const { id, url, authHeaders, authParams } = await response.json();
|
|
152
153
|
this.sandboxId = id;
|
|
153
154
|
if (this.options.debug) {
|
|
154
155
|
console.log(`✅ Sandbox started: ${id} at ${url}`);
|
|
@@ -159,7 +160,8 @@ export class CastariClient {
|
|
|
159
160
|
return {
|
|
160
161
|
configUrl,
|
|
161
162
|
wsUrl: wsUrlBase,
|
|
162
|
-
|
|
163
|
+
authHeaders,
|
|
164
|
+
authParams,
|
|
163
165
|
cleanup: async () => {
|
|
164
166
|
await this.stop({ delete: true });
|
|
165
167
|
}
|
package/dist/server.js
CHANGED
|
@@ -85,7 +85,7 @@ async function processMessages(initialOptions) {
|
|
|
85
85
|
settingSources: ['local'],
|
|
86
86
|
cwd: workspaceDirectory,
|
|
87
87
|
// Auto-approve tool usage (including file writes) inside the sandbox.
|
|
88
|
-
//
|
|
88
|
+
// Sandboxes are already isolated, so this keeps DX smooth without interactive prompts.
|
|
89
89
|
canUseTool: async (_toolName, input) => ({
|
|
90
90
|
behavior: 'allow',
|
|
91
91
|
updatedInput: input,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@castari/sdk",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"files": [
|
|
11
11
|
"dist"
|
|
12
12
|
],
|
|
13
|
-
"license": "
|
|
13
|
+
"license": "MIT",
|
|
14
14
|
"publishConfig": {
|
|
15
15
|
"access": "public"
|
|
16
16
|
},
|