@everruns/sdk 0.1.8 → 0.1.10

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.js CHANGED
@@ -3,17 +3,20 @@
3
3
  */
4
4
  import { ApiKey } from "./auth.js";
5
5
  import { validateAgentName, validateHarnessName, } from "./models.js";
6
- import { ApiError, AuthenticationError, NotFoundError, RateLimitError, } from "./errors.js";
6
+ import { ApiError, AuthenticationError, NotFoundError, RateLimitError, ValidationError, } from "./errors.js";
7
7
  import { EventStream } from "./sse.js";
8
8
  export class Everruns {
9
9
  apiKey;
10
10
  baseUrl;
11
+ orgId;
11
12
  agents;
12
13
  sessions;
13
14
  messages;
14
15
  events;
15
16
  capabilities;
16
- sessionFiles;
17
+ workspaces;
18
+ workspaceFiles;
19
+ memories;
17
20
  connections;
18
21
  budgets;
19
22
  constructor(options = {}) {
@@ -31,13 +34,19 @@ export class Everruns {
31
34
  // Example: "http://host/api/" + "/v1/agents" = "http://host/api//v1/agents" (wrong)
32
35
  // "http://host/api" + "/v1/agents" = "http://host/api/v1/agents" (correct)
33
36
  const rawBaseUrl = options.baseUrl ?? "https://custom.example.com/api";
34
- this.baseUrl = rawBaseUrl.replace(/\/+$/, "");
37
+ this.baseUrl = trimTrailingSlashes(rawBaseUrl);
38
+ const orgId = options.orgId !== undefined
39
+ ? options.orgId
40
+ : process.env.EVERRUNS_ORG_ID || undefined;
41
+ this.orgId = validateOrgId(orgId);
35
42
  this.agents = new AgentsClient(this);
36
43
  this.sessions = new SessionsClient(this);
37
44
  this.messages = new MessagesClient(this);
38
45
  this.events = new EventsClient(this);
39
46
  this.capabilities = new CapabilitiesClient(this);
40
- this.sessionFiles = new SessionFilesClient(this);
47
+ this.workspaces = new WorkspacesClient(this);
48
+ this.workspaceFiles = new WorkspaceFilesClient(this);
49
+ this.memories = new MemoriesClient(this);
41
50
  this.connections = new ConnectionsClient(this);
42
51
  this.budgets = new BudgetsClient(this);
43
52
  }
@@ -45,10 +54,12 @@ export class Everruns {
45
54
  * Create a client using environment variables.
46
55
  *
47
56
  * Reads `EVERRUNS_API_KEY` (required) and `EVERRUNS_API_URL` (optional).
57
+ * Reads `EVERRUNS_ORG_ID` when present.
48
58
  */
49
59
  static fromEnv() {
50
60
  const baseUrl = process.env.EVERRUNS_API_URL;
51
- return new Everruns({ baseUrl });
61
+ const orgId = process.env.EVERRUNS_ORG_ID || undefined;
62
+ return new Everruns({ baseUrl, orgId });
52
63
  }
53
64
  /**
54
65
  * Build full URL from a path, adding the /v1 prefix.
@@ -64,8 +75,7 @@ export class Everruns {
64
75
  const response = await fetch(url, {
65
76
  ...options,
66
77
  headers: {
67
- Authorization: this.apiKey.toHeader(),
68
- "Content-Type": "application/json",
78
+ ...this.authHeaders("application/json"),
69
79
  ...options.headers,
70
80
  },
71
81
  });
@@ -95,7 +105,7 @@ export class Everruns {
95
105
  const response = await fetch(url, {
96
106
  ...options,
97
107
  headers: {
98
- Authorization: this.apiKey.toHeader(),
108
+ ...this.authHeaders(),
99
109
  ...options.headers,
100
110
  },
101
111
  });
@@ -120,6 +130,43 @@ export class Everruns {
120
130
  getAuthHeader() {
121
131
  return this.apiKey.toHeader();
122
132
  }
133
+ getOrgId() {
134
+ return this.orgId;
135
+ }
136
+ authHeaders(contentType) {
137
+ const headers = {
138
+ Authorization: this.apiKey.toHeader(),
139
+ };
140
+ if (contentType !== undefined) {
141
+ headers["Content-Type"] = contentType;
142
+ }
143
+ if (this.orgId !== undefined) {
144
+ headers["X-Org-Id"] = this.orgId;
145
+ }
146
+ return headers;
147
+ }
148
+ }
149
+ function validateOrgId(orgId) {
150
+ if (orgId === undefined)
151
+ return undefined;
152
+ if (orgId.length === 0) {
153
+ throw new ValidationError("orgId cannot be empty");
154
+ }
155
+ try {
156
+ new Headers({ "X-Org-Id": orgId });
157
+ }
158
+ catch (error) {
159
+ const message = error instanceof Error ? error.message : String(error);
160
+ throw new ValidationError(`Invalid orgId header: ${message}`);
161
+ }
162
+ return orgId;
163
+ }
164
+ function trimTrailingSlashes(value) {
165
+ let end = value.length;
166
+ while (end > 0 && value.charCodeAt(end - 1) === 47) {
167
+ end -= 1;
168
+ }
169
+ return value.slice(0, end);
123
170
  }
124
171
  class AgentsClient {
125
172
  client;
@@ -165,6 +212,61 @@ class AgentsClient {
165
212
  async get(agentId) {
166
213
  return this.client.fetch(`/agents/${agentId}`);
167
214
  }
215
+ /** Get aggregate usage stats for an agent. */
216
+ async stats(agentId) {
217
+ return this.client.fetch(`/agents/${agentId}/stats`);
218
+ }
219
+ /** List recent behavioral health check runs for an agent. */
220
+ async listHealthChecks(agentId) {
221
+ return this.client.fetch(`/agents/${agentId}/health-checks`);
222
+ }
223
+ /** Trigger a behavioral health check for an agent. */
224
+ async triggerHealthCheck(agentId) {
225
+ return this.client.fetch(`/agents/${agentId}/health-checks`, {
226
+ method: "POST",
227
+ });
228
+ }
229
+ /** Get a single health check run for an agent. */
230
+ async getHealthCheck(agentId, runId) {
231
+ return this.client.fetch(`/agents/${agentId}/health-checks/${runId}`);
232
+ }
233
+ /** List saved versions for an agent. */
234
+ async listVersions(agentId) {
235
+ return this.client.fetch(`/agents/${agentId}/versions`);
236
+ }
237
+ /** Save the current agent configuration as a version. */
238
+ async createVersion(agentId, request = {}) {
239
+ return this.client.fetch(`/agents/${agentId}/versions`, {
240
+ method: "POST",
241
+ body: JSON.stringify(toCreateAgentVersionBody(request)),
242
+ });
243
+ }
244
+ /** Set the default version for an agent. */
245
+ async setDefaultVersion(agentId, request) {
246
+ return this.client.fetch(`/agents/${agentId}/versions/default`, {
247
+ method: "POST",
248
+ body: JSON.stringify({ version_id: request.versionId }),
249
+ });
250
+ }
251
+ /** Diff two saved agent versions. */
252
+ async diffVersions(agentId, fromVersionId, toVersionId) {
253
+ return this.client.fetch(`/agents/${agentId}/versions/${fromVersionId}/diff/${toVersionId}`);
254
+ }
255
+ /** Create a new agent from a saved version. */
256
+ async forkVersion(agentId, versionId, request) {
257
+ validateAgentName(request.name);
258
+ return this.client.fetch(`/agents/${agentId}/versions/${versionId}/fork`, {
259
+ method: "POST",
260
+ body: JSON.stringify(toForkAgentVersionBody(request)),
261
+ });
262
+ }
263
+ /** Restore an agent from a saved version. */
264
+ async rollbackVersion(agentId, versionId, request = {}) {
265
+ return this.client.fetch(`/agents/${agentId}/versions/${versionId}/rollback`, {
266
+ method: "POST",
267
+ body: JSON.stringify(toRollbackAgentVersionBody(request)),
268
+ });
269
+ }
168
270
  async list(options) {
169
271
  const query = options?.search
170
272
  ? `?search=${encodeURIComponent(options.search)}`
@@ -201,6 +303,18 @@ class AgentsClient {
201
303
  async export(agentId) {
202
304
  return this.client.fetchText(`/agents/${agentId}/export`);
203
305
  }
306
+ /** Run advisory checks against an agent shape. */
307
+ async analyze(request) {
308
+ return this.client.fetch("/agents/analyze", {
309
+ method: "POST",
310
+ body: JSON.stringify({
311
+ system_prompt: request.systemPrompt,
312
+ capabilities: request.capabilities ?? [],
313
+ tools: request.tools ?? [],
314
+ mcpServers: request.mcpServers,
315
+ }),
316
+ });
317
+ }
204
318
  }
205
319
  class SessionsClient {
206
320
  client;
@@ -239,6 +353,9 @@ class SessionsClient {
239
353
  if (request.capabilities?.length) {
240
354
  body.capabilities = request.capabilities;
241
355
  }
356
+ if (request.tools?.length) {
357
+ body.tools = request.tools;
358
+ }
242
359
  if (request.initialFiles !== undefined) {
243
360
  body.initial_files = request.initialFiles.map((file) => ({
244
361
  path: file.path,
@@ -335,23 +452,52 @@ class MessagesClient {
335
452
  /**
336
453
  * Send tool results back to the session.
337
454
  *
338
- * Use after receiving tool calls from an `output.message.completed`
455
+ * Use after receiving tool calls from a `tool.call_requested`
339
456
  * event to provide results from locally-executed tools.
340
457
  */
341
458
  async createToolResults(sessionId, results) {
342
- const request = {
343
- message: { role: "tool_result", content: results },
344
- };
345
- return this.client.fetch(`/sessions/${sessionId}/messages`, {
346
- method: "POST",
347
- body: JSON.stringify(request),
459
+ const toolResults = results.map((part) => {
460
+ if (part.type !== "tool_result" || !part.tool_call_id) {
461
+ throw new Error("createToolResults accepts only tool_result content parts");
462
+ }
463
+ return {
464
+ tool_call_id: part.tool_call_id,
465
+ result: part.result,
466
+ error: part.error,
467
+ };
348
468
  });
469
+ const body = JSON.stringify({ tool_results: toolResults });
470
+ let delay = 100;
471
+ for (let attempt = 0; attempt <= 5; attempt++) {
472
+ try {
473
+ return await this.client.fetch(`/sessions/${sessionId}/tool-results`, {
474
+ method: "POST",
475
+ body,
476
+ });
477
+ }
478
+ catch (error) {
479
+ if (attempt >= 5 || !isToolResultsPendingConflict(error)) {
480
+ throw error;
481
+ }
482
+ await sleep(delay);
483
+ delay *= 2;
484
+ }
485
+ }
486
+ throw new Error("unreachable");
349
487
  }
350
488
  async list(sessionId) {
351
489
  const response = await this.client.fetch(`/sessions/${sessionId}/messages`);
352
490
  return response.messages;
353
491
  }
354
492
  }
493
+ function isToolResultsPendingConflict(error) {
494
+ return (error instanceof ApiError &&
495
+ error.statusCode === 409 &&
496
+ String(error.body).includes("not waiting for tool results"));
497
+ }
498
+ function sleep(ms) {
499
+ return new Promise((resolve) => setTimeout(resolve, ms));
500
+ }
355
501
  class EventsClient {
356
502
  client;
357
503
  constructor(client) {
@@ -375,9 +521,36 @@ class EventsClient {
375
521
  params.set("limit", String(options.limit));
376
522
  if (options?.beforeSequence != null)
377
523
  params.set("before_sequence", String(options.beforeSequence));
524
+ if (options?.afterSequence != null)
525
+ params.set("after_sequence", String(options.afterSequence));
526
+ if (options?.around)
527
+ params.set("around", options.around);
528
+ if (options?.window != null)
529
+ params.set("window", String(options.window));
530
+ if (options?.fromTs)
531
+ params.set("from_ts", options.fromTs);
532
+ if (options?.toTs)
533
+ params.set("to_ts", options.toTs);
534
+ if (options?.turnId)
535
+ params.set("turn_id", options.turnId);
536
+ if (options?.execId)
537
+ params.set("exec_id", options.execId);
538
+ if (options?.traceId)
539
+ params.set("trace_id", options.traceId);
540
+ if (options?.tags) {
541
+ for (const tag of options.tags) {
542
+ params.append("tags", tag);
543
+ }
544
+ }
545
+ if (options?.toolName)
546
+ params.set("tool_name", options.toolName);
547
+ if (options?.q)
548
+ params.set("q", options.q);
549
+ if (options?.orderDesc !== undefined)
550
+ params.set("order_desc", String(options.orderDesc));
378
551
  const query = params.toString() ? `?${params}` : "";
379
552
  const response = await this.client.fetch(`/sessions/${sessionId}/events${query}`);
380
- return response.events;
553
+ return response.data;
381
554
  }
382
555
  /**
383
556
  * Stream events from a session via SSE with automatic reconnection.
@@ -402,7 +575,7 @@ class EventsClient {
402
575
  stream(sessionId, options) {
403
576
  // Build base URL (without since_id - EventStream handles that for reconnection)
404
577
  const url = this.client.getStreamUrl(`/sessions/${sessionId}/sse`);
405
- return new EventStream(url, this.client.getAuthHeader(), options);
578
+ return new EventStream(url, this.client.getAuthHeader(), options, this.client.getOrgId());
406
579
  }
407
580
  }
408
581
  class CapabilitiesClient {
@@ -421,89 +594,258 @@ class CapabilitiesClient {
421
594
  params.set("limit", String(options.limit));
422
595
  const query = params.toString() ? `?${params.toString()}` : "";
423
596
  const response = await this.client.fetch(`/capabilities${query}`);
424
- return { data: response.data, total: response.total ?? 0, offset: response.offset ?? 0, limit: response.limit ?? 0 };
597
+ return {
598
+ data: response.data,
599
+ total: response.total ?? 0,
600
+ offset: response.offset ?? 0,
601
+ limit: response.limit ?? 0,
602
+ };
425
603
  }
426
604
  /** Get a specific capability by ID. */
427
605
  async get(capabilityId) {
428
606
  return this.client.fetch(`/capabilities/${capabilityId}`);
429
607
  }
608
+ /** List adoptable guardrail presets. */
609
+ async listGuardrailExamples() {
610
+ return this.client.fetch("/capabilities/guardrails/examples");
611
+ }
612
+ /** Evaluate a guardrails config against sample content. */
613
+ async dryRunGuardrails(request) {
614
+ return this.client.fetch("/capabilities/guardrails/dry-run", {
615
+ method: "POST",
616
+ body: JSON.stringify({
617
+ config: request.config,
618
+ stage: request.stage,
619
+ text: request.text,
620
+ tool_name: request.toolName,
621
+ }),
622
+ });
623
+ }
624
+ }
625
+ class WorkspacesClient {
626
+ client;
627
+ constructor(client) {
628
+ this.client = client;
629
+ }
630
+ /** List workspaces. */
631
+ async list(options) {
632
+ const params = new URLSearchParams();
633
+ if (options?.search)
634
+ params.set("search", options.search);
635
+ if (options?.includeArchived != null) {
636
+ params.set("include_archived", String(options.includeArchived));
637
+ }
638
+ const query = params.toString() ? `?${params}` : "";
639
+ const response = await this.client.fetch(`/workspaces${query}`);
640
+ return response.data;
641
+ }
642
+ /** Create a workspace. */
643
+ async create(request) {
644
+ return this.client.fetch("/workspaces", {
645
+ method: "POST",
646
+ body: JSON.stringify(request),
647
+ });
648
+ }
649
+ /** Get a workspace by ID. */
650
+ async get(workspaceId) {
651
+ return this.client.fetch(`/workspaces/${workspaceId}`);
652
+ }
653
+ /** Update a workspace. */
654
+ async update(workspaceId, request) {
655
+ return this.client.fetch(`/workspaces/${workspaceId}`, {
656
+ method: "PATCH",
657
+ body: JSON.stringify(request),
658
+ });
659
+ }
660
+ /** Archive a workspace. */
661
+ async delete(workspaceId) {
662
+ await this.client.fetch(`/workspaces/${workspaceId}`, { method: "DELETE" });
663
+ }
430
664
  }
431
- class SessionFilesClient {
665
+ class WorkspaceFilesClient {
432
666
  client;
433
667
  constructor(client) {
434
668
  this.client = client;
435
669
  }
436
670
  /** List files in a directory. */
437
- async list(sessionId, options) {
671
+ async list(workspaceId, options) {
438
672
  const fsPath = options?.path
439
- ? `/sessions/${sessionId}/fs/${options.path.replace(/^\//, "")}`
440
- : `/sessions/${sessionId}/fs`;
673
+ ? `/workspaces/${workspaceId}/fs/${options.path.replace(/^\//, "")}`
674
+ : `/workspaces/${workspaceId}/fs`;
441
675
  const params = new URLSearchParams();
442
676
  if (options?.recursive)
443
677
  params.set("recursive", "true");
444
678
  const query = params.toString() ? `?${params}` : "";
445
679
  const response = await this.client.fetch(`${fsPath}${query}`);
446
- return { data: response.data, total: response.total ?? 0, offset: response.offset ?? 0, limit: response.limit ?? 0 };
680
+ return {
681
+ data: response.data,
682
+ total: response.total ?? 0,
683
+ offset: response.offset ?? 0,
684
+ limit: response.limit ?? 0,
685
+ };
447
686
  }
448
687
  /** Read a file's content. */
449
- async read(sessionId, path) {
450
- return this.client.fetch(`/sessions/${sessionId}/fs/${path.replace(/^\//, "")}`);
688
+ async read(workspaceId, path) {
689
+ return this.client.fetch(`/workspaces/${workspaceId}/fs/${path.replace(/^\//, "")}`);
451
690
  }
452
691
  /** Create a file. */
453
- async create(sessionId, path, content, options) {
692
+ async create(workspaceId, path, content, options) {
454
693
  const body = { content };
455
694
  if (options?.encoding)
456
695
  body.encoding = options.encoding;
457
696
  if (options?.isReadonly != null)
458
697
  body.is_readonly = options.isReadonly;
459
- return this.client.fetch(`/sessions/${sessionId}/fs/${path.replace(/^\//, "")}`, { method: "POST", body: JSON.stringify(body) });
698
+ return this.client.fetch(`/workspaces/${workspaceId}/fs/${path.replace(/^\//, "")}`, { method: "POST", body: JSON.stringify(body) });
460
699
  }
461
700
  /** Create a directory. */
462
- async createDir(sessionId, path) {
463
- return this.client.fetch(`/sessions/${sessionId}/fs/${path.replace(/^\//, "")}`, { method: "POST", body: JSON.stringify({ is_directory: true }) });
701
+ async createDir(workspaceId, path) {
702
+ return this.client.fetch(`/workspaces/${workspaceId}/fs/${path.replace(/^\//, "")}`, { method: "POST", body: JSON.stringify({ is_directory: true }) });
464
703
  }
465
704
  /** Update a file's content. */
466
- async update(sessionId, path, content, options) {
705
+ async update(workspaceId, path, content, options) {
467
706
  const body = { content };
468
707
  if (options?.encoding)
469
708
  body.encoding = options.encoding;
470
709
  if (options?.isReadonly != null)
471
710
  body.is_readonly = options.isReadonly;
472
- return this.client.fetch(`/sessions/${sessionId}/fs/${path.replace(/^\//, "")}`, { method: "PUT", body: JSON.stringify(body) });
711
+ return this.client.fetch(`/workspaces/${workspaceId}/fs/${path.replace(/^\//, "")}`, { method: "PUT", body: JSON.stringify(body) });
473
712
  }
474
713
  /** Delete a file or directory. */
475
- async delete(sessionId, path, options) {
714
+ async delete(workspaceId, path, options) {
476
715
  const params = new URLSearchParams();
477
716
  if (options?.recursive)
478
717
  params.set("recursive", "true");
479
718
  const query = params.toString() ? `?${params}` : "";
480
- return this.client.fetch(`/sessions/${sessionId}/fs/${path.replace(/^\//, "")}${query}`, { method: "DELETE" });
719
+ return this.client.fetch(`/workspaces/${workspaceId}/fs/${path.replace(/^\//, "")}${query}`, { method: "DELETE" });
481
720
  }
482
721
  /** Move/rename a file. */
483
- async moveFile(sessionId, srcPath, dstPath) {
484
- return this.client.fetch(`/sessions/${sessionId}/fs/_/move`, {
722
+ async moveFile(workspaceId, srcPath, dstPath) {
723
+ return this.client.fetch(`/workspaces/${workspaceId}/fs/_/move`, {
485
724
  method: "POST",
486
725
  body: JSON.stringify({ src_path: srcPath, dst_path: dstPath }),
487
726
  });
488
727
  }
489
728
  /** Copy a file. */
490
- async copyFile(sessionId, srcPath, dstPath) {
491
- return this.client.fetch(`/sessions/${sessionId}/fs/_/copy`, {
729
+ async copyFile(workspaceId, srcPath, dstPath) {
730
+ return this.client.fetch(`/workspaces/${workspaceId}/fs/_/copy`, {
492
731
  method: "POST",
493
732
  body: JSON.stringify({ src_path: srcPath, dst_path: dstPath }),
494
733
  });
495
734
  }
496
735
  /** Search files with regex. */
497
- async grep(sessionId, pattern, options) {
736
+ async grep(workspaceId, pattern, options) {
498
737
  const body = { pattern };
499
738
  if (options?.pathPattern)
500
739
  body.path_pattern = options.pathPattern;
501
- const response = await this.client.fetch(`/sessions/${sessionId}/fs/_/grep`, { method: "POST", body: JSON.stringify(body) });
740
+ const response = await this.client.fetch(`/workspaces/${workspaceId}/fs/_/grep`, { method: "POST", body: JSON.stringify(body) });
502
741
  return response.data;
503
742
  }
504
743
  /** Get file or directory stat. */
505
- async stat(sessionId, path) {
506
- return this.client.fetch(`/sessions/${sessionId}/fs/_/stat`, {
744
+ async stat(workspaceId, path) {
745
+ return this.client.fetch(`/workspaces/${workspaceId}/fs/_/stat`, {
746
+ method: "POST",
747
+ body: JSON.stringify({ path }),
748
+ });
749
+ }
750
+ }
751
+ class MemoriesClient {
752
+ client;
753
+ constructor(client) {
754
+ this.client = client;
755
+ }
756
+ /** List memories. */
757
+ async list(options) {
758
+ const params = new URLSearchParams();
759
+ if (options?.search)
760
+ params.set("search", options.search);
761
+ if (options?.includeArchived != null) {
762
+ params.set("include_archived", String(options.includeArchived));
763
+ }
764
+ const query = params.toString() ? `?${params}` : "";
765
+ const response = await this.client.fetch(`/memories${query}`);
766
+ return response.data;
767
+ }
768
+ /** Create a memory. */
769
+ async create(request) {
770
+ return this.client.fetch("/memories", {
771
+ method: "POST",
772
+ body: JSON.stringify(request),
773
+ });
774
+ }
775
+ /** Get a memory by ID. */
776
+ async get(memoryId) {
777
+ return this.client.fetch(`/memories/${memoryId}`);
778
+ }
779
+ /** Update a memory. */
780
+ async update(memoryId, request) {
781
+ return this.client.fetch(`/memories/${memoryId}`, {
782
+ method: "PATCH",
783
+ body: JSON.stringify(request),
784
+ });
785
+ }
786
+ /** Archive a memory. */
787
+ async delete(memoryId) {
788
+ await this.client.fetch(`/memories/${memoryId}`, { method: "DELETE" });
789
+ }
790
+ /** Trigger memory sync now. */
791
+ async sync(memoryId) {
792
+ return this.client.fetch(`/memories/${memoryId}/sync`, {
793
+ method: "POST",
794
+ });
795
+ }
796
+ /** List memory files at the root. */
797
+ async listFiles(memoryId) {
798
+ const response = await this.client.fetch(`/memories/${memoryId}/fs`);
799
+ return response.data;
800
+ }
801
+ /** Read a memory file. */
802
+ async readFile(memoryId, path) {
803
+ return this.client.fetch(`/memories/${memoryId}/fs/${path.replace(/^\//, "")}`);
804
+ }
805
+ /** Download a memory file as text. */
806
+ async downloadFile(memoryId, path) {
807
+ return this.client.fetchText(`/memories/${memoryId}/fs/_/download/${path.replace(/^\//, "")}`);
808
+ }
809
+ /** Create a memory file. */
810
+ async createFile(memoryId, path, request) {
811
+ return this.client.fetch(`/memories/${memoryId}/fs/${path.replace(/^\//, "")}`, {
812
+ method: "POST",
813
+ body: JSON.stringify({
814
+ content: request.content,
815
+ encoding: request.encoding,
816
+ is_directory: request.isDirectory,
817
+ }),
818
+ });
819
+ }
820
+ /** Create a memory directory. */
821
+ async createDir(memoryId, path) {
822
+ return this.createFile(memoryId, path, { isDirectory: true });
823
+ }
824
+ /** Update a memory file. */
825
+ async updateFile(memoryId, path, request) {
826
+ return this.client.fetch(`/memories/${memoryId}/fs/${path.replace(/^\//, "")}`, {
827
+ method: "PUT",
828
+ body: JSON.stringify({
829
+ content: request.content,
830
+ encoding: request.encoding,
831
+ }),
832
+ });
833
+ }
834
+ /** Delete a memory file or directory. */
835
+ async deleteFile(memoryId, path) {
836
+ await this.client.fetch(`/memories/${memoryId}/fs/${path.replace(/^\//, "")}`, { method: "DELETE" });
837
+ }
838
+ /** Search memory files by regex. */
839
+ async grepFiles(memoryId, pattern, options) {
840
+ const body = { pattern };
841
+ if (options?.pathPattern)
842
+ body.path_pattern = options.pathPattern;
843
+ const response = await this.client.fetch(`/memories/${memoryId}/fs/_/grep`, { method: "POST", body: JSON.stringify(body) });
844
+ return response.data;
845
+ }
846
+ /** Stat a memory file or directory. */
847
+ async statFile(memoryId, path) {
848
+ return this.client.fetch(`/memories/${memoryId}/fs/_/stat`, {
507
849
  method: "POST",
508
850
  body: JSON.stringify({ path }),
509
851
  });
@@ -621,6 +963,9 @@ function toAgentBody(request) {
621
963
  if (request.capabilities?.length) {
622
964
  body.capabilities = request.capabilities;
623
965
  }
966
+ if (request.tools?.length) {
967
+ body.tools = request.tools;
968
+ }
624
969
  if (request.initialFiles?.length) {
625
970
  body.initial_files = request.initialFiles.map((file) => ({
626
971
  path: file.path,
@@ -631,6 +976,36 @@ function toAgentBody(request) {
631
976
  }
632
977
  return body;
633
978
  }
979
+ function toCreateAgentVersionBody(request) {
980
+ const body = {};
981
+ if (request.changeKind !== undefined) {
982
+ body.change_kind = request.changeKind;
983
+ }
984
+ if (request.summary !== undefined) {
985
+ body.summary = request.summary;
986
+ }
987
+ return body;
988
+ }
989
+ function toForkAgentVersionBody(request) {
990
+ const body = { name: request.name };
991
+ if (request.displayName !== undefined) {
992
+ body.display_name = request.displayName;
993
+ }
994
+ if (request.description !== undefined) {
995
+ body.description = request.description;
996
+ }
997
+ return body;
998
+ }
999
+ function toRollbackAgentVersionBody(request) {
1000
+ const body = {};
1001
+ if (request.saveVersion !== undefined) {
1002
+ body.save_version = request.saveVersion;
1003
+ }
1004
+ if (request.summary !== undefined) {
1005
+ body.summary = request.summary;
1006
+ }
1007
+ return body;
1008
+ }
634
1009
  /** Check if the body looks like an HTML response */
635
1010
  function isHtmlResponse(body) {
636
1011
  const trimmed = body.trimStart();