letta-client 0.1.77__py3-none-any.whl → 0.1.79__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.

letta_client/client.py CHANGED
@@ -7,6 +7,7 @@ from abc import abstractmethod
7
7
  from .base_client import AsyncLettaBase, LettaBase
8
8
  from .core.request_options import RequestOptions
9
9
  from .tools.client import ToolsClient as ToolsClientBase
10
+ from .tools.client import AsyncToolsClient as AsyncToolsClientBase
10
11
  from .types.tool import Tool
11
12
 
12
13
  # this is used as the default value for optional parameters
@@ -24,7 +25,7 @@ class AsyncLetta(AsyncLettaBase):
24
25
 
25
26
  def __init__(self, *args, **kwargs):
26
27
  super().__init__(*args, **kwargs)
27
- self.tools = ToolsClient(client_wrapper=self._client_wrapper)
28
+ self.tools = AsyncToolsClient(client_wrapper=self._client_wrapper)
28
29
 
29
30
 
30
31
  class BaseTool(Tool):
@@ -380,3 +381,258 @@ class ToolsClient(ToolsClientBase):
380
381
  return_char_limit=tool.return_char_limit or OMIT,
381
382
  request_options=request_options,
382
383
  )
384
+
385
+
386
+ class AsyncToolsClient(AsyncToolsClientBase):
387
+
388
+ async def create_from_function(
389
+ self,
390
+ *,
391
+ func: typing.Callable,
392
+ args_schema: typing.Optional[typing.Type[BaseModel]] = OMIT,
393
+ description: typing.Optional[str] = OMIT,
394
+ tags: typing.Optional[typing.Sequence[str]] = OMIT,
395
+ source_type: typing.Optional[str] = OMIT,
396
+ json_schema: typing.Optional[
397
+ typing.Dict[str, typing.Optional[typing.Any]]
398
+ ] = OMIT,
399
+ return_char_limit: typing.Optional[int] = OMIT,
400
+ request_options: typing.Optional[RequestOptions] = None,
401
+ ) -> Tool:
402
+ """
403
+ Create a new tool from a callable
404
+
405
+ Parameters
406
+ ----------
407
+ func : typing.Callable
408
+ The callable to create the tool from.
409
+
410
+ args_schema : typing.Optional[typing.Type[BaseModel]]
411
+ The arguments schema of the function, as a Pydantic model.
412
+
413
+ description : typing.Optional[str]
414
+ The description of the tool.
415
+
416
+ tags : typing.Optional[typing.Sequence[str]]
417
+ Metadata tags.
418
+
419
+ source_type : typing.Optional[str]
420
+ The source type of the function.
421
+
422
+ json_schema : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
423
+ The JSON schema of the function (auto-generated from source_code if not provided)
424
+
425
+ return_char_limit : typing.Optional[int]
426
+ The maximum number of characters in the response.
427
+
428
+ request_options : typing.Optional[RequestOptions]
429
+ Request-specific configuration.
430
+
431
+ Returns
432
+ -------
433
+ Tool
434
+ Successful Response
435
+
436
+ Examples
437
+ --------
438
+ from letta_client import Letta
439
+
440
+ client = Letta(
441
+ token="YOUR_TOKEN",
442
+ )
443
+
444
+ def add_two_numbers(a: int, b: int) -> int:
445
+ return a + b
446
+
447
+ await client.tools.create_from_function(
448
+ func=add_two_numbers,
449
+ )
450
+
451
+ class InventoryEntryData(BaseModel):
452
+ data: InventoryEntry
453
+ quantity_change: int
454
+
455
+ def manage_inventory(data: InventoryEntry, quantity_change: int) -> bool:
456
+ pass
457
+
458
+ await client.tools.create_from_function(
459
+ func=manage_inventory,
460
+ args_schema=InventoryEntryData,
461
+ )
462
+ """
463
+ source_code = dedent(inspect.getsource(func))
464
+ args_json_schema = args_schema.model_json_schema() if args_schema and args_schema != OMIT else None
465
+ return await self.create(
466
+ source_code=source_code,
467
+ args_json_schema=args_json_schema,
468
+ description=description,
469
+ tags=tags,
470
+ source_type=source_type,
471
+ json_schema=json_schema,
472
+ return_char_limit=return_char_limit,
473
+ request_options=request_options,
474
+ )
475
+
476
+
477
+ async def upsert_from_function(
478
+ self,
479
+ *,
480
+ func: typing.Callable,
481
+ args_schema: typing.Optional[typing.Type[BaseModel]] = OMIT,
482
+ description: typing.Optional[str] = OMIT,
483
+ tags: typing.Optional[typing.Sequence[str]] = OMIT,
484
+ source_type: typing.Optional[str] = OMIT,
485
+ json_schema: typing.Optional[
486
+ typing.Dict[str, typing.Optional[typing.Any]]
487
+ ] = OMIT,
488
+ return_char_limit: typing.Optional[int] = OMIT,
489
+ request_options: typing.Optional[RequestOptions] = None,
490
+ ) -> Tool:
491
+ """
492
+ Create or update a tool from a callable
493
+
494
+ Parameters
495
+ ----------
496
+ func : typing.Callable
497
+ The callable to create or update the tool from.
498
+
499
+ args_schema : typing.Optional[typing.Type[BaseModel]]
500
+ The arguments schema of the function, as a Pydantic model.
501
+
502
+ description : typing.Optional[str]
503
+ The description of the tool.
504
+
505
+ tags : typing.Optional[typing.Sequence[str]]
506
+ Metadata tags.
507
+
508
+ source_type : typing.Optional[str]
509
+ The source type of the function.
510
+
511
+ json_schema : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
512
+ The JSON schema of the function (auto-generated from source_code if not provided)
513
+
514
+ return_char_limit : typing.Optional[int]
515
+ The maximum number of characters in the response.
516
+
517
+ request_options : typing.Optional[RequestOptions]
518
+ Request-specific configuration.
519
+
520
+ Returns
521
+ -------
522
+ Tool
523
+ Successful Response
524
+
525
+ Examples
526
+ --------
527
+ from letta_client import Letta
528
+
529
+ client = Letta(
530
+ token="YOUR_TOKEN",
531
+ )
532
+
533
+ def add_two_numbers(a: int, b: int) -> int:
534
+ return a + b
535
+
536
+ await client.tools.upsert_from_function(
537
+ func=add_two_numbers,
538
+ )
539
+
540
+ class InventoryEntryData(BaseModel):
541
+ data: InventoryEntry
542
+ quantity_change: int
543
+
544
+ def manage_inventory(data: InventoryEntry, quantity_change: int) -> bool:
545
+ pass
546
+
547
+ await client.tools.upsert_from_function(
548
+ func=manage_inventory,
549
+ args_schema=InventoryEntryData,
550
+ )
551
+ """
552
+ source_code = dedent(inspect.getsource(func))
553
+ args_json_schema = args_schema.model_json_schema() if args_schema and args_schema != OMIT else None
554
+ return await self.upsert(
555
+ source_code=source_code,
556
+ args_json_schema=args_json_schema,
557
+ description=description,
558
+ tags=tags,
559
+ source_type=source_type,
560
+ json_schema=json_schema,
561
+ return_char_limit=return_char_limit,
562
+ request_options=request_options,
563
+ )
564
+
565
+ async def add(
566
+ self,
567
+ *,
568
+ tool: BaseTool,
569
+ request_options: typing.Optional[RequestOptions] = None,
570
+ ) -> Tool:
571
+ """
572
+ Add a tool to Letta from a custom Tool class
573
+
574
+ Parameters
575
+ ----------
576
+ tool : BaseTool
577
+ The tool object to be added.
578
+
579
+ request_options : typing.Optional[RequestOptions]
580
+ Request-specific configuration.
581
+
582
+ Returns
583
+ -------
584
+ Tool
585
+ Successful Response
586
+
587
+ Examples
588
+ --------
589
+ from letta_client import Letta
590
+
591
+ client = Letta(
592
+ token="YOUR_TOKEN",
593
+ )
594
+
595
+ class InventoryItem(BaseModel):
596
+ sku: str # Unique product identifier
597
+ name: str # Product name
598
+ price: float # Current price
599
+ category: str # Product category (e.g., "Electronics", "Clothing")
600
+
601
+ class InventoryEntry(BaseModel):
602
+ timestamp: int # Unix timestamp of the transaction
603
+ item: InventoryItem # The product being updated
604
+ transaction_id: str # Unique identifier for this inventory update
605
+
606
+ class InventoryEntryData(BaseModel):
607
+ data: InventoryEntry
608
+ quantity_change: int # Change in quantity (positive for additions, negative for removals)
609
+
610
+ class ManageInventoryTool(BaseTool):
611
+ name: str = "manage_inventory"
612
+ args_schema: Type[BaseModel] = InventoryEntryData
613
+ description: str = "Update inventory catalogue with a new data entry"
614
+ tags: List[str] = ["inventory", "shop"]
615
+
616
+ def run(self, data: InventoryEntry, quantity_change: int) -> bool:
617
+ '''
618
+ Implementation of the manage_inventory tool
619
+ '''
620
+ print(f"Updated inventory for {data.item.name} with a quantity change of {quantity_change}")
621
+ return True
622
+
623
+ await client.tools.add(
624
+ tool=ManageInventoryTool()
625
+ )
626
+ """
627
+ source_code = tool.get_source_code()
628
+ args_json_schema = tool.args_schema.model_json_schema() if tool.args_schema else None
629
+ return await self.upsert(
630
+ source_code=source_code,
631
+ args_json_schema=args_json_schema or OMIT,
632
+ description=tool.description or OMIT,
633
+ tags=tool.tags or OMIT,
634
+ source_type=tool.source_type or OMIT,
635
+ json_schema=tool.json_schema or OMIT,
636
+ return_char_limit=tool.return_char_limit or OMIT,
637
+ request_options=request_options,
638
+ )
@@ -16,7 +16,7 @@ class BaseClientWrapper:
16
16
  headers: typing.Dict[str, str] = {
17
17
  "X-Fern-Language": "Python",
18
18
  "X-Fern-SDK-Name": "letta-client",
19
- "X-Fern-SDK-Version": "0.1.77",
19
+ "X-Fern-SDK-Version": "0.1.79",
20
20
  }
