@castari/sdk 0.0.5 → 0.0.7
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/dist/client.d.ts +7 -1
- package/dist/client.js +35 -12
- package/dist/const.js +1 -1
- package/dist/server.js +1 -1
- package/package.json +2 -2
package/dist/client.d.ts
CHANGED
|
@@ -8,13 +8,17 @@ export interface ClientOptions extends Partial<QueryConfig> {
|
|
|
8
8
|
connectionUrl?: string;
|
|
9
9
|
/** Anthropic API key (required unless present in process.env.ANTHROPIC_API_KEY) */
|
|
10
10
|
anthropicApiKey?: string;
|
|
11
|
+
/** Castari client ID (required for platform mode; otherwise read from env) */
|
|
12
|
+
clientId?: string;
|
|
13
|
+
/** Castari platform API key (used for auth when contacting the platform) */
|
|
14
|
+
platformApiKey?: string;
|
|
11
15
|
/** Enable debug logging */
|
|
12
16
|
debug?: boolean;
|
|
13
17
|
/** Snapshot name to deploy/start */
|
|
14
18
|
snapshot?: string;
|
|
15
19
|
/** Optional labels to apply to the sandbox (and filter by for reuse) */
|
|
16
20
|
labels?: Record<string, string>;
|
|
17
|
-
/** Optional volume name to mount at /home/
|
|
21
|
+
/** Optional volume name to mount at /home/castari/agent-workspace */
|
|
18
22
|
volume?: string;
|
|
19
23
|
/** Castari Platform API URL. Defaults to https://api.castari.com (or localhost in dev) */
|
|
20
24
|
platformUrl?: string;
|
|
@@ -26,6 +30,8 @@ export declare class CastariClient {
|
|
|
26
30
|
private options;
|
|
27
31
|
private messageHandlers;
|
|
28
32
|
private sandboxId?;
|
|
33
|
+
private resolvedClientId?;
|
|
34
|
+
private resolvedPlatformApiKey?;
|
|
29
35
|
constructor(options?: ClientOptions);
|
|
30
36
|
start(): Promise<void>;
|
|
31
37
|
private setupLocalConnection;
|
package/dist/client.js
CHANGED
|
@@ -5,6 +5,8 @@ export class CastariClient {
|
|
|
5
5
|
options;
|
|
6
6
|
messageHandlers = [];
|
|
7
7
|
sandboxId;
|
|
8
|
+
resolvedClientId;
|
|
9
|
+
resolvedPlatformApiKey;
|
|
8
10
|
constructor(options = {}) {
|
|
9
11
|
this.options = {
|
|
10
12
|
...options,
|
|
@@ -15,6 +17,10 @@ export class CastariClient {
|
|
|
15
17
|
if (!anthropicApiKey) {
|
|
16
18
|
throw new Error('ANTHROPIC_API_KEY is required');
|
|
17
19
|
}
|
|
20
|
+
this.resolvedClientId =
|
|
21
|
+
this.options.clientId || process.env.CASTARI_CLIENT_ID || undefined;
|
|
22
|
+
this.resolvedPlatformApiKey =
|
|
23
|
+
this.options.platformApiKey || process.env.CASTARI_API_KEY || undefined;
|
|
18
24
|
const connection = this.options.connectionUrl
|
|
19
25
|
? await this.setupLocalConnection()
|
|
20
26
|
: await this.setupPlatformConnection();
|
|
@@ -34,12 +40,10 @@ export class CastariClient {
|
|
|
34
40
|
}
|
|
35
41
|
const configHeaders = {
|
|
36
42
|
'Content-Type': 'application/json',
|
|
43
|
+
...connection.authHeaders,
|
|
37
44
|
};
|
|
38
|
-
if (connection.previewToken) {
|
|
39
|
-
configHeaders['x-daytona-preview-token'] = connection.previewToken;
|
|
40
|
-
}
|
|
41
45
|
let configResponse = null;
|
|
42
|
-
const maxConfigAttempts =
|
|
46
|
+
const maxConfigAttempts = 5;
|
|
43
47
|
for (let attempt = 1; attempt <= maxConfigAttempts; attempt++) {
|
|
44
48
|
configResponse = await fetch(connection.configUrl, {
|
|
45
49
|
method: 'POST',
|
|
@@ -74,8 +78,11 @@ export class CastariClient {
|
|
|
74
78
|
}
|
|
75
79
|
const wsUrlParams = new URLSearchParams();
|
|
76
80
|
wsUrlParams.set('token', connectionToken);
|
|
77
|
-
|
|
78
|
-
|
|
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
|
+
}
|
|
79
86
|
}
|
|
80
87
|
const wsUrlJoiner = connection.wsUrl.includes('?') ? '&' : '?';
|
|
81
88
|
const wsUrl = `${connection.wsUrl}${wsUrlJoiner}${wsUrlParams.toString()}`;
|
|
@@ -116,24 +123,33 @@ export class CastariClient {
|
|
|
116
123
|
};
|
|
117
124
|
}
|
|
118
125
|
async setupPlatformConnection() {
|
|
126
|
+
if (!this.resolvedClientId) {
|
|
127
|
+
throw new Error('CASTARI_CLIENT_ID is required when connecting via the Castari Platform');
|
|
128
|
+
}
|
|
119
129
|
const platformUrl = this.options.platformUrl || process.env.CASTARI_PLATFORM_URL || 'http://localhost:3000';
|
|
120
130
|
if (this.options.debug) {
|
|
121
131
|
console.log(`🚀 Requesting sandbox from ${platformUrl}...`);
|
|
122
132
|
}
|
|
123
133
|
const response = await fetch(`${platformUrl}/sandbox/start`, {
|
|
124
134
|
method: 'POST',
|
|
125
|
-
headers: {
|
|
135
|
+
headers: {
|
|
136
|
+
'Content-Type': 'application/json',
|
|
137
|
+
...(this.resolvedPlatformApiKey
|
|
138
|
+
? { Authorization: `Bearer ${this.resolvedPlatformApiKey}` }
|
|
139
|
+
: {}),
|
|
140
|
+
},
|
|
126
141
|
body: JSON.stringify({
|
|
127
142
|
snapshot: this.options.snapshot,
|
|
128
143
|
labels: this.options.labels,
|
|
129
|
-
volume: this.options.volume
|
|
144
|
+
volume: this.options.volume,
|
|
145
|
+
clientId: this.resolvedClientId
|
|
130
146
|
})
|
|
131
147
|
});
|
|
132
148
|
if (!response.ok) {
|
|
133
149
|
const errorText = await response.text();
|
|
134
150
|
throw new Error(`Failed to start sandbox: ${errorText}`);
|
|
135
151
|
}
|
|
136
|
-
const { id, url,
|
|
152
|
+
const { id, url, authHeaders, authParams } = await response.json();
|
|
137
153
|
this.sandboxId = id;
|
|
138
154
|
if (this.options.debug) {
|
|
139
155
|
console.log(`✅ Sandbox started: ${id} at ${url}`);
|
|
@@ -144,7 +160,8 @@ export class CastariClient {
|
|
|
144
160
|
return {
|
|
145
161
|
configUrl,
|
|
146
162
|
wsUrl: wsUrlBase,
|
|
147
|
-
|
|
163
|
+
authHeaders,
|
|
164
|
+
authParams,
|
|
148
165
|
cleanup: async () => {
|
|
149
166
|
await this.stop({ delete: true });
|
|
150
167
|
}
|
|
@@ -175,12 +192,18 @@ export class CastariClient {
|
|
|
175
192
|
if (this.sandboxId) {
|
|
176
193
|
const platformUrl = this.options.platformUrl || process.env.CASTARI_PLATFORM_URL || 'http://localhost:3000';
|
|
177
194
|
try {
|
|
195
|
+
const clientId = this.resolvedClientId || this.options.clientId || process.env.CASTARI_CLIENT_ID;
|
|
196
|
+
const apiKey = this.resolvedPlatformApiKey || this.options.platformApiKey || process.env.CASTARI_API_KEY;
|
|
178
197
|
const response = await fetch(`${platformUrl}/sandbox/stop`, {
|
|
179
198
|
method: 'POST',
|
|
180
|
-
headers: {
|
|
199
|
+
headers: {
|
|
200
|
+
'Content-Type': 'application/json',
|
|
201
|
+
...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}),
|
|
202
|
+
},
|
|
181
203
|
body: JSON.stringify({
|
|
182
204
|
sandboxId: this.sandboxId,
|
|
183
|
-
delete: options.delete
|
|
205
|
+
delete: options.delete,
|
|
206
|
+
clientId
|
|
184
207
|
})
|
|
185
208
|
});
|
|
186
209
|
if (!response.ok) {
|
package/dist/const.js
CHANGED
|
@@ -6,4 +6,4 @@ export const SERVER_PORT = 3000;
|
|
|
6
6
|
// Workspace configuration
|
|
7
7
|
export const WORKSPACE_DIR_NAME = 'agent-workspace';
|
|
8
8
|
// Connection token (one-time) configuration
|
|
9
|
-
export const CONNECTION_TOKEN_TTL_MS = 5 * 60 *
|
|
9
|
+
export const CONNECTION_TOKEN_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
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