@castari/sdk 0.0.1 → 0.0.3
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 +5 -1
- package/dist/client.js +42 -9
- package/dist/server.d.ts +2 -1
- package/dist/server.js +15 -1
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -44,6 +44,8 @@ export interface ClientOptions extends Partial<QueryConfig> {
|
|
|
44
44
|
ephemeral?: boolean;
|
|
45
45
|
/** Optional Daytona volume name to mount at /home/daytona/agent-workspace. Defaults to undefined (no volume). */
|
|
46
46
|
volume?: string;
|
|
47
|
+
/** Optional labels to apply to the sandbox (and filter by for reuse) */
|
|
48
|
+
labels?: Record<string, string>;
|
|
47
49
|
/** @deprecated Use `volume` instead */
|
|
48
50
|
workspaceVolumeName?: string;
|
|
49
51
|
}
|
|
@@ -60,5 +62,7 @@ export declare class CastariClient {
|
|
|
60
62
|
private handleMessage;
|
|
61
63
|
onMessage(handler: (message: WSOutputMessage) => void): () => void;
|
|
62
64
|
send(message: WSInputMessage): void;
|
|
63
|
-
stop(
|
|
65
|
+
stop(options?: {
|
|
66
|
+
delete?: boolean;
|
|
67
|
+
}): Promise<void>;
|
|
64
68
|
}
|
package/dist/client.js
CHANGED
|
@@ -174,9 +174,35 @@ export class CastariClient {
|
|
|
174
174
|
public: true,
|
|
175
175
|
volumes: volumeMounts,
|
|
176
176
|
};
|
|
177
|
-
|
|
178
|
-
if (this.options.
|
|
179
|
-
|
|
177
|
+
// Check for existing sandbox if labels are provided
|
|
178
|
+
if (this.options.labels) {
|
|
179
|
+
const existing = await this.daytona.list(this.options.labels);
|
|
180
|
+
if (existing.items.length > 0) {
|
|
181
|
+
// Use the first matching sandbox
|
|
182
|
+
this.sandbox = existing.items[0];
|
|
183
|
+
if (this.options.debug) {
|
|
184
|
+
console.log(`♻️ Found existing sandbox: ${this.sandbox.id} (${this.sandbox.state})`);
|
|
185
|
+
}
|
|
186
|
+
// Ensure it's started
|
|
187
|
+
if (this.sandbox.state !== 'started') {
|
|
188
|
+
if (this.options.debug) {
|
|
189
|
+
console.log('▶️ Starting existing sandbox...');
|
|
190
|
+
}
|
|
191
|
+
await this.sandbox.start();
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// Create new if not found
|
|
196
|
+
if (!this.sandbox) {
|
|
197
|
+
// Add labels to create params
|
|
198
|
+
const paramsWithLabels = {
|
|
199
|
+
...createParams,
|
|
200
|
+
labels: this.options.labels,
|
|
201
|
+
};
|
|
202
|
+
this.sandbox = await this.daytona.create(paramsWithLabels);
|
|
203
|
+
if (this.options.debug) {
|
|
204
|
+
console.log(`✅ Sandbox created: ${this.sandbox.id}`);
|
|
205
|
+
}
|
|
180
206
|
}
|
|
181
207
|
// Wait for sandbox to reach STARTED state before interacting with it
|
|
182
208
|
const sandboxAny = this.sandbox;
|
|
@@ -313,25 +339,32 @@ export class CastariClient {
|
|
|
313
339
|
}
|
|
314
340
|
this.ws.send(JSON.stringify(message));
|
|
315
341
|
}
|
|
316
|
-
async stop() {
|
|
342
|
+
async stop(options = { delete: true }) {
|
|
317
343
|
if (this.ws) {
|
|
318
344
|
this.ws.close();
|
|
319
345
|
}
|
|
320
346
|
if (this.sandbox) {
|
|
321
347
|
try {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
348
|
+
if (options.delete) {
|
|
349
|
+
await this.sandbox.delete();
|
|
350
|
+
if (this.options.debug)
|
|
351
|
+
console.log('🧹 Sandbox deleted');
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
354
|
+
await this.sandbox.stop();
|
|
355
|
+
if (this.options.debug)
|
|
356
|
+
console.log('🛑 Sandbox stopped (preserved)');
|
|
357
|
+
}
|
|
325
358
|
}
|
|
326
359
|
catch (err) {
|
|
327
360
|
const msg = err?.response?.data?.message || err?.message || String(err);
|
|
328
361
|
if (msg.includes('state change in progress')) {
|
|
329
362
|
if (this.options.debug) {
|
|
330
|
-
console.warn(
|
|
363
|
+
console.warn(`⚠️ Sandbox ${options.delete ? 'deletion' : 'stop'} skipped (state change in progress)`);
|
|
331
364
|
}
|
|
332
365
|
}
|
|
333
366
|
else {
|
|
334
|
-
console.error(
|
|
367
|
+
console.error(`Failed to ${options.delete ? 'delete' : 'stop'} sandbox:`, err);
|
|
335
368
|
}
|
|
336
369
|
}
|
|
337
370
|
}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { type Options } from '@anthropic-ai/claude-agent-sdk';
|
|
1
|
+
import { tool, type Options } from '@anthropic-ai/claude-agent-sdk';
|
|
2
2
|
export type CastariServerOptions = Partial<Options> & {
|
|
3
3
|
port?: number;
|
|
4
|
+
tools?: ReturnType<typeof tool>[];
|
|
4
5
|
};
|
|
5
6
|
export declare function serve(options?: CastariServerOptions): Promise<void>;
|
package/dist/server.js
CHANGED
|
@@ -2,7 +2,7 @@ import { randomBytes } from 'crypto';
|
|
|
2
2
|
import { mkdir } from 'fs/promises';
|
|
3
3
|
import { homedir } from 'os';
|
|
4
4
|
import { join } from 'path';
|
|
5
|
-
import { query, } from '@anthropic-ai/claude-agent-sdk';
|
|
5
|
+
import { query, createSdkMcpServer, } from '@anthropic-ai/claude-agent-sdk';
|
|
6
6
|
import { CONNECTION_TOKEN_TTL_MS, SERVER_PORT, WORKSPACE_DIR_NAME, } from './const';
|
|
7
7
|
import { handleMessage } from './message-handler';
|
|
8
8
|
const workspaceDirectory = process.env.CASTARI_WORKSPACE || join(homedir(), WORKSPACE_DIR_NAME);
|
|
@@ -68,6 +68,19 @@ async function* generateMessages() {
|
|
|
68
68
|
// Process messages from the SDK and send to WebSocket client
|
|
69
69
|
async function processMessages(initialOptions) {
|
|
70
70
|
try {
|
|
71
|
+
// Handle custom tools by creating an SDK MCP server
|
|
72
|
+
let mcpServers = initialOptions.mcpServers || {};
|
|
73
|
+
if (initialOptions.tools && initialOptions.tools.length > 0) {
|
|
74
|
+
const sdkServer = createSdkMcpServer({
|
|
75
|
+
name: 'castari-agent',
|
|
76
|
+
version: '1.0.0',
|
|
77
|
+
tools: initialOptions.tools,
|
|
78
|
+
});
|
|
79
|
+
mcpServers = {
|
|
80
|
+
...mcpServers,
|
|
81
|
+
'castari-agent': sdkServer,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
71
84
|
const options = {
|
|
72
85
|
settingSources: ['local'],
|
|
73
86
|
cwd: workspaceDirectory,
|
|
@@ -87,6 +100,7 @@ async function processMessages(initialOptions) {
|
|
|
87
100
|
}
|
|
88
101
|
},
|
|
89
102
|
...initialOptions, // Merge initial options (tools, systemPrompt, etc.)
|
|
103
|
+
mcpServers, // Override mcpServers with our injected one
|
|
90
104
|
...queryConfig, // Merge dynamic config from /config endpoint (overrides initial)
|
|
91
105
|
...(queryConfig.anthropicApiKey || process.env.ANTHROPIC_API_KEY
|
|
92
106
|
? {
|