21
21
  if self.token is not None:
22
22
  headers["Authorization"] = f"Bearer {self.token}"
@@ -4,5 +4,5 @@ import enum
4
4
 
5
5
 
6
6
  class LettaEnvironment(enum.Enum):
7
- LETTA_CLOUD = "https://app.letta.com"
7
+ LETTA_CLOUD = "https://api.letta.com"
8
8
  SELF_HOSTED = "http://localhost:8283"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: letta-client
3
- Version: 0.1.77
3
+ Version: 0.1.79
4
4
  Summary:
5
5
  Requires-Python: >=3.8,<4.0
6
6
  Classifier: Intended Audience :: Developers
@@ -231,10 +231,10 @@ letta_client/agents/types/update_agent_tool_rules_item.py,sha256=O0W83nOK8oMx_6N
231
231
  letta_client/base_client.py,sha256=bF1nEcPGrhNqelaWz3DgROYdroGsBFCjpAHHri0uq7I,8629
232
232
  letta_client/blocks/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8-_v1roeGPAKoa_pw,65
233
233
  letta_client/blocks/client.py,sha256=LE9dsHaBxFLC3G035f0VpNDG7XKWRK8y9OXpeFCMvUw,30082
234
- letta_client/client.py,sha256=xdSrD4IkWokZHujowd1r7zESBoVgKGNvo6RqgZ3f0Fg,12808
234
+ letta_client/client.py,sha256=k2mZqqEWciVmEQHgipjCK4kQILk74hpSqzcdNwdql9A,21212
235
235
  letta_client/core/__init__.py,sha256=OKbX2aCZXgHCDUsCouqv-OiX32xA6eFFCKIUH9M5Vzk,1591
