letta-client 0.1.76__py3-none-any.whl → 0.1.78__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.76",
19
+ "X-Fern-SDK-Version": "0.1.78",
20
20
  }
21
21
  if self.token is not None:
22
22
  headers["Authorization"] = f"Bearer {self.token}"
@@ -67,7 +67,7 @@ class VoiceClient:
67
67
  )
68
68
  """
69
69
  _response = self._client_wrapper.httpx_client.request(
70
- f"v1/voice/{jsonable_encoder(agent_id)}/chat/completions",
70
+ f"v1/voice-beta/{jsonable_encoder(agent_id)}/chat/completions",
71
71
  method="POST",
72
72
  json=convert_and_respect_annotation_metadata(
73
73
  object_=request, annotation=CreateVoiceChatCompletionsRequest, direction="write"
@@ -158,7 +158,7 @@ class AsyncVoiceClient:
158
158
  asyncio.run(main())
159
159
  """
160
160
  _response = await self._client_wrapper.httpx_client.request(
161
- f"v1/voice/{jsonable_encoder(agent_id)}/chat/completions",
161
+ f"v1/voice-beta/{jsonable_encoder(agent_id)}/chat/completions",
162
162
  method="POST",
163
163
  json=convert_and_respect_annotation_metadata(
164
164
  object_=request, annotation=CreateVoiceChatCompletionsRequest, direction="write"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: letta-client
3
- Version: 0.1.76
3
+ Version: 0.1.78
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=m72yMYtZAntTFfZukyoYaXDvTAGJVmo3uM8ApA5-4Do,1997
237
+ letta_client/core/client_wrapper.py,sha256=JO6fN9Yvpg2o0vMf-HNqjk5yv0wFGsDDnc-w-Rm8MhQ,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
@@ -686,9 +686,9 @@ letta_client/types/web_search_options_user_location.py,sha256=4aXfFcwUBu7YNA5XBj
686
686
  letta_client/types/web_search_options_user_location_approximate.py,sha256=Ywk01J9H67L6_498E5E6ceJ2VbJUfcLiIJWD_s92_M0,731
687
687
  letta_client/version.py,sha256=bttKLbIhO3UonCYQlqs600zzbQgfhCCMjeXR9WRzid4,79
688
688
  letta_client/voice/__init__.py,sha256=ZrZEuXIukVGhsfM-i0dIFfqjeSOBMPeEgDva7VvnipE,167
689
- letta_client/voice/client.py,sha256=O38dLq__WTwLPlFTtvw1hgqaPYK9alds_ft12Bnp5fs,6475
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.76.dist-info/METADATA,sha256=OdjoWoEzRUZMtWIwev_KF6CsvryP-47n8uttllkLbJ4,5041
693
- letta_client-0.1.76.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
694
- letta_client-0.1.76.dist-info/RECORD,,
692
+ letta_client-0.1.78.dist-info/METADATA,sha256=VxRfLmu98Hu1fY_4Gju0oKLYXZUvVp88drgfAQaV78E,5041
693
+ letta_client-0.1.78.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
694
+ letta_client-0.1.78.dist-info/RECORD,,