letta-client 0.1.216__py3-none-any.whl → 0.1.217__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,1933 @@
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 ..core.request_options import RequestOptions
6
+ from ..core.unchecked_base_model import construct_type
7
+ from ..errors.unprocessable_entity_error import UnprocessableEntityError
8
+ from ..types.http_validation_error import HttpValidationError
9
+ from json.decoder import JSONDecodeError
10
+ from ..core.api_error import ApiError
11
+ from ..types.folder import Folder
12
+ from ..core.jsonable_encoder import jsonable_encoder
13
+ from ..types.embedding_config import EmbeddingConfig
14
+ from ..core.serialization import convert_and_respect_annotation_metadata
15
+ from ..types.organization_sources_stats import OrganizationSourcesStats
16
+ from .. import core
17
+ from ..types.duplicate_file_handling import DuplicateFileHandling
18
+ from ..types.file_metadata import FileMetadata
19
+ from ..types.passage import Passage
20
+ from ..core.client_wrapper import AsyncClientWrapper
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
+
30
+ def count_folders(self, *, request_options: typing.Optional[RequestOptions] = None) -> int:
31
+ """
32
+ Count all data folders created by a user.
33
+
34
+ Parameters
35
+ ----------
36
+ request_options : typing.Optional[RequestOptions]
37
+ Request-specific configuration.
38
+
39
+ Returns
40
+ -------
41
+ int
42
+ Successful Response
43
+
44
+ Examples
45
+ --------
46
+ from letta_client import Letta
47
+
48
+ client = Letta(
49
+ project="YOUR_PROJECT",
50
+ token="YOUR_TOKEN",
51
+ )
52
+ client.folders.count_folders()
53
+ """
54
+ _response = self._client_wrapper.httpx_client.request(
55
+ "v1/folders/count",
56
+ method="GET",
57
+ request_options=request_options,
58
+ )
59
+ try:
60
+ if 200 <= _response.status_code < 300:
61
+ return typing.cast(
62
+ int,
63
+ construct_type(
64
+ type_=int, # type: ignore
65
+ object_=_response.json(),
66
+ ),
67
+ )
68
+ if _response.status_code == 422:
69
+ raise UnprocessableEntityError(
70
+ typing.cast(
71
+ HttpValidationError,
72
+ construct_type(
73
+ type_=HttpValidationError, # type: ignore
74
+ object_=_response.json(),
75
+ ),
76
+ )
77
+ )
78
+ _response_json = _response.json()
79
+ except JSONDecodeError:
80
+ raise ApiError(status_code=_response.status_code, body=_response.text)
81
+ raise ApiError(status_code=_response.status_code, body=_response_json)
82
+
83
+ def retrieve_folder(self, folder_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Folder:
84
+ """
85
+ Get a folder by ID
86
+
87
+ Parameters
88
+ ----------
89
+ folder_id : str
90
+
91
+ request_options : typing.Optional[RequestOptions]
92
+ Request-specific configuration.
93
+
94
+ Returns
95
+ -------
96
+ Folder
97
+ Successful Response
98
+
99
+ Examples
100
+ --------
101
+ from letta_client import Letta
102
+
103
+ client = Letta(
104
+ project="YOUR_PROJECT",
105
+ token="YOUR_TOKEN",
106
+ )
107
+ client.folders.retrieve_folder(
108
+ folder_id="folder_id",
109
+ )
110
+ """
111
+ _response = self._client_wrapper.httpx_client.request(
112
+ f"v1/folders/{jsonable_encoder(folder_id)}",
113
+ method="GET",
114
+ request_options=request_options,
115
+ )
116
+ try:
117
+ if 200 <= _response.status_code < 300:
118
+ return typing.cast(
119
+ Folder,
120
+ construct_type(
121
+ type_=Folder, # type: ignore
122
+ object_=_response.json(),
123
+ ),
124
+ )
125
+ if _response.status_code == 422:
126
+ raise UnprocessableEntityError(
127
+ typing.cast(
128
+ HttpValidationError,
129
+ construct_type(
130
+ type_=HttpValidationError, # type: ignore
131
+ object_=_response.json(),
132
+ ),
133
+ )
134
+ )
135
+ _response_json = _response.json()
136
+ except JSONDecodeError:
137
+ raise ApiError(status_code=_response.status_code, body=_response.text)
138
+ raise ApiError(status_code=_response.status_code, body=_response_json)
139
+
140
+ def delete_folder(
141
+ self, folder_id: str, *, request_options: typing.Optional[RequestOptions] = None
142
+ ) -> typing.Optional[typing.Any]:
143
+ """
144
+ Delete a data folder.
145
+
146
+ Parameters
147
+ ----------
148
+ folder_id : str
149
+
150
+ request_options : typing.Optional[RequestOptions]
151
+ Request-specific configuration.
152
+
153
+ Returns
154
+ -------
155
+ typing.Optional[typing.Any]
156
+ Successful Response
157
+
158
+ Examples
159
+ --------
160
+ from letta_client import Letta
161
+
162
+ client = Letta(
163
+ project="YOUR_PROJECT",
164
+ token="YOUR_TOKEN",
165
+ )
166
+ client.folders.delete_folder(
167
+ folder_id="folder_id",
168
+ )
169
+ """
170
+ _response = self._client_wrapper.httpx_client.request(
171
+ f"v1/folders/{jsonable_encoder(folder_id)}",
172
+ method="DELETE",
173
+ request_options=request_options,
174
+ )
175
+ try:
176
+ if 200 <= _response.status_code < 300:
177
+ return typing.cast(
178
+ typing.Optional[typing.Any],
179
+ construct_type(
180
+ type_=typing.Optional[typing.Any], # type: ignore
181
+ object_=_response.json(),
182
+ ),
183
+ )
184
+ if _response.status_code == 422:
185
+ raise UnprocessableEntityError(
186
+ typing.cast(
187
+ HttpValidationError,
188
+ construct_type(
189
+ type_=HttpValidationError, # type: ignore
190
+ object_=_response.json(),
191
+ ),
192
+ )
193
+ )
194
+ _response_json = _response.json()
195
+ except JSONDecodeError:
196
+ raise ApiError(status_code=_response.status_code, body=_response.text)
197
+ raise ApiError(status_code=_response.status_code, body=_response_json)
198
+
199
+ def modify_folder(
200
+ self,
201
+ folder_id: str,
202
+ *,
203
+ name: typing.Optional[str] = OMIT,
204
+ description: typing.Optional[str] = OMIT,
205
+ instructions: typing.Optional[str] = OMIT,
206
+ metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
207
+ embedding_config: typing.Optional[EmbeddingConfig] = OMIT,
208
+ request_options: typing.Optional[RequestOptions] = None,
209
+ ) -> Folder:
210
+ """
211
+ Update the name or documentation of an existing data folder.
212
+
213
+ Parameters
214
+ ----------
215
+ folder_id : str
216
+
217
+ name : typing.Optional[str]
218
+ The name of the folder.
219
+
220
+ description : typing.Optional[str]
221
+ The description of the folder.
222
+
223
+ instructions : typing.Optional[str]
224
+ Instructions for how to use the folder.
225
+
226
+ metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
227
+ Metadata associated with the folder.
228
+
229
+ embedding_config : typing.Optional[EmbeddingConfig]
230
+ The embedding configuration used by the folder.
231
+
232
+ request_options : typing.Optional[RequestOptions]
233
+ Request-specific configuration.
234
+
235
+ Returns
236
+ -------
237
+ Folder
238
+ Successful Response
239
+
240
+ Examples
241
+ --------
242
+ from letta_client import Letta
243
+
244
+ client = Letta(
245
+ project="YOUR_PROJECT",
246
+ token="YOUR_TOKEN",
247
+ )
248
+ client.folders.modify_folder(
249
+ folder_id="folder_id",
250
+ )
251
+ """
252
+ _response = self._client_wrapper.httpx_client.request(
253
+ f"v1/folders/{jsonable_encoder(folder_id)}",
254
+ method="PATCH",
255
+ json={
256
+ "name": name,
257
+ "description": description,
258
+ "instructions": instructions,
259
+ "metadata": metadata,
260
+ "embedding_config": convert_and_respect_annotation_metadata(
261
+ object_=embedding_config, annotation=EmbeddingConfig, direction="write"
262
+ ),
263
+ },
264
+ headers={
265
+ "content-type": "application/json",
266
+ },
267
+ request_options=request_options,
268
+ omit=OMIT,
269
+ )
270
+ try:
271
+ if 200 <= _response.status_code < 300:
272
+ return typing.cast(
273
+ Folder,
274
+ construct_type(
275
+ type_=Folder, # type: ignore
276
+ object_=_response.json(),
277
+ ),
278
+ )
279
+ if _response.status_code == 422:
280
+ raise UnprocessableEntityError(
281
+ typing.cast(
282
+ HttpValidationError,
283
+ construct_type(
284
+ type_=HttpValidationError, # type: ignore
285
+ object_=_response.json(),
286
+ ),
287
+ )
288
+ )
289
+ _response_json = _response.json()
290
+ except JSONDecodeError:
291
+ raise ApiError(status_code=_response.status_code, body=_response.text)
292
+ raise ApiError(status_code=_response.status_code, body=_response_json)
293
+
294
+ def get_folder_id_by_name(
295
+ self, folder_name: str, *, request_options: typing.Optional[RequestOptions] = None
296
+ ) -> 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.get_folder_id_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_folders(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_folders()
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_folder(
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_folder(
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 upload_file_to_folder(
578
+ self,
579
+ folder_id: str,
580
+ *,
581
+ file: core.File,
582
+ duplicate_handling: typing.Optional[DuplicateFileHandling] = None,
583
+ request_options: typing.Optional[RequestOptions] = None,
584
+ ) -> FileMetadata:
585
+ """
586
+ Upload a file to a data folder.
587
+
588
+ Parameters
589
+ ----------
590
+ folder_id : str
591
+
592
+ file : core.File
593
+ See core.File for more documentation
594
+
595
+ duplicate_handling : typing.Optional[DuplicateFileHandling]
596
+ How to handle duplicate filenames
597
+
598
+ request_options : typing.Optional[RequestOptions]
599
+ Request-specific configuration.
600
+
601
+ Returns
602
+ -------
603
+ FileMetadata
604
+ Successful Response
605
+
606
+ Examples
607
+ --------
608
+ from letta_client import Letta
609
+
610
+ client = Letta(
611
+ project="YOUR_PROJECT",
612
+ token="YOUR_TOKEN",
613
+ )
614
+ client.folders.upload_file_to_folder(
615
+ folder_id="folder_id",
616
+ )
617
+ """
618
+ _response = self._client_wrapper.httpx_client.request(
619
+ f"v1/folders/{jsonable_encoder(folder_id)}/upload",
620
+ method="POST",
621
+ params={
622
+ "duplicate_handling": duplicate_handling,
623
+ },
624
+ data={},
625
+ files={
626
+ "file": file,
627
+ },
628
+ request_options=request_options,
629
+ omit=OMIT,
630
+ )
631
+ try:
632
+ if 200 <= _response.status_code < 300:
633
+ return typing.cast(
634
+ FileMetadata,
635
+ construct_type(
636
+ type_=FileMetadata, # type: ignore
637
+ object_=_response.json(),
638
+ ),
639
+ )
640
+ if _response.status_code == 422:
641
+ raise UnprocessableEntityError(
642
+ typing.cast(
643
+ HttpValidationError,
644
+ construct_type(
645
+ type_=HttpValidationError, # type: ignore
646
+ object_=_response.json(),
647
+ ),
648
+ )
649
+ )
650
+ _response_json = _response.json()
651
+ except JSONDecodeError:
652
+ raise ApiError(status_code=_response.status_code, body=_response.text)
653
+ raise ApiError(status_code=_response.status_code, body=_response_json)
654
+
655
+ def get_agents_for_folder(
656
+ self, folder_id: str, *, request_options: typing.Optional[RequestOptions] = None
657
+ ) -> typing.List[str]:
658
+ """
659
+ Get all agent IDs that have the specified folder attached.
660
+
661
+ Parameters
662
+ ----------
663
+ folder_id : str
664
+
665
+ request_options : typing.Optional[RequestOptions]
666
+ Request-specific configuration.
667
+
668
+ Returns
669
+ -------
670
+ typing.List[str]
671
+ Successful Response
672
+
673
+ Examples
674
+ --------
675
+ from letta_client import Letta
676
+
677
+ client = Letta(
678
+ project="YOUR_PROJECT",
679
+ token="YOUR_TOKEN",
680
+ )
681
+ client.folders.get_agents_for_folder(
682
+ folder_id="folder_id",
683
+ )
684
+ """
685
+ _response = self._client_wrapper.httpx_client.request(
686
+ f"v1/folders/{jsonable_encoder(folder_id)}/agents",
687
+ method="GET",
688
+ request_options=request_options,
689
+ )
690
+ try:
691
+ if 200 <= _response.status_code < 300:
692
+ return typing.cast(
693
+ typing.List[str],
694
+ construct_type(
695
+ type_=typing.List[str], # type: ignore
696
+ object_=_response.json(),
697
+ ),
698
+ )
699
+ if _response.status_code == 422:
700
+ raise UnprocessableEntityError(
701
+ typing.cast(
702
+ HttpValidationError,
703
+ construct_type(
704
+ type_=HttpValidationError, # type: ignore
705
+ object_=_response.json(),
706
+ ),
707
+ )
708
+ )
709
+ _response_json = _response.json()
710
+ except JSONDecodeError:
711
+ raise ApiError(status_code=_response.status_code, body=_response.text)
712
+ raise ApiError(status_code=_response.status_code, body=_response_json)
713
+
714
+ def list_folder_passages(
715
+ self,
716
+ folder_id: str,
717
+ *,
718
+ after: typing.Optional[str] = None,
719
+ before: typing.Optional[str] = None,
720
+ limit: typing.Optional[int] = None,
721
+ request_options: typing.Optional[RequestOptions] = None,
722
+ ) -> typing.List[Passage]:
723
+ """
724
+ List all passages associated with a data folder.
725
+
726
+ Parameters
727
+ ----------
728
+ folder_id : str
729
+
730
+ after : typing.Optional[str]
731
+ Message after which to retrieve the returned messages.
732
+
733
+ before : typing.Optional[str]
734
+ Message before which to retrieve the returned messages.
735
+
736
+ limit : typing.Optional[int]
737
+ Maximum number of messages to retrieve.
738
+
739
+ request_options : typing.Optional[RequestOptions]
740
+ Request-specific configuration.
741
+
742
+ Returns
743
+ -------
744
+ typing.List[Passage]
745
+ Successful Response
746
+
747
+ Examples
748
+ --------
749
+ from letta_client import Letta
750
+
751
+ client = Letta(
752
+ project="YOUR_PROJECT",
753
+ token="YOUR_TOKEN",
754
+ )
755
+ client.folders.list_folder_passages(
756
+ folder_id="folder_id",
757
+ )
758
+ """
759
+ _response = self._client_wrapper.httpx_client.request(
760
+ f"v1/folders/{jsonable_encoder(folder_id)}/passages",
761
+ method="GET",
762
+ params={
763
+ "after": after,
764
+ "before": before,
765
+ "limit": limit,
766
+ },
767
+ request_options=request_options,
768
+ )
769
+ try:
770
+ if 200 <= _response.status_code < 300:
771
+ return typing.cast(
772
+ typing.List[Passage],
773
+ construct_type(
774
+ type_=typing.List[Passage], # type: ignore
775
+ object_=_response.json(),
776
+ ),
777
+ )
778
+ if _response.status_code == 422:
779
+ raise UnprocessableEntityError(
780
+ typing.cast(
781
+ HttpValidationError,
782
+ construct_type(
783
+ type_=HttpValidationError, # type: ignore
784
+ object_=_response.json(),
785
+ ),
786
+ )
787
+ )
788
+ _response_json = _response.json()
789
+ except JSONDecodeError:
790
+ raise ApiError(status_code=_response.status_code, body=_response.text)
791
+ raise ApiError(status_code=_response.status_code, body=_response_json)
792
+
793
+ def list_folder_files(
794
+ self,
795
+ folder_id: str,
796
+ *,
797
+ limit: typing.Optional[int] = None,
798
+ after: typing.Optional[str] = None,
799
+ include_content: typing.Optional[bool] = None,
800
+ request_options: typing.Optional[RequestOptions] = None,
801
+ ) -> typing.List[FileMetadata]:
802
+ """
803
+ List paginated files associated with a data folder.
804
+
805
+ Parameters
806
+ ----------
807
+ folder_id : str
808
+
809
+ limit : typing.Optional[int]
810
+ Number of files to return
811
+
812
+ after : typing.Optional[str]
813
+ Pagination cursor to fetch the next set of results
814
+
815
+ include_content : typing.Optional[bool]
816
+ Whether to include full file content
817
+
818
+ request_options : typing.Optional[RequestOptions]
819
+ Request-specific configuration.
820
+
821
+ Returns
822
+ -------
823
+ typing.List[FileMetadata]
824
+ Successful Response
825
+
826
+ Examples
827
+ --------
828
+ from letta_client import Letta
829
+
830
+ client = Letta(
831
+ project="YOUR_PROJECT",
832
+ token="YOUR_TOKEN",
833
+ )
834
+ client.folders.list_folder_files(
835
+ folder_id="folder_id",
836
+ )
837
+ """
838
+ _response = self._client_wrapper.httpx_client.request(
839
+ f"v1/folders/{jsonable_encoder(folder_id)}/files",
840
+ method="GET",
841
+ params={
842
+ "limit": limit,
843
+ "after": after,
844
+ "include_content": include_content,
845
+ },
846
+ request_options=request_options,
847
+ )
848
+ try:
849
+ if 200 <= _response.status_code < 300:
850
+ return typing.cast(
851
+ typing.List[FileMetadata],
852
+ construct_type(
853
+ type_=typing.List[FileMetadata], # type: ignore
854
+ object_=_response.json(),
855
+ ),
856
+ )
857
+ if _response.status_code == 422:
858
+ raise UnprocessableEntityError(
859
+ typing.cast(
860
+ HttpValidationError,
861
+ construct_type(
862
+ type_=HttpValidationError, # type: ignore
863
+ object_=_response.json(),
864
+ ),
865
+ )
866
+ )
867
+ _response_json = _response.json()
868
+ except JSONDecodeError:
869
+ raise ApiError(status_code=_response.status_code, body=_response.text)
870
+ raise ApiError(status_code=_response.status_code, body=_response_json)
871
+
872
+ def delete_file_from_folder(
873
+ self, folder_id: str, file_id: str, *, request_options: typing.Optional[RequestOptions] = None
874
+ ) -> None:
875
+ """
876
+ Delete a file from a folder.
877
+
878
+ Parameters
879
+ ----------
880
+ folder_id : str
881
+
882
+ file_id : str
883
+
884
+ request_options : typing.Optional[RequestOptions]
885
+ Request-specific configuration.
886
+
887
+ Returns
888
+ -------
889
+ None
890
+
891
+ Examples
892
+ --------
893
+ from letta_client import Letta
894
+
895
+ client = Letta(
896
+ project="YOUR_PROJECT",
897
+ token="YOUR_TOKEN",
898
+ )
899
+ client.folders.delete_file_from_folder(
900
+ folder_id="folder_id",
901
+ file_id="file_id",
902
+ )
903
+ """
904
+ _response = self._client_wrapper.httpx_client.request(
905
+ f"v1/folders/{jsonable_encoder(folder_id)}/{jsonable_encoder(file_id)}",
906
+ method="DELETE",
907
+ request_options=request_options,
908
+ )
909
+ try:
910
+ if 200 <= _response.status_code < 300:
911
+ return
912
+ if _response.status_code == 422:
913
+ raise UnprocessableEntityError(
914
+ typing.cast(
915
+ HttpValidationError,
916
+ construct_type(
917
+ type_=HttpValidationError, # type: ignore
918
+ object_=_response.json(),
919
+ ),
920
+ )
921
+ )
922
+ _response_json = _response.json()
923
+ except JSONDecodeError:
924
+ raise ApiError(status_code=_response.status_code, body=_response.text)
925
+ raise ApiError(status_code=_response.status_code, body=_response_json)
926
+
927
+
928
+ class AsyncFoldersClient:
929
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
930
+ self._client_wrapper = client_wrapper
931
+
932
+ async def count_folders(self, *, request_options: typing.Optional[RequestOptions] = None) -> int:
933
+ """
934
+ Count all data folders created by a user.
935
+
936
+ Parameters
937
+ ----------
938
+ request_options : typing.Optional[RequestOptions]
939
+ Request-specific configuration.
940
+
941
+ Returns
942
+ -------
943
+ int
944
+ Successful Response
945
+
946
+ Examples
947
+ --------
948
+ import asyncio
949
+
950
+ from letta_client import AsyncLetta
951
+
952
+ client = AsyncLetta(
953
+ project="YOUR_PROJECT",
954
+ token="YOUR_TOKEN",
955
+ )
956
+
957
+
958
+ async def main() -> None:
959
+ await client.folders.count_folders()
960
+
961
+
962
+ asyncio.run(main())
963
+ """
964
+ _response = await self._client_wrapper.httpx_client.request(
965
+ "v1/folders/count",
966
+ method="GET",
967
+ request_options=request_options,
968
+ )
969
+ try:
970
+ if 200 <= _response.status_code < 300:
971
+ return typing.cast(
972
+ int,
973
+ construct_type(
974
+ type_=int, # type: ignore
975
+ object_=_response.json(),
976
+ ),
977
+ )
978
+ if _response.status_code == 422:
979
+ raise UnprocessableEntityError(
980
+ typing.cast(
981
+ HttpValidationError,
982
+ construct_type(
983
+ type_=HttpValidationError, # type: ignore
984
+ object_=_response.json(),
985
+ ),
986
+ )
987
+ )
988
+ _response_json = _response.json()
989
+ except JSONDecodeError:
990
+ raise ApiError(status_code=_response.status_code, body=_response.text)
991
+ raise ApiError(status_code=_response.status_code, body=_response_json)
992
+
993
+ async def retrieve_folder(
994
+ self, folder_id: str, *, request_options: typing.Optional[RequestOptions] = None
995
+ ) -> Folder:
996
+ """
997
+ Get a folder by ID
998
+
999
+ Parameters
1000
+ ----------
1001
+ folder_id : str
1002
+
1003
+ request_options : typing.Optional[RequestOptions]
1004
+ Request-specific configuration.
1005
+
1006
+ Returns
1007
+ -------
1008
+ Folder
1009
+ Successful Response
1010
+
1011
+ Examples
1012
+ --------
1013
+ import asyncio
1014
+
1015
+ from letta_client import AsyncLetta
1016
+
1017
+ client = AsyncLetta(
1018
+ project="YOUR_PROJECT",
1019
+ token="YOUR_TOKEN",
1020
+ )
1021
+
1022
+
1023
+ async def main() -> None:
1024
+ await client.folders.retrieve_folder(
1025
+ folder_id="folder_id",
1026
+ )
1027
+
1028
+
1029
+ asyncio.run(main())
1030
+ """
1031
+ _response = await self._client_wrapper.httpx_client.request(
1032
+ f"v1/folders/{jsonable_encoder(folder_id)}",
1033
+ method="GET",
1034
+ request_options=request_options,
1035
+ )
1036
+ try:
1037
+ if 200 <= _response.status_code < 300:
1038
+ return typing.cast(
1039
+ Folder,
1040
+ construct_type(
1041
+ type_=Folder, # type: ignore
1042
+ object_=_response.json(),
1043
+ ),
1044
+ )
1045
+ if _response.status_code == 422:
1046
+ raise UnprocessableEntityError(
1047
+ typing.cast(
1048
+ HttpValidationError,
1049
+ construct_type(
1050
+ type_=HttpValidationError, # type: ignore
1051
+ object_=_response.json(),
1052
+ ),
1053
+ )
1054
+ )
1055
+ _response_json = _response.json()
1056
+ except JSONDecodeError:
1057
+ raise ApiError(status_code=_response.status_code, body=_response.text)
1058
+ raise ApiError(status_code=_response.status_code, body=_response_json)
1059
+
1060
+ async def delete_folder(
1061
+ self, folder_id: str, *, request_options: typing.Optional[RequestOptions] = None
1062
+ ) -> typing.Optional[typing.Any]:
1063
+ """
1064
+ Delete a data folder.
1065
+
1066
+ Parameters
1067
+ ----------
1068
+ folder_id : str
1069
+
1070
+ request_options : typing.Optional[RequestOptions]
1071
+ Request-specific configuration.
1072
+
1073
+ Returns
1074
+ -------
1075
+ typing.Optional[typing.Any]
1076
+ Successful Response
1077
+
1078
+ Examples
1079
+ --------
1080
+ import asyncio
1081
+
1082
+ from letta_client import AsyncLetta
1083
+
1084
+ client = AsyncLetta(
1085
+ project="YOUR_PROJECT",
1086
+ token="YOUR_TOKEN",
1087
+ )
1088
+
1089
+
1090
+ async def main() -> None:
1091
+ await client.folders.delete_folder(
1092
+ folder_id="folder_id",
1093
+ )
1094
+
1095
+
1096
+ asyncio.run(main())
1097
+ """
1098
+ _response = await self._client_wrapper.httpx_client.request(
1099
+ f"v1/folders/{jsonable_encoder(folder_id)}",
1100
+ method="DELETE",
1101
+ request_options=request_options,
1102
+ )
1103
+ try:
1104
+ if 200 <= _response.status_code < 300:
1105
+ return typing.cast(
1106
+ typing.Optional[typing.Any],
1107
+ construct_type(
1108
+ type_=typing.Optional[typing.Any], # type: ignore
1109
+ object_=_response.json(),
1110
+ ),
1111
+ )
1112
+ if _response.status_code == 422:
1113
+ raise UnprocessableEntityError(
1114
+ typing.cast(
1115
+ HttpValidationError,
1116
+ construct_type(
1117
+ type_=HttpValidationError, # type: ignore
1118
+ object_=_response.json(),
1119
+ ),
1120
+ )
1121
+ )
1122
+ _response_json = _response.json()
1123
+ except JSONDecodeError:
1124
+ raise ApiError(status_code=_response.status_code, body=_response.text)
1125
+ raise ApiError(status_code=_response.status_code, body=_response_json)
1126
+
1127
+ async def modify_folder(
1128
+ self,
1129
+ folder_id: str,
1130
+ *,
1131
+ name: typing.Optional[str] = OMIT,
1132
+ description: typing.Optional[str] = OMIT,
1133
+ instructions: typing.Optional[str] = OMIT,
1134
+ metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
1135
+ embedding_config: typing.Optional[EmbeddingConfig] = OMIT,
1136
+ request_options: typing.Optional[RequestOptions] = None,
1137
+ ) -> Folder:
1138
+ """
1139
+ Update the name or documentation of an existing data folder.
1140
+
1141
+ Parameters
1142
+ ----------
1143
+ folder_id : str
1144
+
1145
+ name : typing.Optional[str]
1146
+ The name of the folder.
1147
+
1148
+ description : typing.Optional[str]
1149
+ The description of the folder.
1150
+
1151
+ instructions : typing.Optional[str]
1152
+ Instructions for how to use the folder.
1153
+
1154
+ metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
1155
+ Metadata associated with the folder.
1156
+
1157
+ embedding_config : typing.Optional[EmbeddingConfig]
1158
+ The embedding configuration used by the folder.
1159
+
1160
+ request_options : typing.Optional[RequestOptions]
1161
+ Request-specific configuration.
1162
+
1163
+ Returns
1164
+ -------
1165
+ Folder
1166
+ Successful Response
1167
+
1168
+ Examples
1169
+ --------
1170
+ import asyncio
1171
+
1172
+ from letta_client import AsyncLetta
1173
+
1174
+ client = AsyncLetta(
1175
+ project="YOUR_PROJECT",
1176
+ token="YOUR_TOKEN",
1177
+ )
1178
+
1179
+
1180
+ async def main() -> None:
1181
+ await client.folders.modify_folder(
1182
+ folder_id="folder_id",
1183
+ )
1184
+
1185
+
1186
+ asyncio.run(main())
1187
+ """
1188
+ _response = await self._client_wrapper.httpx_client.request(
1189
+ f"v1/folders/{jsonable_encoder(folder_id)}",
1190
+ method="PATCH",
1191
+ json={
1192
+ "name": name,
1193
+ "description": description,
1194
+ "instructions": instructions,
1195
+ "metadata": metadata,
1196
+ "embedding_config": convert_and_respect_annotation_metadata(
1197
+ object_=embedding_config, annotation=EmbeddingConfig, direction="write"
1198
+ ),
1199
+ },
1200
+ headers={
1201
+ "content-type": "application/json",
1202
+ },
1203
+ request_options=request_options,
1204
+ omit=OMIT,
1205
+ )
1206
+ try:
1207
+ if 200 <= _response.status_code < 300:
1208
+ return typing.cast(
1209
+ Folder,
1210
+ construct_type(
1211
+ type_=Folder, # type: ignore
1212
+ object_=_response.json(),
1213
+ ),
1214
+ )
1215
+ if _response.status_code == 422:
1216
+ raise UnprocessableEntityError(
1217
+ typing.cast(
1218
+ HttpValidationError,
1219
+ construct_type(
1220
+ type_=HttpValidationError, # type: ignore
1221
+ object_=_response.json(),
1222
+ ),
1223
+ )
1224
+ )
1225
+ _response_json = _response.json()
1226
+ except JSONDecodeError:
1227
+ raise ApiError(status_code=_response.status_code, body=_response.text)
1228
+ raise ApiError(status_code=_response.status_code, body=_response_json)
1229
+
1230
+ async def get_folder_id_by_name(
1231
+ self, folder_name: str, *, request_options: typing.Optional[RequestOptions] = None
1232
+ ) -> str:
1233
+ """
1234
+ Get a folder by name
1235
+
1236
+ Parameters
1237
+ ----------
1238
+ folder_name : str
1239
+
1240
+ request_options : typing.Optional[RequestOptions]
1241
+ Request-specific configuration.
1242
+
1243
+ Returns
1244
+ -------
1245
+ str
1246
+ Successful Response
1247
+
1248
+ Examples
1249
+ --------
1250
+ import asyncio
1251
+
1252
+ from letta_client import AsyncLetta
1253
+
1254
+ client = AsyncLetta(
1255
+ project="YOUR_PROJECT",
1256
+ token="YOUR_TOKEN",
1257
+ )
1258
+
1259
+
1260
+ async def main() -> None:
1261
+ await client.folders.get_folder_id_by_name(
1262
+ folder_name="folder_name",
1263
+ )
1264
+
1265
+
1266
+ asyncio.run(main())
1267
+ """
1268
+ _response = await self._client_wrapper.httpx_client.request(
1269
+ f"v1/folders/name/{jsonable_encoder(folder_name)}",
1270
+ method="GET",
1271
+ request_options=request_options,
1272
+ )
1273
+ try:
1274
+ if 200 <= _response.status_code < 300:
1275
+ return typing.cast(
1276
+ str,
1277
+ construct_type(
1278
+ type_=str, # type: ignore
1279
+ object_=_response.json(),
1280
+ ),
1281
+ )
1282
+ if _response.status_code == 422:
1283
+ raise UnprocessableEntityError(
1284
+ typing.cast(
1285
+ HttpValidationError,
1286
+ construct_type(
1287
+ type_=HttpValidationError, # type: ignore
1288
+ object_=_response.json(),
1289
+ ),
1290
+ )
1291
+ )
1292
+ _response_json = _response.json()
1293
+ except JSONDecodeError:
1294
+ raise ApiError(status_code=_response.status_code, body=_response.text)
1295
+ raise ApiError(status_code=_response.status_code, body=_response_json)
1296
+
1297
+ async def get_folders_metadata(
1298
+ self,
1299
+ *,
1300
+ include_detailed_per_source_metadata: typing.Optional[bool] = None,
1301
+ request_options: typing.Optional[RequestOptions] = None,
1302
+ ) -> OrganizationSourcesStats:
1303
+ """
1304
+ Get aggregated metadata for all folders in an organization.
1305
+
1306
+ Returns structured metadata including:
1307
+ - Total number of folders
1308
+ - Total number of files across all folders
1309
+ - Total size of all files
1310
+ - Per-source breakdown with file details (file_name, file_size per file) if include_detailed_per_source_metadata is True
1311
+
1312
+ Parameters
1313
+ ----------
1314
+ include_detailed_per_source_metadata : typing.Optional[bool]
1315
+
1316
+ request_options : typing.Optional[RequestOptions]
1317
+ Request-specific configuration.
1318
+
1319
+ Returns
1320
+ -------
1321
+ OrganizationSourcesStats
1322
+ Successful Response
1323
+
1324
+ Examples
1325
+ --------
1326
+ import asyncio
1327
+
1328
+ from letta_client import AsyncLetta
1329
+
1330
+ client = AsyncLetta(
1331
+ project="YOUR_PROJECT",
1332
+ token="YOUR_TOKEN",
1333
+ )
1334
+
1335
+
1336
+ async def main() -> None:
1337
+ await client.folders.get_folders_metadata()
1338
+
1339
+
1340
+ asyncio.run(main())
1341
+ """
1342
+ _response = await self._client_wrapper.httpx_client.request(
1343
+ "v1/folders/metadata",
1344
+ method="GET",
1345
+ params={
1346
+ "include_detailed_per_source_metadata": include_detailed_per_source_metadata,
1347
+ },
1348
+ request_options=request_options,
1349
+ )
1350
+ try:
1351
+ if 200 <= _response.status_code < 300:
1352
+ return typing.cast(
1353
+ OrganizationSourcesStats,
1354
+ construct_type(
1355
+ type_=OrganizationSourcesStats, # type: ignore
1356
+ object_=_response.json(),
1357
+ ),
1358
+ )
1359
+ if _response.status_code == 422:
1360
+ raise UnprocessableEntityError(
1361
+ typing.cast(
1362
+ HttpValidationError,
1363
+ construct_type(
1364
+ type_=HttpValidationError, # type: ignore
1365
+ object_=_response.json(),
1366
+ ),
1367
+ )
1368
+ )
1369
+ _response_json = _response.json()
1370
+ except JSONDecodeError:
1371
+ raise ApiError(status_code=_response.status_code, body=_response.text)
1372
+ raise ApiError(status_code=_response.status_code, body=_response_json)
1373
+
1374
+ async def list_folders(self, *, request_options: typing.Optional[RequestOptions] = None) -> typing.List[Folder]:
1375
+ """
1376
+ List all data folders created by a user.
1377
+
1378
+ Parameters
1379
+ ----------
1380
+ request_options : typing.Optional[RequestOptions]
1381
+ Request-specific configuration.
1382
+
1383
+ Returns
1384
+ -------
1385
+ typing.List[Folder]
1386
+ Successful Response
1387
+
1388
+ Examples
1389
+ --------
1390
+ import asyncio
1391
+
1392
+ from letta_client import AsyncLetta
1393
+
1394
+ client = AsyncLetta(
1395
+ project="YOUR_PROJECT",
1396
+ token="YOUR_TOKEN",
1397
+ )
1398
+
1399
+
1400
+ async def main() -> None:
1401
+ await client.folders.list_folders()
1402
+
1403
+
1404
+ asyncio.run(main())
1405
+ """
1406
+ _response = await self._client_wrapper.httpx_client.request(
1407
+ "v1/folders/",
1408
+ method="GET",
1409
+ request_options=request_options,
1410
+ )
1411
+ try:
1412
+ if 200 <= _response.status_code < 300:
1413
+ return typing.cast(
1414
+ typing.List[Folder],
1415
+ construct_type(
1416
+ type_=typing.List[Folder], # type: ignore
1417
+ object_=_response.json(),
1418
+ ),
1419
+ )
1420
+ if _response.status_code == 422:
1421
+ raise UnprocessableEntityError(
1422
+ typing.cast(
1423
+ HttpValidationError,
1424
+ construct_type(
1425
+ type_=HttpValidationError, # type: ignore
1426
+ object_=_response.json(),
1427
+ ),
1428
+ )
1429
+ )
1430
+ _response_json = _response.json()
1431
+ except JSONDecodeError:
1432
+ raise ApiError(status_code=_response.status_code, body=_response.text)
1433
+ raise ApiError(status_code=_response.status_code, body=_response_json)
1434
+
1435
+ async def create_folder(
1436
+ self,
1437
+ *,
1438
+ name: str,
1439
+ description: typing.Optional[str] = OMIT,
1440
+ instructions: typing.Optional[str] = OMIT,
1441
+ metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
1442
+ embedding: typing.Optional[str] = OMIT,
1443
+ embedding_chunk_size: typing.Optional[int] = OMIT,
1444
+ embedding_config: typing.Optional[EmbeddingConfig] = OMIT,
1445
+ request_options: typing.Optional[RequestOptions] = None,
1446
+ ) -> Folder:
1447
+ """
1448
+ Create a new data folder.
1449
+
1450
+ Parameters
1451
+ ----------
1452
+ name : str
1453
+ The name of the folder.
1454
+
1455
+ description : typing.Optional[str]
1456
+ The description of the folder.
1457
+
1458
+ instructions : typing.Optional[str]
1459
+ Instructions for how to use the folder.
1460
+
1461
+ metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
1462
+ Metadata associated with the folder.
1463
+
1464
+ embedding : typing.Optional[str]
1465
+ The handle for the embedding config used by the folder.
1466
+
1467
+ embedding_chunk_size : typing.Optional[int]
1468
+ The chunk size of the embedding.
1469
+
1470
+ embedding_config : typing.Optional[EmbeddingConfig]
1471
+ (Legacy) The embedding configuration used by the folder.
1472
+
1473
+ request_options : typing.Optional[RequestOptions]
1474
+ Request-specific configuration.
1475
+
1476
+ Returns
1477
+ -------
1478
+ Folder
1479
+ Successful Response
1480
+
1481
+ Examples
1482
+ --------
1483
+ import asyncio
1484
+
1485
+ from letta_client import AsyncLetta
1486
+
1487
+ client = AsyncLetta(
1488
+ project="YOUR_PROJECT",
1489
+ token="YOUR_TOKEN",
1490
+ )
1491
+
1492
+
1493
+ async def main() -> None:
1494
+ await client.folders.create_folder(
1495
+ name="name",
1496
+ )
1497
+
1498
+
1499
+ asyncio.run(main())
1500
+ """
1501
+ _response = await self._client_wrapper.httpx_client.request(
1502
+ "v1/folders/",
1503
+ method="POST",
1504
+ json={
1505
+ "name": name,
1506
+ "description": description,
1507
+ "instructions": instructions,
1508
+ "metadata": metadata,
1509
+ "embedding": embedding,
1510
+ "embedding_chunk_size": embedding_chunk_size,
1511
+ "embedding_config": convert_and_respect_annotation_metadata(
1512
+ object_=embedding_config, annotation=EmbeddingConfig, direction="write"
1513
+ ),
1514
+ },
1515
+ headers={
1516
+ "content-type": "application/json",
1517
+ },
1518
+ request_options=request_options,
1519
+ omit=OMIT,
1520
+ )
1521
+ try:
1522
+ if 200 <= _response.status_code < 300:
1523
+ return typing.cast(
1524
+ Folder,
1525
+ construct_type(
1526
+ type_=Folder, # type: ignore
1527
+ object_=_response.json(),
1528
+ ),
1529
+ )
1530
+ if _response.status_code == 422:
1531
+ raise UnprocessableEntityError(
1532
+ typing.cast(
1533
+ HttpValidationError,
1534
+ construct_type(
1535
+ type_=HttpValidationError, # type: ignore
1536
+ object_=_response.json(),
1537
+ ),
1538
+ )
1539
+ )
1540
+ _response_json = _response.json()
1541
+ except JSONDecodeError:
1542
+ raise ApiError(status_code=_response.status_code, body=_response.text)
1543
+ raise ApiError(status_code=_response.status_code, body=_response_json)
1544
+
1545
+ async def upload_file_to_folder(
1546
+ self,
1547
+ folder_id: str,
1548
+ *,
1549
+ file: core.File,
1550
+ duplicate_handling: typing.Optional[DuplicateFileHandling] = None,
1551
+ request_options: typing.Optional[RequestOptions] = None,
1552
+ ) -> FileMetadata:
1553
+ """
1554
+ Upload a file to a data folder.
1555
+
1556
+ Parameters
1557
+ ----------
1558
+ folder_id : str
1559
+
1560
+ file : core.File
1561
+ See core.File for more documentation
1562
+
1563
+ duplicate_handling : typing.Optional[DuplicateFileHandling]
1564
+ How to handle duplicate filenames
1565
+
1566
+ request_options : typing.Optional[RequestOptions]
1567
+ Request-specific configuration.
1568
+
1569
+ Returns
1570
+ -------
1571
+ FileMetadata
1572
+ Successful Response
1573
+
1574
+ Examples
1575
+ --------
1576
+ import asyncio
1577
+
1578
+ from letta_client import AsyncLetta
1579
+
1580
+ client = AsyncLetta(
1581
+ project="YOUR_PROJECT",
1582
+ token="YOUR_TOKEN",
1583
+ )
1584
+
1585
+
1586
+ async def main() -> None:
1587
+ await client.folders.upload_file_to_folder(
1588
+ folder_id="folder_id",
1589
+ )
1590
+
1591
+
1592
+ asyncio.run(main())
1593
+ """
1594
+ _response = await self._client_wrapper.httpx_client.request(
1595
+ f"v1/folders/{jsonable_encoder(folder_id)}/upload",
1596
+ method="POST",
1597
+ params={
1598
+ "duplicate_handling": duplicate_handling,
1599
+ },
1600
+ data={},
1601
+ files={
1602
+ "file": file,
1603
+ },
1604
+ request_options=request_options,
1605
+ omit=OMIT,
1606
+ )
1607
+ try:
1608
+ if 200 <= _response.status_code < 300:
1609
+ return typing.cast(
1610
+ FileMetadata,
1611
+ construct_type(
1612
+ type_=FileMetadata, # type: ignore
1613
+ object_=_response.json(),
1614
+ ),
1615
+ )
1616
+ if _response.status_code == 422:
1617
+ raise UnprocessableEntityError(
1618
+ typing.cast(
1619
+ HttpValidationError,
1620
+ construct_type(
1621
+ type_=HttpValidationError, # type: ignore
1622
+ object_=_response.json(),
1623
+ ),
1624
+ )
1625
+ )
1626
+ _response_json = _response.json()
1627
+ except JSONDecodeError:
1628
+ raise ApiError(status_code=_response.status_code, body=_response.text)
1629
+ raise ApiError(status_code=_response.status_code, body=_response_json)
1630
+
1631
+ async def get_agents_for_folder(
1632
+ self, folder_id: str, *, request_options: typing.Optional[RequestOptions] = None
1633
+ ) -> typing.List[str]:
1634
+ """
1635
+ Get all agent IDs that have the specified folder attached.
1636
+
1637
+ Parameters
1638
+ ----------
1639
+ folder_id : str
1640
+
1641
+ request_options : typing.Optional[RequestOptions]
1642
+ Request-specific configuration.
1643
+
1644
+ Returns
1645
+ -------
1646
+ typing.List[str]
1647
+ Successful Response
1648
+
1649
+ Examples
1650
+ --------
1651
+ import asyncio
1652
+
1653
+ from letta_client import AsyncLetta
1654
+
1655
+ client = AsyncLetta(
1656
+ project="YOUR_PROJECT",
1657
+ token="YOUR_TOKEN",
1658
+ )
1659
+
1660
+
1661
+ async def main() -> None:
1662
+ await client.folders.get_agents_for_folder(
1663
+ folder_id="folder_id",
1664
+ )
1665
+
1666
+
1667
+ asyncio.run(main())
1668
+ """
1669
+ _response = await self._client_wrapper.httpx_client.request(
1670
+ f"v1/folders/{jsonable_encoder(folder_id)}/agents",
1671
+ method="GET",
1672
+ request_options=request_options,
1673
+ )
1674
+ try:
1675
+ if 200 <= _response.status_code < 300:
1676
+ return typing.cast(
1677
+ typing.List[str],
1678
+ construct_type(
1679
+ type_=typing.List[str], # type: ignore
1680
+ object_=_response.json(),
1681
+ ),
1682
+ )
1683
+ if _response.status_code == 422:
1684
+ raise UnprocessableEntityError(
1685
+ typing.cast(
1686
+ HttpValidationError,
1687
+ construct_type(
1688
+ type_=HttpValidationError, # type: ignore
1689
+ object_=_response.json(),
1690
+ ),
1691
+ )
1692
+ )
1693
+ _response_json = _response.json()
1694
+ except JSONDecodeError:
1695
+ raise ApiError(status_code=_response.status_code, body=_response.text)
1696
+ raise ApiError(status_code=_response.status_code, body=_response_json)
1697
+
1698
+ async def list_folder_passages(
1699
+ self,
1700
+ folder_id: str,
1701
+ *,
1702
+ after: typing.Optional[str] = None,
1703
+ before: typing.Optional[str] = None,
1704
+ limit: typing.Optional[int] = None,
1705
+ request_options: typing.Optional[RequestOptions] = None,
1706
+ ) -> typing.List[Passage]:
1707
+ """
1708
+ List all passages associated with a data folder.
1709
+
1710
+ Parameters
1711
+ ----------
1712
+ folder_id : str
1713
+
1714
+ after : typing.Optional[str]
1715
+ Message after which to retrieve the returned messages.
1716
+
1717
+ before : typing.Optional[str]
1718
+ Message before which to retrieve the returned messages.
1719
+
1720
+ limit : typing.Optional[int]
1721
+ Maximum number of messages to retrieve.
1722
+
1723
+ request_options : typing.Optional[RequestOptions]
1724
+ Request-specific configuration.
1725
+
1726
+ Returns
1727
+ -------
1728
+ typing.List[Passage]
1729
+ Successful Response
1730
+
1731
+ Examples
1732
+ --------
1733
+ import asyncio
1734
+
1735
+ from letta_client import AsyncLetta
1736
+
1737
+ client = AsyncLetta(
1738
+ project="YOUR_PROJECT",
1739
+ token="YOUR_TOKEN",
1740
+ )
1741
+
1742
+
1743
+ async def main() -> None:
1744
+ await client.folders.list_folder_passages(
1745
+ folder_id="folder_id",
1746
+ )
1747
+
1748
+
1749
+ asyncio.run(main())
1750
+ """
1751
+ _response = await self._client_wrapper.httpx_client.request(
1752
+ f"v1/folders/{jsonable_encoder(folder_id)}/passages",
1753
+ method="GET",
1754
+ params={
1755
+ "after": after,
1756
+ "before": before,
1757
+ "limit": limit,
1758
+ },
1759
+ request_options=request_options,
1760
+ )
1761
+ try:
1762
+ if 200 <= _response.status_code < 300:
1763
+ return typing.cast(
1764
+ typing.List[Passage],
1765
+ construct_type(
1766
+ type_=typing.List[Passage], # type: ignore
1767
+ object_=_response.json(),
1768
+ ),
1769
+ )
1770
+ if _response.status_code == 422:
1771
+ raise UnprocessableEntityError(
1772
+ typing.cast(
1773
+ HttpValidationError,
1774
+ construct_type(
1775
+ type_=HttpValidationError, # type: ignore
1776
+ object_=_response.json(),
1777
+ ),
1778
+ )
1779
+ )
1780
+ _response_json = _response.json()
1781
+ except JSONDecodeError:
1782
+ raise ApiError(status_code=_response.status_code, body=_response.text)
1783
+ raise ApiError(status_code=_response.status_code, body=_response_json)
1784
+
1785
+ async def list_folder_files(
1786
+ self,
1787
+ folder_id: str,
1788
+ *,
1789
+ limit: typing.Optional[int] = None,
1790
+ after: typing.Optional[str] = None,
1791
+ include_content: typing.Optional[bool] = None,
1792
+ request_options: typing.Optional[RequestOptions] = None,
1793
+ ) -> typing.List[FileMetadata]:
1794
+ """
1795
+ List paginated files associated with a data folder.
1796
+
1797
+ Parameters
1798
+ ----------
1799
+ folder_id : str
1800
+
1801
+ limit : typing.Optional[int]
1802
+ Number of files to return
1803
+
1804
+ after : typing.Optional[str]
1805
+ Pagination cursor to fetch the next set of results
1806
+
1807
+ include_content : typing.Optional[bool]
1808
+ Whether to include full file content
1809
+
1810
+ request_options : typing.Optional[RequestOptions]
1811
+ Request-specific configuration.
1812
+
1813
+ Returns
1814
+ -------
1815
+ typing.List[FileMetadata]
1816
+ Successful Response
1817
+
1818
+ Examples
1819
+ --------
1820
+ import asyncio
1821
+
1822
+ from letta_client import AsyncLetta
1823
+
1824
+ client = AsyncLetta(
1825
+ project="YOUR_PROJECT",
1826
+ token="YOUR_TOKEN",
1827
+ )
1828
+
1829
+
1830
+ async def main() -> None:
1831
+ await client.folders.list_folder_files(
1832
+ folder_id="folder_id",
1833
+ )
1834
+
1835
+
1836
+ asyncio.run(main())
1837
+ """
1838
+ _response = await self._client_wrapper.httpx_client.request(
1839
+ f"v1/folders/{jsonable_encoder(folder_id)}/files",
1840
+ method="GET",
1841
+ params={
1842
+ "limit": limit,
1843
+ "after": after,
1844
+ "include_content": include_content,
1845
+ },
1846
+ request_options=request_options,
1847
+ )
1848
+ try:
1849
+ if 200 <= _response.status_code < 300:
1850
+ return typing.cast(
1851
+ typing.List[FileMetadata],
1852
+ construct_type(
1853
+ type_=typing.List[FileMetadata], # type: ignore
1854
+ object_=_response.json(),
1855
+ ),
1856
+ )
1857
+ if _response.status_code == 422:
1858
+ raise UnprocessableEntityError(
1859
+ typing.cast(
1860
+ HttpValidationError,
1861
+ construct_type(
1862
+ type_=HttpValidationError, # type: ignore
1863
+ object_=_response.json(),
1864
+ ),
1865
+ )
1866
+ )
1867
+ _response_json = _response.json()
1868
+ except JSONDecodeError:
1869
+ raise ApiError(status_code=_response.status_code, body=_response.text)
1870
+ raise ApiError(status_code=_response.status_code, body=_response_json)
1871
+
1872
+ async def delete_file_from_folder(
1873
+ self, folder_id: str, file_id: str, *, request_options: typing.Optional[RequestOptions] = None
1874
+ ) -> None:
1875
+ """
1876
+ Delete a file from a folder.
1877
+
1878
+ Parameters
1879
+ ----------
1880
+ folder_id : str
1881
+
1882
+ file_id : str
1883
+
1884
+ request_options : typing.Optional[RequestOptions]
1885
+ Request-specific configuration.
1886
+
1887
+ Returns
1888
+ -------
1889
+ None
1890
+
1891
+ Examples
1892
+ --------
1893
+ import asyncio
1894
+
1895
+ from letta_client import AsyncLetta
1896
+
1897
+ client = AsyncLetta(
1898
+ project="YOUR_PROJECT",
1899
+ token="YOUR_TOKEN",
1900
+ )
1901
+
1902
+
1903
+ async def main() -> None:
1904
+ await client.folders.delete_file_from_folder(
1905
+ folder_id="folder_id",
1906
+ file_id="file_id",
1907
+ )
1908
+
1909
+
1910
+ asyncio.run(main())
1911
+ """
1912
+ _response = await self._client_wrapper.httpx_client.request(
1913
+ f"v1/folders/{jsonable_encoder(folder_id)}/{jsonable_encoder(file_id)}",
1914
+ method="DELETE",
1915
+ request_options=request_options,
1916
+ )
1917
+ try:
1918
+ if 200 <= _response.status_code < 300:
1919
+ return
1920
+ if _response.status_code == 422:
1921
+ raise UnprocessableEntityError(
1922
+ typing.cast(
1923
+ HttpValidationError,
1924
+ construct_type(
1925
+ type_=HttpValidationError, # type: ignore
1926
+ object_=_response.json(),
1927
+ ),
1928
+ )
1929
+ )
1930
+ _response_json = _response.json()
1931
+ except JSONDecodeError:
1932
+ raise ApiError(status_code=_response.status_code, body=_response.text)
1933
+ raise ApiError(status_code=_response.status_code, body=_response_json)