236
236
  letta_client/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
237
- letta_client/core/client_wrapper.py,sha256=C7fBDdx_orCk4CP53xXubQTaQL1EQeWcRsOh94IY__M,1997
237
+ letta_client/core/client_wrapper.py,sha256=lOPfWM8JwQ7bdWtGr2yLwZAlAehsnseVorP-ta5I_60,1997
238
238
  letta_client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
239
239
  letta_client/core/file.py,sha256=d4NNbX8XvXP32z8KpK2Xovv33nFfruIrpz0QWxlgpZk,2663
240
240
  letta_client/core/http_client.py,sha256=Z77OIxIbL4OAB2IDqjRq_sYa5yNYAWfmdhdCSSvh6Y4,19552
@@ -245,7 +245,7 @@ letta_client/core/remove_none_from_dict.py,sha256=EU9SGgYidWq7SexuJbNs4-PZ-5Bl3V
245
245
  letta_client/core/request_options.py,sha256=h0QUNCFVdCW_7GclVySCAY2w4NhtXVBUCmHgmzaxpcg,1681
246
246
  letta_client/core/serialization.py,sha256=D9h_t-RQON3-CHWs1C4ESY9B-Yd5d-l5lnTLb_X896g,9601
247
247
  letta_client/core/unchecked_base_model.py,sha256=zliEPgLnK9yQ1dZ0mHP6agQ7H0bTZk8AvX6VC1r9oPQ,10754
