letta-client 0.1.216__py3-none-any.whl → 0.1.218__py3-none-any.whl

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.

Potentially problematic release.


This version of letta-client might be problematic. Click here for more details.

@@ -0,0 +1,1319 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+ from ..core.client_wrapper import SyncClientWrapper
5
+ from .files.client import FilesClient
6
+ from .passages.client import PassagesClient
7
+ from ..core.request_options import RequestOptions
8
+ from ..core.unchecked_base_model import construct_type
9
+ from ..errors.unprocessable_entity_error import UnprocessableEntityError
10
+ from ..types.http_validation_error import HttpValidationError
11
+ from json.decoder import JSONDecodeError
12
+ from ..core.api_error import ApiError
13
+ from ..types.folder import Folder
14
+ from ..core.jsonable_encoder import jsonable_encoder
15
+ from ..types.embedding_config import EmbeddingConfig
16
+ from ..core.serialization import convert_and_respect_annotation_metadata
17
+ from ..types.organization_sources_stats import OrganizationSourcesStats
18
+ from ..core.client_wrapper import AsyncClientWrapper
19
+ from .files.client import AsyncFilesClient
20
+ from .passages.client import AsyncPassagesClient
21
+
22
+ # this is used as the default value for optional parameters
23
+ OMIT = typing.cast(typing.Any, ...)
24
+
25
+
26
+ class FoldersClient:
27
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
28
+ self._client_wrapper = client_wrapper
29
+ self.files = FilesClient(client_wrapper=self._client_wrapper)
30
+ self.passages = PassagesClient(client_wrapper=self._client_wrapper)
31
+
32
+ def count(self, *, request_options: typing.Optional[RequestOptions] = None) -> int:
33
+ """
34
+ Count all data folders created by a user.
35
+
36
+ Parameters
37
+ ----------
38
+ request_options : typing.Optional[RequestOptions]
39
+ Request-specific configuration.
40
+
41
+ Returns
42
+ -------
43
+ int
44
+ Successful Response
45
+
46
+ Examples
47
+ --------
48
+ from letta_client import Letta
49
+
50
+ client = Letta(
51
+ project="YOUR_PROJECT",
52
+ token="YOUR_TOKEN",
53
+ )
54
+ client.folders.count()
55
+ """
56
+ _response = self._client_wrapper.httpx_client.request(
57
+ "v1/folders/count",
58
+ method="GET",
59
+ request_options=request_options,
60
+ )
61
+ try:
62
+ if 200 <= _response.status_code < 300:
63
+ return typing.cast(
64
+ int,
65
+ construct_type(
66
+ type_=int, # type: ignore
67
+ object_=_response.json(),
68
+ ),
69
+ )
70
+ if _response.status_code == 422:
71
+ raise UnprocessableEntityError(
72
+ typing.cast(
73
+ HttpValidationError,
74
+ construct_type(
75
+ type_=HttpValidationError, # type: ignore
76
+ object_=_response.json(),
77
+ ),
78
+ )
79
+ )
80
+ _response_json = _response.json()
81
+ except JSONDecodeError:
82
+ raise ApiError(status_code=_response.status_code, body=_response.text)
83
+ raise ApiError(status_code=_response.status_code, body=_response_json)
84
+
85
+ def retrieve(self, folder_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Folder:
86
+ """
87
+ Get a folder by ID
88
+
89
+ Parameters
90
+ ----------
91
+ folder_id : str
92
+
93
+ request_options : typing.Optional[RequestOptions]
94
+ Request-specific configuration.
95
+
96
+ Returns
97
+ -------
98
+ Folder
99
+ Successful Response
100
+
101
+ Examples
102
+ --------
103
+ from letta_client import Letta
104
+
105
+ client = Letta(
106
+ project="YOUR_PROJECT",
107
+ token="YOUR_TOKEN",
108
+ )
109
+ client.folders.retrieve(
110
+ folder_id="folder_id",
111
+ )
112
+ """
113
+ _response = self._client_wrapper.httpx_client.request(
114
+ f"v1/folders/{jsonable_encoder(folder_id)}",
115
+ method="GET",
116
+ request_options=request_options,
117
+ )
118
+ try:
119
+ if 200 <= _response.status_code < 300:
120
+ return typing.cast(
121
+ Folder,
122
+ construct_type(
123
+ type_=Folder, # type: ignore
124
+ object_=_response.json(),
125
+ ),
126
+ )
127
+ if _response.status_code == 422:
128
+ raise UnprocessableEntityError(
129
+ typing.cast(
130
+ HttpValidationError,
131
+ construct_type(
132
+ type_=HttpValidationError, # type: ignore
133
+ object_=_response.json(),
134
+ ),
135
+ )
136
+ )
137
+ _response_json = _response.json()
138
+ except JSONDecodeError:
139
+ raise ApiError(status_code=_response.status_code, body=_response.text)
140
+ raise ApiError(status_code=_response.status_code, body=_response_json)
141
+
142
+ def delete(
143
+ self, folder_id: str, *, request_options: typing.Optional[RequestOptions] = None
144
+ ) -> typing.Optional[typing.Any]:
145
+ """
146
+ Delete a data folder.
147
+
148
+ Parameters
149
+ ----------
150
+ folder_id : str
151
+
152
+ request_options : typing.Optional[RequestOptions]
153
+ Request-specific configuration.
154
+
155
+ Returns
156
+ -------
157
+ typing.Optional[typing.Any]
158
+ Successful Response
159
+
160
+ Examples
161
+ --------
162
+ from letta_client import Letta
163
+
164
+ client = Letta(
165
+ project="YOUR_PROJECT",
166
+ token="YOUR_TOKEN",
167
+ )
168
+ client.folders.delete(
169
+ folder_id="folder_id",
170
+ )
171
+ """
172
+ _response = self._client_wrapper.httpx_client.request(
173
+ f"v1/folders/{jsonable_encoder(folder_id)}",
174
+ method="DELETE",
175
+ request_options=request_options,
176
+ )
177
+ try:
178
+ if 200 <= _response.status_code < 300:
179
+ return typing.cast(
180
+ typing.Optional[typing.Any],
181
+ construct_type(
182
+ type_=typing.Optional[typing.Any], # type: ignore
183
+ object_=_response.json(),
184
+ ),
185
+ )
186
+ if _response.status_code == 422:
187
+ raise UnprocessableEntityError(
188
+ typing.cast(
189
+ HttpValidationError,
190
+ construct_type(
191
+ type_=HttpValidationError, # type: ignore
192
+ object_=_response.json(),
193
+ ),
194
+ )
195
+ )
196
+ _response_json = _response.json()
197
+ except JSONDecodeError:
198
+ raise ApiError(status_code=_response.status_code, body=_response.text)
199
+ raise ApiError(status_code=_response.status_code, body=_response_json)
200
+
201
+ def modify(
202
+ self,
203
+ folder_id: str,
204
+ *,
205
+ name: typing.Optional[str] = OMIT,
206
+ description: typing.Optional[str] = OMIT,
207
+ instructions: typing.Optional[str] = OMIT,
208
+ metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
209
+ embedding_config: typing.Optional[EmbeddingConfig] = OMIT,
210
+ request_options: typing.Optional[RequestOptions] = None,
211
+ ) -> Folder:
212
+ """
213
+ Update the name or documentation of an existing data folder.
214
+
215
+ Parameters
216
+ ----------
217
+ folder_id : str
218
+
219
+ name : typing.Optional[str]
220
+ The name of the folder.
221
+
222
+ description : typing.Optional[str]
223
+ The description of the folder.
224
+
225
+ instructions : typing.Optional[str]
226
+ Instructions for how to use the folder.
227
+
228
+ metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
229
+ Metadata associated with the folder.
230
+
231
+ embedding_config : typing.Optional[EmbeddingConfig]
232
+ The embedding configuration used by the folder.
233
+
234
+ request_options : typing.Optional[RequestOptions]
235
+ Request-specific configuration.
236
+
237
+ Returns
238
+ -------
239
+ Folder
240
+ Successful Response
241
+
242
+ Examples
243
+ --------
244
+ from letta_client import Letta
245
+
246
+ client = Letta(
247
+ project="YOUR_PROJECT",
248
+ token="YOUR_TOKEN",
249
+ )
250
+ client.folders.modify(
251
+ folder_id="folder_id",
252
+ )
253
+ """
254
+ _response = self._client_wrapper.httpx_client.request(
255
+ f"v1/folders/{jsonable_encoder(folder_id)}",
256
+ method="PATCH",
257
+ json={
258
+ "name": name,
259
+ "description": description,
260
+ "instructions": instructions,
261
+ "metadata": metadata,
262
+ "embedding_config": convert_and_respect_annotation_metadata(
263
+ object_=embedding_config, annotation=EmbeddingConfig, direction="write"
264
+ ),
265
+ },
266
+ headers={
267
+ "content-type": "application/json",
268
+ },
269
+ request_options=request_options,
270
+ omit=OMIT,
271
+ )
272
+ try:
273
+ if 200 <= _response.status_code < 300:
274
+ return typing.cast(
275
+ Folder,
276
+ construct_type(
277
+ type_=Folder, # type: ignore
278
+ object_=_response.json(),
279
+ ),
280
+ )
281
+ if _response.status_code == 422:
282
+ raise UnprocessableEntityError(
283
+ typing.cast(
284
+ HttpValidationError,
285
+ construct_type(
286
+ type_=HttpValidationError, # type: ignore
287
+ object_=_response.json(),
288
+ ),
289
+ )
290
+ )
291
+ _response_json = _response.json()
292
+ except JSONDecodeError:
293
+ raise ApiError(status_code=_response.status_code, body=_response.text)
294
+ raise ApiError(status_code=_response.status_code, body=_response_json)
295
+
296
+ def retrieve_by_name(self, folder_name: str, *, request_options: typing.Optional[RequestOptions] = None) -> str:
297
+ """
298
+ Get a folder by name
299
+
300
+ Parameters
301
+ ----------
302
+ folder_name : str
303
+
304
+ request_options : typing.Optional[RequestOptions]
305
+ Request-specific configuration.
306
+
307
+ Returns
308
+ -------
309
+ str
310
+ Successful Response
311
+
312
+ Examples
313
+ --------
314
+ from letta_client import Letta
315
+
316
+ client = Letta(
317
+ project="YOUR_PROJECT",
318
+ token="YOUR_TOKEN",
319
+ )
320
+ client.folders.retrieve_by_name(
321
+ folder_name="folder_name",
322
+ )
323
+ """
324
+ _response = self._client_wrapper.httpx_client.request(
325
+ f"v1/folders/name/{jsonable_encoder(folder_name)}",
326
+ method="GET",
327
+ request_options=request_options,
328
+ )
329
+ try:
330
+ if 200 <= _response.status_code < 300:
331
+ return typing.cast(
332
+ str,
333
+ construct_type(
334
+ type_=str, # type: ignore
335
+ object_=_response.json(),
336
+ ),
337
+ )
338
+ if _response.status_code == 422:
339
+ raise UnprocessableEntityError(
340
+ typing.cast(
341
+ HttpValidationError,
342
+ construct_type(
343
+ type_=HttpValidationError, # type: ignore
344
+ object_=_response.json(),
345
+ ),
346
+ )
347
+ )
348
+ _response_json = _response.json()
349
+ except JSONDecodeError:
350
+ raise ApiError(status_code=_response.status_code, body=_response.text)
351
+ raise ApiError(status_code=_response.status_code, body=_response_json)
352
+
353
+ def get_folders_metadata(
354
+ self,
355
+ *,
356
+ include_detailed_per_source_metadata: typing.Optional[bool] = None,
357
+ request_options: typing.Optional[RequestOptions] = None,
358
+ ) -> OrganizationSourcesStats:
359
+ """
360
+ Get aggregated metadata for all folders in an organization.
361
+
362
+ Returns structured metadata including:
363
+ - Total number of folders
364
+ - Total number of files across all folders
365
+ - Total size of all files
366
+ - Per-source breakdown with file details (file_name, file_size per file) if include_detailed_per_source_metadata is True
367
+
368
+ Parameters
369
+ ----------
370
+ include_detailed_per_source_metadata : typing.Optional[bool]
371
+
372
+ request_options : typing.Optional[RequestOptions]
373
+ Request-specific configuration.
374
+
375
+ Returns
376
+ -------
377
+ OrganizationSourcesStats
378
+ Successful Response
379
+
380
+ Examples
381
+ --------
382
+ from letta_client import Letta
383
+
384
+ client = Letta(
385
+ project="YOUR_PROJECT",
386
+ token="YOUR_TOKEN",
387
+ )
388
+ client.folders.get_folders_metadata()
389
+ """
390
+ _response = self._client_wrapper.httpx_client.request(
391
+ "v1/folders/metadata",
392
+ method="GET",
393
+ params={
394
+ "include_detailed_per_source_metadata": include_detailed_per_source_metadata,
395
+ },
396
+ request_options=request_options,
397
+ )
398
+ try:
399
+ if 200 <= _response.status_code < 300:
400
+ return typing.cast(
401
+ OrganizationSourcesStats,
402
+ construct_type(
403
+ type_=OrganizationSourcesStats, # type: ignore
404
+ object_=_response.json(),
405
+ ),
406
+ )
407
+ if _response.status_code == 422:
408
+ raise UnprocessableEntityError(
409
+ typing.cast(
410
+ HttpValidationError,
411
+ construct_type(
412
+ type_=HttpValidationError, # type: ignore
413
+ object_=_response.json(),
414
+ ),
415
+ )
416
+ )
417
+ _response_json = _response.json()
418
+ except JSONDecodeError:
419
+ raise ApiError(status_code=_response.status_code, body=_response.text)
420
+ raise ApiError(status_code=_response.status_code, body=_response_json)
421
+
422
+ def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> typing.List[Folder]:
423
+ """
424
+ List all data folders created by a user.
425
+
426
+ Parameters
427
+ ----------
428
+ request_options : typing.Optional[RequestOptions]
429
+ Request-specific configuration.
430
+
431
+ Returns
432
+ -------
433
+ typing.List[Folder]
434
+ Successful Response
435
+
436
+ Examples
437
+ --------
438
+ from letta_client import Letta
439
+
440
+ client = Letta(
441
+ project="YOUR_PROJECT",
442
+ token="YOUR_TOKEN",
443
+ )
444
+ client.folders.list()
445
+ """
446
+ _response = self._client_wrapper.httpx_client.request(
447
+ "v1/folders/",
448
+ method="GET",
449
+ request_options=request_options,
450
+ )
451
+ try:
452
+ if 200 <= _response.status_code < 300:
453
+ return typing.cast(
454
+ typing.List[Folder],
455
+ construct_type(
456
+ type_=typing.List[Folder], # type: ignore
457
+ object_=_response.json(),
458
+ ),
459
+ )
460
+ if _response.status_code == 422:
461
+ raise UnprocessableEntityError(
462
+ typing.cast(
463
+ HttpValidationError,
464
+ construct_type(
465
+ type_=HttpValidationError, # type: ignore
466
+ object_=_response.json(),
467
+ ),
468
+ )
469
+ )
470
+ _response_json = _response.json()
471
+ except JSONDecodeError:
472
+ raise ApiError(status_code=_response.status_code, body=_response.text)
473
+ raise ApiError(status_code=_response.status_code, body=_response_json)
474
+
475
+ def create(
476
+ self,
477
+ *,
478
+ name: str,
479
+ description: typing.Optional[str] = OMIT,
480
+ instructions: typing.Optional[str] = OMIT,
481
+ metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
482
+ embedding: typing.Optional[str] = OMIT,
483
+ embedding_chunk_size: typing.Optional[int] = OMIT,
484
+ embedding_config: typing.Optional[EmbeddingConfig] = OMIT,
485
+ request_options: typing.Optional[RequestOptions] = None,
486
+ ) -> Folder:
487
+ """
488
+ Create a new data folder.
489
+
490
+ Parameters
491
+ ----------
492
+ name : str
493
+ The name of the folder.
494
+
495
+ description : typing.Optional[str]
496
+ The description of the folder.
497
+
498
+ instructions : typing.Optional[str]
499
+ Instructions for how to use the folder.
500
+
501
+ metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
502
+ Metadata associated with the folder.
503
+
504
+ embedding : typing.Optional[str]
505
+ The handle for the embedding config used by the folder.
506
+
507
+ embedding_chunk_size : typing.Optional[int]
508
+ The chunk size of the embedding.
509
+
510
+ embedding_config : typing.Optional[EmbeddingConfig]
511
+ (Legacy) The embedding configuration used by the folder.
512
+
513
+ request_options : typing.Optional[RequestOptions]
514
+ Request-specific configuration.
515
+
516
+ Returns
517
+ -------
518
+ Folder
519
+ Successful Response
520
+
521
+ Examples
522
+ --------
523
+ from letta_client import Letta
524
+
525
+ client = Letta(
526
+ project="YOUR_PROJECT",
527
+ token="YOUR_TOKEN",
528
+ )
529
+ client.folders.create(
530
+ name="name",
531
+ )
532
+ """
533
+ _response = self._client_wrapper.httpx_client.request(
534
+ "v1/folders/",
535
+ method="POST",
536
+ json={
537
+ "name": name,
538
+ "description": description,
539
+ "instructions": instructions,
540
+ "metadata": metadata,
541
+ "embedding": embedding,
542
+ "embedding_chunk_size": embedding_chunk_size,
543
+ "embedding_config": convert_and_respect_annotation_metadata(
544
+ object_=embedding_config, annotation=EmbeddingConfig, direction="write"
545
+ ),
546
+ },
547
+ headers={
548
+ "content-type": "application/json",
549
+ },
550
+ request_options=request_options,
551
+ omit=OMIT,
552
+ )
553
+ try:
554
+ if 200 <= _response.status_code < 300:
555
+ return typing.cast(
556
+ Folder,
557
+ construct_type(
558
+ type_=Folder, # type: ignore
559
+ object_=_response.json(),
560
+ ),
561
+ )
562
+ if _response.status_code == 422:
563
+ raise UnprocessableEntityError(
564
+ typing.cast(
565
+ HttpValidationError,
566
+ construct_type(
567
+ type_=HttpValidationError, # type: ignore
568
+ object_=_response.json(),
569
+ ),
570
+ )
571
+ )
572
+ _response_json = _response.json()
573
+ except JSONDecodeError:
574
+ raise ApiError(status_code=_response.status_code, body=_response.text)
575
+ raise ApiError(status_code=_response.status_code, body=_response_json)
576
+
577
+ def get_agents_for_folder(
578
+ self, folder_id: str, *, request_options: typing.Optional[RequestOptions] = None
579
+ ) -> typing.List[str]:
580
+ """
581
+ Get all agent IDs that have the specified folder attached.
582
+
583
+ Parameters
584
+ ----------
585
+ folder_id : str
586
+
587
+ request_options : typing.Optional[RequestOptions]
588
+ Request-specific configuration.
589
+
590
+ Returns
591
+ -------
592
+ typing.List[str]
593
+ Successful Response
594
+
595
+ Examples
596
+ --------
597
+ from letta_client import Letta
598
+
599
+ client = Letta(
600
+ project="YOUR_PROJECT",
601
+ token="YOUR_TOKEN",
602
+ )
603
+ client.folders.get_agents_for_folder(
604
+ folder_id="folder_id",
605
+ )
606
+ """
607
+ _response = self._client_wrapper.httpx_client.request(
608
+ f"v1/folders/{jsonable_encoder(folder_id)}/agents",
609
+ method="GET",
610
+ request_options=request_options,
611
+ )
612
+ try:
613
+ if 200 <= _response.status_code < 300:
614
+ return typing.cast(
615
+ typing.List[str],
616
+ construct_type(
617
+ type_=typing.List[str], # type: ignore
618
+ object_=_response.json(),
619
+ ),
620
+ )
621
+ if _response.status_code == 422:
622
+ raise UnprocessableEntityError(
623
+ typing.cast(
624
+ HttpValidationError,
625
+ construct_type(
626
+ type_=HttpValidationError, # type: ignore
627
+ object_=_response.json(),
628
+ ),
629
+ )
630
+ )
631
+ _response_json = _response.json()
632
+ except JSONDecodeError:
633
+ raise ApiError(status_code=_response.status_code, body=_response.text)
634
+ raise ApiError(status_code=_response.status_code, body=_response_json)
635
+
636
+
637
+ class AsyncFoldersClient:
638
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
639
+ self._client_wrapper = client_wrapper
640
+ self.files = AsyncFilesClient(client_wrapper=self._client_wrapper)
641
+ self.passages = AsyncPassagesClient(client_wrapper=self._client_wrapper)
642
+
643
+ async def count(self, *, request_options: typing.Optional[RequestOptions] = None) -> int:
644
+ """
645
+ Count all data folders created by a user.
646
+
647
+ Parameters
648
+ ----------
649
+ request_options : typing.Optional[RequestOptions]
650
+ Request-specific configuration.
651
+
652
+ Returns
653
+ -------
654
+ int
655
+ Successful Response
656
+
657
+ Examples
658
+ --------
659
+ import asyncio
660
+
661
+ from letta_client import AsyncLetta
662
+
663
+ client = AsyncLetta(
664
+ project="YOUR_PROJECT",
665
+ token="YOUR_TOKEN",
666
+ )
667
+
668
+
669
+ async def main() -> None:
670
+ await client.folders.count()
671
+
672
+
673
+ asyncio.run(main())
674
+ """
675
+ _response = await self._client_wrapper.httpx_client.request(
676
+ "v1/folders/count",
677
+ method="GET",
678
+ request_options=request_options,
679
+ )
680
+ try:
681
+ if 200 <= _response.status_code < 300:
682
+ return typing.cast(
683
+ int,
684
+ construct_type(
685
+ type_=int, # type: ignore
686
+ object_=_response.json(),
687
+ ),
688
+ )
689
+ if _response.status_code == 422:
690
+ raise UnprocessableEntityError(
691
+ typing.cast(
692
+ HttpValidationError,
693
+ construct_type(
694
+ type_=HttpValidationError, # type: ignore
695
+ object_=_response.json(),
696
+ ),
697
+ )
698
+ )
699
+ _response_json = _response.json()
700
+ except JSONDecodeError:
701
+ raise ApiError(status_code=_response.status_code, body=_response.text)
702
+ raise ApiError(status_code=_response.status_code, body=_response_json)
703
+
704
+ async def retrieve(self, folder_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Folder:
705
+ """
706
+ Get a folder by ID
707
+
708
+ Parameters
709
+ ----------
710
+ folder_id : str
711
+
712
+ request_options : typing.Optional[RequestOptions]
713
+ Request-specific configuration.
714
+
715
+ Returns
716
+ -------
717
+ Folder
718
+ Successful Response
719
+
720
+ Examples
721
+ --------
722
+ import asyncio
723
+
724
+ from letta_client import AsyncLetta
725
+
726
+ client = AsyncLetta(
727
+ project="YOUR_PROJECT",
728
+ token="YOUR_TOKEN",
729
+ )
730
+
731
+
732
+ async def main() -> None:
733
+ await client.folders.retrieve(
734
+ folder_id="folder_id",
735
+ )
736
+
737
+
738
+ asyncio.run(main())
739
+ """
740
+ _response = await self._client_wrapper.httpx_client.request(
741
+ f"v1/folders/{jsonable_encoder(folder_id)}",
742
+ method="GET",
743
+ request_options=request_options,
744
+ )
745
+ try:
746
+ if 200 <= _response.status_code < 300:
747
+ return typing.cast(
748
+ Folder,
749
+ construct_type(
750
+ type_=Folder, # type: ignore
751
+ object_=_response.json(),
752
+ ),
753
+ )
754
+ if _response.status_code == 422:
755
+ raise UnprocessableEntityError(
756
+ typing.cast(
757
+ HttpValidationError,
758
+ construct_type(
759
+ type_=HttpValidationError, # type: ignore
760
+ object_=_response.json(),
761
+ ),
762
+ )
763
+ )
764
+ _response_json = _response.json()
765
+ except JSONDecodeError:
766
+ raise ApiError(status_code=_response.status_code, body=_response.text)
767
+ raise ApiError(status_code=_response.status_code, body=_response_json)
768
+
769
+ async def delete(
770
+ self, folder_id: str, *, request_options: typing.Optional[RequestOptions] = None
771
+ ) -> typing.Optional[typing.Any]:
772
+ """
773
+ Delete a data folder.
774
+
775
+ Parameters
776
+ ----------
777
+ folder_id : str
778
+
779
+ request_options : typing.Optional[RequestOptions]
780
+ Request-specific configuration.
781
+
782
+ Returns
783
+ -------
784
+ typing.Optional[typing.Any]
785
+ Successful Response
786
+
787
+ Examples
788
+ --------
789
+ import asyncio
790
+
791
+ from letta_client import AsyncLetta
792
+
793
+ client = AsyncLetta(
794
+ project="YOUR_PROJECT",
795
+ token="YOUR_TOKEN",
796
+ )
797
+
798
+
799
+ async def main() -> None:
800
+ await client.folders.delete(
801
+ folder_id="folder_id",
802
+ )
803
+
804
+
805
+ asyncio.run(main())
806
+ """
807
+ _response = await self._client_wrapper.httpx_client.request(
808
+ f"v1/folders/{jsonable_encoder(folder_id)}",
809
+ method="DELETE",
810
+ request_options=request_options,
811
+ )
812
+ try:
813
+ if 200 <= _response.status_code < 300:
814
+ return typing.cast(
815
+ typing.Optional[typing.Any],
816
+ construct_type(
817
+ type_=typing.Optional[typing.Any], # type: ignore
818
+ object_=_response.json(),
819
+ ),
820
+ )
821
+ if _response.status_code == 422:
822
+ raise UnprocessableEntityError(
823
+ typing.cast(
824
+ HttpValidationError,
825
+ construct_type(
826
+ type_=HttpValidationError, # type: ignore
827
+ object_=_response.json(),
828
+ ),
829
+ )
830
+ )
831
+ _response_json = _response.json()
832
+ except JSONDecodeError:
833
+ raise ApiError(status_code=_response.status_code, body=_response.text)
834
+ raise ApiError(status_code=_response.status_code, body=_response_json)
835
+
836
+ async def modify(
837
+ self,
838
+ folder_id: str,
839
+ *,
840
+ name: typing.Optional[str] = OMIT,
841
+ description: typing.Optional[str] = OMIT,
842
+ instructions: typing.Optional[str] = OMIT,
843
+ metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
844
+ embedding_config: typing.Optional[EmbeddingConfig] = OMIT,
845
+ request_options: typing.Optional[RequestOptions] = None,
846
+ ) -> Folder:
847
+ """
848
+ Update the name or documentation of an existing data folder.
849
+
850
+ Parameters
851
+ ----------
852
+ folder_id : str
853
+
854
+ name : typing.Optional[str]
855
+ The name of the folder.
856
+
857
+ description : typing.Optional[str]
858
+ The description of the folder.
859
+
860
+ instructions : typing.Optional[str]
861
+ Instructions for how to use the folder.
862
+
863
+ metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
864
+ Metadata associated with the folder.
865
+
866
+ embedding_config : typing.Optional[EmbeddingConfig]
867
+ The embedding configuration used by the folder.
868
+
869
+ request_options : typing.Optional[RequestOptions]
870
+ Request-specific configuration.
871
+
872
+ Returns
873
+ -------
874
+ Folder
875
+ Successful Response
876
+
877
+ Examples
878
+ --------
879
+ import asyncio
880
+
881
+ from letta_client import AsyncLetta
882
+
883
+ client = AsyncLetta(
884
+ project="YOUR_PROJECT",
885
+ token="YOUR_TOKEN",
886
+ )
887
+
888
+
889
+ async def main() -> None:
890
+ await client.folders.modify(
891
+ folder_id="folder_id",
892
+ )
893
+
894
+
895
+ asyncio.run(main())
896
+ """
897
+ _response = await self._client_wrapper.httpx_client.request(
898
+ f"v1/folders/{jsonable_encoder(folder_id)}",
899
+ method="PATCH",
900
+ json={
901
+ "name": name,
902
+ "description": description,
903
+ "instructions": instructions,
904
+ "metadata": metadata,
905
+ "embedding_config": convert_and_respect_annotation_metadata(
906
+ object_=embedding_config, annotation=EmbeddingConfig, direction="write"
907
+ ),
908
+ },
909
+ headers={
910
+ "content-type": "application/json",
911
+ },
912
+ request_options=request_options,
913
+ omit=OMIT,
914
+ )
915
+ try:
916
+ if 200 <= _response.status_code < 300:
917
+ return typing.cast(
918
+ Folder,
919
+ construct_type(
920
+ type_=Folder, # type: ignore
921
+ object_=_response.json(),
922
+ ),
923
+ )
924
+ if _response.status_code == 422:
925
+ raise UnprocessableEntityError(
926
+ typing.cast(
927
+ HttpValidationError,
928
+ construct_type(
929
+ type_=HttpValidationError, # type: ignore
930
+ object_=_response.json(),
931
+ ),
932
+ )
933
+ )
934
+ _response_json = _response.json()
935
+ except JSONDecodeError:
936
+ raise ApiError(status_code=_response.status_code, body=_response.text)
937
+ raise ApiError(status_code=_response.status_code, body=_response_json)
938
+
939
+ async def retrieve_by_name(
940
+ self, folder_name: str, *, request_options: typing.Optional[RequestOptions] = None
941
+ ) -> str:
942
+ """
943
+ Get a folder by name
944
+
945
+ Parameters
946
+ ----------
947
+ folder_name : str
948
+
949
+ request_options : typing.Optional[RequestOptions]
950
+ Request-specific configuration.
951
+
952
+ Returns
953
+ -------
954
+ str
955
+ Successful Response
956
+
957
+ Examples
958
+ --------
959
+ import asyncio
960
+
961
+ from letta_client import AsyncLetta
962
+
963
+ client = AsyncLetta(
964
+ project="YOUR_PROJECT",
965
+ token="YOUR_TOKEN",
966
+ )
967
+
968
+
969
+ async def main() -> None:
970
+ await client.folders.retrieve_by_name(
971
+ folder_name="folder_name",
972
+ )
973
+
974
+
975
+ asyncio.run(main())
976
+ """
977
+ _response = await self._client_wrapper.httpx_client.request(
978
+ f"v1/folders/name/{jsonable_encoder(folder_name)}",
979
+ method="GET",
980
+ request_options=request_options,
981
+ )
982
+ try:
983
+ if 200 <= _response.status_code < 300:
984
+ return typing.cast(
985
+ str,
986
+ construct_type(
987
+ type_=str, # type: ignore
988
+ object_=_response.json(),
989
+ ),
990
+ )
991
+ if _response.status_code == 422:
992
+ raise UnprocessableEntityError(
993
+ typing.cast(
994
+ HttpValidationError,
995
+ construct_type(
996
+ type_=HttpValidationError, # type: ignore
997
+ object_=_response.json(),
998
+ ),
999
+ )
1000
+ )
1001
+ _response_json = _response.json()
1002
+ except JSONDecodeError:
1003
+ raise ApiError(status_code=_response.status_code, body=_response.text)
1004
+ raise ApiError(status_code=_response.status_code, body=_response_json)
1005
+
1006
+ async def get_folders_metadata(
1007
+ self,
1008
+ *,
1009
+ include_detailed_per_source_metadata: typing.Optional[bool] = None,
1010
+ request_options: typing.Optional[RequestOptions] = None,
1011
+ ) -> OrganizationSourcesStats:
1012
+ """
1013
+ Get aggregated metadata for all folders in an organization.
1014
+
1015
+ Returns structured metadata including:
1016
+ - Total number of folders
1017
+ - Total number of files across all folders
1018
+ - Total size of all files
1019
+ - Per-source breakdown with file details (file_name, file_size per file) if include_detailed_per_source_metadata is True
1020
+
1021
+ Parameters
1022
+ ----------
1023
+ include_detailed_per_source_metadata : typing.Optional[bool]
1024
+
1025
+ request_options : typing.Optional[RequestOptions]
1026
+ Request-specific configuration.
1027
+
1028
+ Returns
1029
+ -------
1030
+ OrganizationSourcesStats
1031
+ Successful Response
1032
+
1033
+ Examples
1034
+ --------
1035
+ import asyncio
1036
+
1037
+ from letta_client import AsyncLetta
1038
+
1039
+ client = AsyncLetta(
1040
+ project="YOUR_PROJECT",
1041
+ token="YOUR_TOKEN",
1042
+ )
1043
+
1044
+
1045
+ async def main() -> None:
1046
+ await client.folders.get_folders_metadata()
1047
+
1048
+
1049
+ asyncio.run(main())
1050
+ """
1051
+ _response = await self._client_wrapper.httpx_client.request(
1052
+ "v1/folders/metadata",
1053
+ method="GET",
1054
+ params={
1055
+ "include_detailed_per_source_metadata": include_detailed_per_source_metadata,
1056
+ },
1057
+ request_options=request_options,
1058
+ )
1059
+ try:
1060
+ if 200 <= _response.status_code < 300:
1061
+ return typing.cast(
1062
+ OrganizationSourcesStats,
1063
+ construct_type(
1064
+ type_=OrganizationSourcesStats, # type: ignore
1065
+ object_=_response.json(),
1066
+ ),
1067
+ )
1068
+ if _response.status_code == 422:
1069
+ raise UnprocessableEntityError(
1070
+ typing.cast(
1071
+ HttpValidationError,
1072
+ construct_type(
1073
+ type_=HttpValidationError, # type: ignore
1074
+ object_=_response.json(),
1075
+ ),
1076
+ )
1077
+ )
1078
+ _response_json = _response.json()
1079
+ except JSONDecodeError:
1080
+ raise ApiError(status_code=_response.status_code, body=_response.text)
1081
+ raise ApiError(status_code=_response.status_code, body=_response_json)
1082
+
1083
+ async def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> typing.List[Folder]:
1084
+ """
1085
+ List all data folders created by a user.
1086
+
1087
+ Parameters
1088
+ ----------
1089
+ request_options : typing.Optional[RequestOptions]
1090
+ Request-specific configuration.
1091
+
1092
+ Returns
1093
+ -------
1094
+ typing.List[Folder]
1095
+ Successful Response
1096
+
1097
+ Examples
1098
+ --------
1099
+ import asyncio
1100
+
1101
+ from letta_client import AsyncLetta
1102
+
1103
+ client = AsyncLetta(
1104
+ project="YOUR_PROJECT",
1105
+ token="YOUR_TOKEN",
1106
+ )
1107
+
1108
+
1109
+ async def main() -> None:
1110
+ await client.folders.list()
1111
+
1112
+
1113
+ asyncio.run(main())
1114
+ """
1115
+ _response = await self._client_wrapper.httpx_client.request(
1116
+ "v1/folders/",
1117
+ method="GET",
1118
+ request_options=request_options,
1119
+ )
1120
+ try:
1121
+ if 200 <= _response.status_code < 300:
1122
+ return typing.cast(
1123
+ typing.List[Folder],
1124
+ construct_type(
1125
+ type_=typing.List[Folder], # type: ignore
1126
+ object_=_response.json(),
1127
+ ),
1128
+ )
1129
+ if _response.status_code == 422:
1130
+ raise UnprocessableEntityError(
1131
+ typing.cast(
1132
+ HttpValidationError,
1133
+ construct_type(
1134
+ type_=HttpValidationError, # type: ignore
1135
+ object_=_response.json(),
1136
+ ),
1137
+ )
1138
+ )
1139
+ _response_json = _response.json()
1140
+ except JSONDecodeError:
1141
+ raise ApiError(status_code=_response.status_code, body=_response.text)
1142
+ raise ApiError(status_code=_response.status_code, body=_response_json)
1143
+
1144
+ async def create(
1145
+ self,
1146
+ *,
1147
+ name: str,
1148
+ description: typing.Optional[str] = OMIT,
1149
+ instructions: typing.Optional[str] = OMIT,
1150
+ metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
1151
+ embedding: typing.Optional[str] = OMIT,
1152
+ embedding_chunk_size: typing.Optional[int] = OMIT,
1153
+ embedding_config: typing.Optional[EmbeddingConfig] = OMIT,
1154
+ request_options: typing.Optional[RequestOptions] = None,
1155
+ ) -> Folder:
1156
+ """
1157
+ Create a new data folder.
1158
+
1159
+ Parameters
1160
+ ----------
1161
+ name : str
1162
+ The name of the folder.
1163
+
1164
+ description : typing.Optional[str]
1165
+ The description of the folder.
1166
+
1167
+ instructions : typing.Optional[str]
1168
+ Instructions for how to use the folder.
1169
+
1170
+ metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
1171
+ Metadata associated with the folder.
1172
+
1173
+ embedding : typing.Optional[str]
1174
+ The handle for the embedding config used by the folder.
1175
+
1176
+ embedding_chunk_size : typing.Optional[int]
1177
+ The chunk size of the embedding.
1178
+
1179
+ embedding_config : typing.Optional[EmbeddingConfig]
1180
+ (Legacy) The embedding configuration used by the folder.
1181
+
1182
+ request_options : typing.Optional[RequestOptions]
1183
+ Request-specific configuration.
1184
+
1185
+ Returns
1186
+ -------
1187
+ Folder
1188
+ Successful Response
1189
+
1190
+ Examples
1191
+ --------
1192
+ import asyncio
1193
+
1194
+ from letta_client import AsyncLetta
1195
+
1196
+ client = AsyncLetta(
1197
+ project="YOUR_PROJECT",
1198
+ token="YOUR_TOKEN",
1199
+ )
1200
+
1201
+
1202
+ async def main() -> None:
1203
+ await client.folders.create(
1204
+ name="name",
1205
+ )
1206
+
1207
+
1208
+ asyncio.run(main())
1209
+ """
1210
+ _response = await self._client_wrapper.httpx_client.request(
1211
+ "v1/folders/",
1212
+ method="POST",
1213
+ json={
1214
+ "name": name,
1215
+ "description": description,
1216
+ "instructions": instructions,
1217
+ "metadata": metadata,
1218
+ "embedding": embedding,
1219
+ "embedding_chunk_size": embedding_chunk_size,
1220
+ "embedding_config": convert_and_respect_annotation_metadata(
1221
+ object_=embedding_config, annotation=EmbeddingConfig, direction="write"
1222
+ ),
1223
+ },
1224
+ headers={
1225
+ "content-type": "application/json",
1226
+ },
1227
+ request_options=request_options,
1228
+ omit=OMIT,
1229
+ )
1230
+ try:
1231
+ if 200 <= _response.status_code < 300:
1232
+ return typing.cast(
1233
+ Folder,
1234
+ construct_type(
1235
+ type_=Folder, # type: ignore
1236
+ object_=_response.json(),
1237
+ ),
1238
+ )
1239
+ if _response.status_code == 422:
1240
+ raise UnprocessableEntityError(
1241
+ typing.cast(
1242
+ HttpValidationError,
1243
+ construct_type(
1244
+ type_=HttpValidationError, # type: ignore
1245
+ object_=_response.json(),
1246
+ ),
1247
+ )
1248
+ )
1249
+ _response_json = _response.json()
1250
+ except JSONDecodeError:
1251
+ raise ApiError(status_code=_response.status_code, body=_response.text)
1252
+ raise ApiError(status_code=_response.status_code, body=_response_json)
1253
+
1254
+ async def get_agents_for_folder(
1255
+ self, folder_id: str, *, request_options: typing.Optional[RequestOptions] = None
1256
+ ) -> typing.List[str]:
1257
+ """
1258
+ Get all agent IDs that have the specified folder attached.
1259
+
1260
+ Parameters
1261
+ ----------
1262
+ folder_id : str
1263
+
1264
+ request_options : typing.Optional[RequestOptions]
1265
+ Request-specific configuration.
1266
+
1267
+ Returns
1268
+ -------
1269
+ typing.List[str]
1270
+ Successful Response
1271
+
1272
+ Examples
1273
+ --------
1274
+ import asyncio
1275
+
1276
+ from letta_client import AsyncLetta
1277
+
1278
+ client = AsyncLetta(
1279
+ project="YOUR_PROJECT",
1280
+ token="YOUR_TOKEN",
1281
+ )
1282
+
1283
+
1284
+ async def main() -> None:
1285
+ await client.folders.get_agents_for_folder(
1286
+ folder_id="folder_id",
1287
+ )
1288
+
1289
+
1290
+ asyncio.run(main())
1291
+ """
1292
+ _response = await self._client_wrapper.httpx_client.request(
1293
+ f"v1/folders/{jsonable_encoder(folder_id)}/agents",
1294
+ method="GET",
1295
+ request_options=request_options,
1296
+ )
1297
+ try:
1298
+ if 200 <= _response.status_code < 300:
1299
+ return typing.cast(
1300
+ typing.List[str],
1301
+ construct_type(
1302
+ type_=typing.List[str], # type: ignore
1303
+ object_=_response.json(),
1304
+ ),
1305
+ )
1306
+ if _response.status_code == 422:
1307
+ raise UnprocessableEntityError(
1308
+ typing.cast(
1309
+ HttpValidationError,
1310
+ construct_type(
1311
+ type_=HttpValidationError, # type: ignore
1312
+ object_=_response.json(),
1313
+ ),
1314
+ )
1315
+ )
1316
+ _response_json = _response.json()
1317
+ except JSONDecodeError:
1318
+ raise ApiError(status_code=_response.status_code, body=_response.text)
1319
+ raise ApiError(status_code=_response.status_code, body=_response_json)