248
- letta_client/environment.py,sha256=7ou6ZwDZLBOdYQrHv-1lUk5a1q-HgEwzGlFITiRZ0XU,198
248
+ letta_client/environment.py,sha256=91gYLF9bT4-hTPQ9dcPfmub4LgEl-T4a5kW7NXzRIJU,198
249
249
  letta_client/errors/__init__.py,sha256=wqo3GnyT9iRy7zuPMs6TXOg9GMNfDp4fxq7M8lFFgK8,367
250
250
  letta_client/errors/conflict_error.py,sha256=INHRMcX6i0ywcbZfw-vn3aBoVi06bDjev3p_O8U8IA4,296
251
251
  letta_client/errors/internal_server_error.py,sha256=8USCagXyJJ1MOm9snpcXIUt6eNXvrd_aq7Gfcu1vlOI,268
@@ -689,6 +689,6 @@ letta_client/voice/__init__.py,sha256=ZrZEuXIukVGhsfM-i0dIFfqjeSOBMPeEgDva7Vvnip
689
689
  letta_client/voice/client.py,sha256=2KKJiteGk5HQM79ne1jOPl_ZyUTfZM_gXNdZZ_ndPU8,6485
690
690
  letta_client/voice/types/__init__.py,sha256=hBLJcrom99DkDxxsVRU2ni8kPx6SsCy8gtAJvNOz26w,199
691
691
  letta_client/voice/types/create_voice_chat_completions_request.py,sha256=K4__83rXRCshfdobyAmH-5fUDJQ_PeSQetTUeC4Abk0,381
692
- letta_client-0.1.77.dist-info/METADATA,sha256=PvdfXj-r_Bus9_HKv1zHMjP3h_f_EZ23RRAiq3pPRb0,5041
693
- letta_client-0.1.77.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
694
- letta_client-0.1.77.dist-info/RECORD,,
692
+ letta_client-0.1.79.dist-info/METADATA,sha256=mgRrvp8FBjX9gly_JrDXDmq51_OEeaWLJdMPhmMhgYU,5041
693
+ letta_client-0.1.79.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
694
+ letta_client-0.1.79.dist-info/RECORD,,