letta-nightly 0.6.12.dev20250122104013__py3-none-any.whl → 0.6.14.dev20250123041709__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-nightly might be problematic. Click here for more details.
- letta/__init__.py +2 -2
- letta/agent.py +69 -100
- letta/chat_only_agent.py +1 -1
- letta/client/client.py +169 -149
- letta/constants.py +1 -8
- letta/data_sources/connectors.py +1 -1
- letta/functions/helpers.py +29 -4
- letta/functions/schema_generator.py +55 -0
- letta/llm_api/helpers.py +51 -1
- letta/memory.py +9 -7
- letta/orm/agent.py +2 -2
- letta/orm/block.py +3 -1
- letta/orm/custom_columns.py +5 -4
- letta/orm/enums.py +1 -0
- letta/orm/message.py +2 -2
- letta/orm/sqlalchemy_base.py +5 -0
- letta/schemas/agent.py +13 -13
- letta/schemas/block.py +2 -2
- letta/schemas/environment_variables.py +1 -1
- letta/schemas/job.py +1 -1
- letta/schemas/letta_base.py +6 -0
- letta/schemas/letta_message.py +6 -6
- letta/schemas/memory.py +3 -2
- letta/schemas/message.py +21 -13
- letta/schemas/passage.py +1 -1
- letta/schemas/source.py +4 -4
- letta/schemas/tool.py +38 -43
- letta/server/rest_api/app.py +1 -16
- letta/server/rest_api/routers/v1/agents.py +95 -118
- letta/server/rest_api/routers/v1/blocks.py +8 -46
- letta/server/rest_api/routers/v1/jobs.py +4 -4
- letta/server/rest_api/routers/v1/providers.py +2 -2
- letta/server/rest_api/routers/v1/runs.py +6 -6
- letta/server/rest_api/routers/v1/sources.py +8 -38
- letta/server/rest_api/routers/v1/tags.py +1 -1
- letta/server/rest_api/routers/v1/tools.py +6 -24
- letta/server/server.py +6 -6
- letta/services/agent_manager.py +43 -9
- letta/services/block_manager.py +3 -3
- letta/services/job_manager.py +5 -3
- letta/services/organization_manager.py +1 -1
- letta/services/passage_manager.py +3 -3
- letta/services/provider_manager.py +2 -2
- letta/services/sandbox_config_manager.py +2 -2
- letta/services/source_manager.py +3 -3
- letta/services/tool_execution_sandbox.py +3 -1
- letta/services/tool_manager.py +8 -3
- letta/services/user_manager.py +2 -2
- letta/settings.py +29 -0
- letta/system.py +2 -2
- {letta_nightly-0.6.12.dev20250122104013.dist-info → letta_nightly-0.6.14.dev20250123041709.dist-info}/METADATA +1 -1
- {letta_nightly-0.6.12.dev20250122104013.dist-info → letta_nightly-0.6.14.dev20250123041709.dist-info}/RECORD +55 -61
- letta/server/rest_api/routers/openai/__init__.py +0 -0
- letta/server/rest_api/routers/openai/assistants/__init__.py +0 -0
- letta/server/rest_api/routers/openai/assistants/assistants.py +0 -115
- letta/server/rest_api/routers/openai/assistants/schemas.py +0 -115
- letta/server/rest_api/routers/openai/chat_completions/__init__.py +0 -0
- letta/server/rest_api/routers/openai/chat_completions/chat_completions.py +0 -120
- {letta_nightly-0.6.12.dev20250122104013.dist-info → letta_nightly-0.6.14.dev20250123041709.dist-info}/LICENSE +0 -0
- {letta_nightly-0.6.12.dev20250122104013.dist-info → letta_nightly-0.6.14.dev20250123041709.dist-info}/WHEEL +0 -0
- {letta_nightly-0.6.12.dev20250122104013.dist-info → letta_nightly-0.6.14.dev20250123041709.dist-info}/entry_points.txt +0 -0
letta/client/client.py
CHANGED
|
@@ -3,6 +3,7 @@ import time
|
|
|
3
3
|
from typing import Callable, Dict, Generator, List, Optional, Union
|
|
4
4
|
|
|
5
5
|
import requests
|
|
6
|
+
from openai.types.chat.chat_completion_message_tool_call import ChatCompletionMessageToolCall as OpenAIToolCall
|
|
6
7
|
|
|
7
8
|
import letta.utils
|
|
8
9
|
from letta.constants import ADMIN_PREFIX, BASE_MEMORY_TOOLS, BASE_TOOLS, DEFAULT_HUMAN, DEFAULT_PERSONA, FUNCTION_RETURN_CHAR_LIMIT
|
|
@@ -29,7 +30,6 @@ from letta.schemas.llm_config import LLMConfig
|
|
|
29
30
|
from letta.schemas.memory import ArchivalMemorySummary, ChatMemory, CreateArchivalMemory, Memory, RecallMemorySummary
|
|
30
31
|
from letta.schemas.message import Message, MessageCreate, MessageUpdate
|
|
31
32
|
from letta.schemas.openai.chat_completion_response import UsageStatistics
|
|
32
|
-
from letta.schemas.openai.chat_completions import ToolCall
|
|
33
33
|
from letta.schemas.organization import Organization
|
|
34
34
|
from letta.schemas.passage import Passage
|
|
35
35
|
from letta.schemas.run import Run
|
|
@@ -92,19 +92,19 @@ class AbstractClient(object):
|
|
|
92
92
|
):
|
|
93
93
|
raise NotImplementedError
|
|
94
94
|
|
|
95
|
-
def get_tools_from_agent(self, agent_id: str):
|
|
95
|
+
def get_tools_from_agent(self, agent_id: str) -> List[Tool]:
|
|
96
96
|
raise NotImplementedError
|
|
97
97
|
|
|
98
|
-
def
|
|
98
|
+
def attach_tool(self, agent_id: str, tool_id: str) -> AgentState:
|
|
99
99
|
raise NotImplementedError
|
|
100
100
|
|
|
101
|
-
def
|
|
101
|
+
def detach_tool(self, agent_id: str, tool_id: str) -> AgentState:
|
|
102
102
|
raise NotImplementedError
|
|
103
103
|
|
|
104
|
-
def rename_agent(self, agent_id: str, new_name: str):
|
|
104
|
+
def rename_agent(self, agent_id: str, new_name: str) -> AgentState:
|
|
105
105
|
raise NotImplementedError
|
|
106
106
|
|
|
107
|
-
def delete_agent(self, agent_id: str):
|
|
107
|
+
def delete_agent(self, agent_id: str) -> None:
|
|
108
108
|
raise NotImplementedError
|
|
109
109
|
|
|
110
110
|
def get_agent(self, agent_id: str) -> AgentState:
|
|
@@ -218,6 +218,18 @@ class AbstractClient(object):
|
|
|
218
218
|
def get_tool_id(self, name: str) -> Optional[str]:
|
|
219
219
|
raise NotImplementedError
|
|
220
220
|
|
|
221
|
+
def list_attached_tools(self, agent_id: str) -> List[Tool]:
|
|
222
|
+
"""
|
|
223
|
+
List all tools attached to an agent.
|
|
224
|
+
|
|
225
|
+
Args:
|
|
226
|
+
agent_id (str): ID of the agent
|
|
227
|
+
|
|
228
|
+
Returns:
|
|
229
|
+
List[Tool]: A list of attached tools
|
|
230
|
+
"""
|
|
231
|
+
raise NotImplementedError
|
|
232
|
+
|
|
221
233
|
def upsert_base_tools(self) -> List[Tool]:
|
|
222
234
|
raise NotImplementedError
|
|
223
235
|
|
|
@@ -242,10 +254,10 @@ class AbstractClient(object):
|
|
|
242
254
|
def get_source_id(self, source_name: str) -> str:
|
|
243
255
|
raise NotImplementedError
|
|
244
256
|
|
|
245
|
-
def
|
|
257
|
+
def attach_source(self, agent_id: str, source_id: Optional[str] = None, source_name: Optional[str] = None) -> AgentState:
|
|
246
258
|
raise NotImplementedError
|
|
247
259
|
|
|
248
|
-
def
|
|
260
|
+
def detach_source(self, agent_id: str, source_id: Optional[str] = None, source_name: Optional[str] = None) -> AgentState:
|
|
249
261
|
raise NotImplementedError
|
|
250
262
|
|
|
251
263
|
def list_sources(self) -> List[Source]:
|
|
@@ -397,6 +409,26 @@ class AbstractClient(object):
|
|
|
397
409
|
"""
|
|
398
410
|
raise NotImplementedError
|
|
399
411
|
|
|
412
|
+
def attach_block(self, agent_id: str, block_id: str) -> AgentState:
|
|
413
|
+
"""
|
|
414
|
+
Attach a block to an agent.
|
|
415
|
+
|
|
416
|
+
Args:
|
|
417
|
+
agent_id (str): ID of the agent
|
|
418
|
+
block_id (str): ID of the block to attach
|
|
419
|
+
"""
|
|
420
|
+
raise NotImplementedError
|
|
421
|
+
|
|
422
|
+
def detach_block(self, agent_id: str, block_id: str) -> AgentState:
|
|
423
|
+
"""
|
|
424
|
+
Detach a block from an agent.
|
|
425
|
+
|
|
426
|
+
Args:
|
|
427
|
+
agent_id (str): ID of the agent
|
|
428
|
+
block_id (str): ID of the block to detach
|
|
429
|
+
"""
|
|
430
|
+
raise NotImplementedError
|
|
431
|
+
|
|
400
432
|
|
|
401
433
|
class RESTClient(AbstractClient):
|
|
402
434
|
"""
|
|
@@ -554,7 +586,7 @@ class RESTClient(AbstractClient):
|
|
|
554
586
|
# create agent
|
|
555
587
|
create_params = {
|
|
556
588
|
"description": description,
|
|
557
|
-
"
|
|
589
|
+
"metadata": metadata,
|
|
558
590
|
"memory_blocks": [],
|
|
559
591
|
"block_ids": [b.id for b in memory.get_blocks()] + block_ids,
|
|
560
592
|
"tool_ids": tool_ids,
|
|
@@ -599,7 +631,7 @@ class RESTClient(AbstractClient):
|
|
|
599
631
|
role: Optional[MessageRole] = None,
|
|
600
632
|
text: Optional[str] = None,
|
|
601
633
|
name: Optional[str] = None,
|
|
602
|
-
tool_calls: Optional[List[
|
|
634
|
+
tool_calls: Optional[List[OpenAIToolCall]] = None,
|
|
603
635
|
tool_call_id: Optional[str] = None,
|
|
604
636
|
) -> Message:
|
|
605
637
|
request = MessageUpdate(
|
|
@@ -628,7 +660,7 @@ class RESTClient(AbstractClient):
|
|
|
628
660
|
embedding_config: Optional[EmbeddingConfig] = None,
|
|
629
661
|
message_ids: Optional[List[str]] = None,
|
|
630
662
|
tags: Optional[List[str]] = None,
|
|
631
|
-
):
|
|
663
|
+
) -> AgentState:
|
|
632
664
|
"""
|
|
633
665
|
Update an existing agent
|
|
634
666
|
|
|
@@ -653,7 +685,7 @@ class RESTClient(AbstractClient):
|
|
|
653
685
|
tool_ids=tool_ids,
|
|
654
686
|
tags=tags,
|
|
655
687
|
description=description,
|
|
656
|
-
|
|
688
|
+
metadata=metadata,
|
|
657
689
|
llm_config=llm_config,
|
|
658
690
|
embedding_config=embedding_config,
|
|
659
691
|
message_ids=message_ids,
|
|
@@ -678,7 +710,7 @@ class RESTClient(AbstractClient):
|
|
|
678
710
|
raise ValueError(f"Failed to get tools from agents: {response.text}")
|
|
679
711
|
return [Tool(**tool) for tool in response.json()]
|
|
680
712
|
|
|
681
|
-
def
|
|
713
|
+
def attach_tool(self, agent_id: str, tool_id: str) -> AgentState:
|
|
682
714
|
"""
|
|
683
715
|
Add tool to an existing agent
|
|
684
716
|
|
|
@@ -689,12 +721,12 @@ class RESTClient(AbstractClient):
|
|
|
689
721
|
Returns:
|
|
690
722
|
agent_state (AgentState): State of the updated agent
|
|
691
723
|
"""
|
|
692
|
-
response = requests.patch(f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/
|
|
724
|
+
response = requests.patch(f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/tools/attach/{tool_id}", headers=self.headers)
|
|
693
725
|
if response.status_code != 200:
|
|
694
726
|
raise ValueError(f"Failed to update agent: {response.text}")
|
|
695
727
|
return AgentState(**response.json())
|
|
696
728
|
|
|
697
|
-
def
|
|
729
|
+
def detach_tool(self, agent_id: str, tool_id: str) -> AgentState:
|
|
698
730
|
"""
|
|
699
731
|
Removes tools from an existing agent
|
|
700
732
|
|
|
@@ -706,12 +738,12 @@ class RESTClient(AbstractClient):
|
|
|
706
738
|
agent_state (AgentState): State of the updated agent
|
|
707
739
|
"""
|
|
708
740
|
|
|
709
|
-
response = requests.patch(f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/
|
|
741
|
+
response = requests.patch(f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/tools/detach/{tool_id}", headers=self.headers)
|
|
710
742
|
if response.status_code != 200:
|
|
711
743
|
raise ValueError(f"Failed to update agent: {response.text}")
|
|
712
744
|
return AgentState(**response.json())
|
|
713
745
|
|
|
714
|
-
def rename_agent(self, agent_id: str, new_name: str):
|
|
746
|
+
def rename_agent(self, agent_id: str, new_name: str) -> AgentState:
|
|
715
747
|
"""
|
|
716
748
|
Rename an agent
|
|
717
749
|
|
|
@@ -719,10 +751,12 @@ class RESTClient(AbstractClient):
|
|
|
719
751
|
agent_id (str): ID of the agent
|
|
720
752
|
new_name (str): New name for the agent
|
|
721
753
|
|
|
754
|
+
Returns:
|
|
755
|
+
agent_state (AgentState): State of the updated agent
|
|
722
756
|
"""
|
|
723
757
|
return self.update_agent(agent_id, name=new_name)
|
|
724
758
|
|
|
725
|
-
def delete_agent(self, agent_id: str):
|
|
759
|
+
def delete_agent(self, agent_id: str) -> None:
|
|
726
760
|
"""
|
|
727
761
|
Delete an agent
|
|
728
762
|
|
|
@@ -776,7 +810,8 @@ class RESTClient(AbstractClient):
|
|
|
776
810
|
Returns:
|
|
777
811
|
memory (Memory): In-context memory of the agent
|
|
778
812
|
"""
|
|
779
|
-
|
|
813
|
+
|
|
814
|
+
response = requests.get(f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/core-memory", headers=self.headers)
|
|
780
815
|
if response.status_code != 200:
|
|
781
816
|
raise ValueError(f"Failed to get in-context memory: {response.text}")
|
|
782
817
|
return Memory(**response.json())
|
|
@@ -797,7 +832,7 @@ class RESTClient(AbstractClient):
|
|
|
797
832
|
"""
|
|
798
833
|
memory_update_dict = {section: value}
|
|
799
834
|
response = requests.patch(
|
|
800
|
-
f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/memory", json=memory_update_dict, headers=self.headers
|
|
835
|
+
f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/core-memory", json=memory_update_dict, headers=self.headers
|
|
801
836
|
)
|
|
802
837
|
if response.status_code != 200:
|
|
803
838
|
raise ValueError(f"Failed to update in-context memory: {response.text}")
|
|
@@ -814,10 +849,10 @@ class RESTClient(AbstractClient):
|
|
|
814
849
|
summary (ArchivalMemorySummary): Summary of the archival memory
|
|
815
850
|
|
|
816
851
|
"""
|
|
817
|
-
response = requests.get(f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/
|
|
852
|
+
response = requests.get(f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/context", headers=self.headers)
|
|
818
853
|
if response.status_code != 200:
|
|
819
854
|
raise ValueError(f"Failed to get archival memory summary: {response.text}")
|
|
820
|
-
return ArchivalMemorySummary(
|
|
855
|
+
return ArchivalMemorySummary(size=response.json().get("num_archival_memory", 0))
|
|
821
856
|
|
|
822
857
|
def get_recall_memory_summary(self, agent_id: str) -> RecallMemorySummary:
|
|
823
858
|
"""
|
|
@@ -829,10 +864,10 @@ class RESTClient(AbstractClient):
|
|
|
829
864
|
Returns:
|
|
830
865
|
summary (RecallMemorySummary): Summary of the recall memory
|
|
831
866
|
"""
|
|
832
|
-
response = requests.get(f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/
|
|
867
|
+
response = requests.get(f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/context", headers=self.headers)
|
|
833
868
|
if response.status_code != 200:
|
|
834
869
|
raise ValueError(f"Failed to get recall memory summary: {response.text}")
|
|
835
|
-
return RecallMemorySummary(
|
|
870
|
+
return RecallMemorySummary(size=response.json().get("num_recall_memory", 0))
|
|
836
871
|
|
|
837
872
|
def get_in_context_messages(self, agent_id: str) -> List[Message]:
|
|
838
873
|
"""
|
|
@@ -844,10 +879,10 @@ class RESTClient(AbstractClient):
|
|
|
844
879
|
Returns:
|
|
845
880
|
messages (List[Message]): List of in-context messages
|
|
846
881
|
"""
|
|
847
|
-
response = requests.get(f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/
|
|
882
|
+
response = requests.get(f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/context", headers=self.headers)
|
|
848
883
|
if response.status_code != 200:
|
|
849
|
-
raise ValueError(f"Failed to get
|
|
850
|
-
return [Message(**message) for message in response.json()]
|
|
884
|
+
raise ValueError(f"Failed to get recall memory summary: {response.text}")
|
|
885
|
+
return [Message(**message) for message in response.json().get("messages", "")]
|
|
851
886
|
|
|
852
887
|
# agent interactions
|
|
853
888
|
|
|
@@ -889,7 +924,9 @@ class RESTClient(AbstractClient):
|
|
|
889
924
|
params["before"] = str(before)
|
|
890
925
|
if after:
|
|
891
926
|
params["after"] = str(after)
|
|
892
|
-
response = requests.get(
|
|
927
|
+
response = requests.get(
|
|
928
|
+
f"{self.base_url}/{self.api_prefix}/agents/{str(agent_id)}/archival-memory", params=params, headers=self.headers
|
|
929
|
+
)
|
|
893
930
|
assert response.status_code == 200, f"Failed to get archival memory: {response.text}"
|
|
894
931
|
return [Passage(**passage) for passage in response.json()]
|
|
895
932
|
|
|
@@ -906,7 +943,7 @@ class RESTClient(AbstractClient):
|
|
|
906
943
|
"""
|
|
907
944
|
request = CreateArchivalMemory(text=memory)
|
|
908
945
|
response = requests.post(
|
|
909
|
-
f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/archival", headers=self.headers, json=request.model_dump()
|
|
946
|
+
f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/archival-memory", headers=self.headers, json=request.model_dump()
|
|
910
947
|
)
|
|
911
948
|
if response.status_code != 200:
|
|
912
949
|
raise ValueError(f"Failed to insert archival memory: {response.text}")
|
|
@@ -920,7 +957,7 @@ class RESTClient(AbstractClient):
|
|
|
920
957
|
agent_id (str): ID of the agent
|
|
921
958
|
memory_id (str): ID of the memory
|
|
922
959
|
"""
|
|
923
|
-
response = requests.delete(f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/archival/{memory_id}", headers=self.headers)
|
|
960
|
+
response = requests.delete(f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/archival-memory/{memory_id}", headers=self.headers)
|
|
924
961
|
assert response.status_code == 200, f"Failed to delete archival memory: {response.text}"
|
|
925
962
|
|
|
926
963
|
# messages (recall memory)
|
|
@@ -1431,7 +1468,7 @@ class RESTClient(AbstractClient):
|
|
|
1431
1468
|
raise ValueError(f"Failed to update source: {response.text}")
|
|
1432
1469
|
return Source(**response.json())
|
|
1433
1470
|
|
|
1434
|
-
def
|
|
1471
|
+
def attach_source(self, source_id: str, agent_id: str) -> AgentState:
|
|
1435
1472
|
"""
|
|
1436
1473
|
Attach a source to an agent
|
|
1437
1474
|
|
|
@@ -1441,15 +1478,20 @@ class RESTClient(AbstractClient):
|
|
|
1441
1478
|
source_name (str): Name of the source
|
|
1442
1479
|
"""
|
|
1443
1480
|
params = {"agent_id": agent_id}
|
|
1444
|
-
response = requests.
|
|
1481
|
+
response = requests.patch(
|
|
1482
|
+
f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/sources/attach/{source_id}", params=params, headers=self.headers
|
|
1483
|
+
)
|
|
1445
1484
|
assert response.status_code == 200, f"Failed to attach source to agent: {response.text}"
|
|
1485
|
+
return AgentState(**response.json())
|
|
1446
1486
|
|
|
1447
|
-
def detach_source(self, source_id: str, agent_id: str):
|
|
1487
|
+
def detach_source(self, source_id: str, agent_id: str) -> AgentState:
|
|
1448
1488
|
"""Detach a source from an agent"""
|
|
1449
1489
|
params = {"agent_id": str(agent_id)}
|
|
1450
|
-
response = requests.
|
|
1490
|
+
response = requests.patch(
|
|
1491
|
+
f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/sources/detach/{source_id}", params=params, headers=self.headers
|
|
1492
|
+
)
|
|
1451
1493
|
assert response.status_code == 200, f"Failed to detach source from agent: {response.text}"
|
|
1452
|
-
return
|
|
1494
|
+
return AgentState(**response.json())
|
|
1453
1495
|
|
|
1454
1496
|
# tools
|
|
1455
1497
|
|
|
@@ -1463,12 +1505,29 @@ class RESTClient(AbstractClient):
|
|
|
1463
1505
|
Returns:
|
|
1464
1506
|
id (str): ID of the tool (`None` if not found)
|
|
1465
1507
|
"""
|
|
1466
|
-
response = requests.get(f"{self.base_url}/{self.api_prefix}/tools
|
|
1467
|
-
if response.status_code
|
|
1468
|
-
return None
|
|
1469
|
-
elif response.status_code != 200:
|
|
1508
|
+
response = requests.get(f"{self.base_url}/{self.api_prefix}/tools", headers=self.headers)
|
|
1509
|
+
if response.status_code != 200:
|
|
1470
1510
|
raise ValueError(f"Failed to get tool: {response.text}")
|
|
1471
|
-
|
|
1511
|
+
|
|
1512
|
+
tools = [tool for tool in [Tool(**tool) for tool in response.json()] if tool.name == tool_name]
|
|
1513
|
+
if not tools:
|
|
1514
|
+
return None
|
|
1515
|
+
return tools[0].id
|
|
1516
|
+
|
|
1517
|
+
def list_attached_tools(self, agent_id: str) -> List[Tool]:
|
|
1518
|
+
"""
|
|
1519
|
+
List all tools attached to an agent.
|
|
1520
|
+
|
|
1521
|
+
Args:
|
|
1522
|
+
agent_id (str): ID of the agent
|
|
1523
|
+
|
|
1524
|
+
Returns:
|
|
1525
|
+
List[Tool]: A list of attached tools
|
|
1526
|
+
"""
|
|
1527
|
+
response = requests.get(f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/tools", headers=self.headers)
|
|
1528
|
+
if response.status_code != 200:
|
|
1529
|
+
raise ValueError(f"Failed to list attached tools: {response.text}")
|
|
1530
|
+
return [Tool(**tool) for tool in response.json()]
|
|
1472
1531
|
|
|
1473
1532
|
def upsert_base_tools(self) -> List[Tool]:
|
|
1474
1533
|
response = requests.post(f"{self.base_url}/{self.api_prefix}/tools/add-base-tools/", headers=self.headers)
|
|
@@ -1839,68 +1898,38 @@ class RESTClient(AbstractClient):
|
|
|
1839
1898
|
block = self.get_agent_memory_block(agent_id, current_label)
|
|
1840
1899
|
return self.update_block(block.id, label=new_label)
|
|
1841
1900
|
|
|
1842
|
-
|
|
1843
|
-
def add_agent_memory_block(self, agent_id: str, create_block: CreateBlock) -> Memory:
|
|
1844
|
-
"""
|
|
1845
|
-
Create and link a memory block to an agent's core memory
|
|
1846
|
-
|
|
1847
|
-
Args:
|
|
1848
|
-
agent_id (str): The agent ID
|
|
1849
|
-
create_block (CreateBlock): The block to create
|
|
1850
|
-
|
|
1851
|
-
Returns:
|
|
1852
|
-
memory (Memory): The updated memory
|
|
1853
|
-
"""
|
|
1854
|
-
response = requests.post(
|
|
1855
|
-
f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/memory/block",
|
|
1856
|
-
headers=self.headers,
|
|
1857
|
-
json=create_block.model_dump(),
|
|
1858
|
-
)
|
|
1859
|
-
if response.status_code != 200:
|
|
1860
|
-
raise ValueError(f"Failed to add agent memory block: {response.text}")
|
|
1861
|
-
return Memory(**response.json())
|
|
1862
|
-
|
|
1863
|
-
def link_agent_memory_block(self, agent_id: str, block_id: str) -> Memory:
|
|
1901
|
+
def attach_block(self, agent_id: str, block_id: str) -> AgentState:
|
|
1864
1902
|
"""
|
|
1865
|
-
|
|
1903
|
+
Attach a block to an agent.
|
|
1866
1904
|
|
|
1867
1905
|
Args:
|
|
1868
|
-
agent_id (str):
|
|
1869
|
-
block_id (str):
|
|
1870
|
-
|
|
1871
|
-
Returns:
|
|
1872
|
-
memory (Memory): The updated memory
|
|
1906
|
+
agent_id (str): ID of the agent
|
|
1907
|
+
block_id (str): ID of the block to attach
|
|
1873
1908
|
"""
|
|
1874
|
-
params = {"agent_id": agent_id}
|
|
1875
1909
|
response = requests.patch(
|
|
1876
|
-
f"{self.base_url}/{self.api_prefix}/blocks/{block_id}
|
|
1877
|
-
params=params,
|
|
1910
|
+
f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/core-memory/blocks/attach/{block_id}",
|
|
1878
1911
|
headers=self.headers,
|
|
1879
1912
|
)
|
|
1880
1913
|
if response.status_code != 200:
|
|
1881
|
-
raise ValueError(f"Failed to
|
|
1882
|
-
return
|
|
1914
|
+
raise ValueError(f"Failed to attach block to agent: {response.text}")
|
|
1915
|
+
return AgentState(**response.json())
|
|
1883
1916
|
|
|
1884
|
-
def
|
|
1917
|
+
def detach_block(self, agent_id: str, block_id: str) -> AgentState:
|
|
1885
1918
|
"""
|
|
1886
|
-
|
|
1919
|
+
Detach a block from an agent.
|
|
1887
1920
|
|
|
1888
1921
|
Args:
|
|
1889
|
-
agent_id (str):
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
Returns:
|
|
1893
|
-
memory (Memory): The updated memory
|
|
1922
|
+
agent_id (str): ID of the agent
|
|
1923
|
+
block_id (str): ID of the block to detach
|
|
1894
1924
|
"""
|
|
1895
|
-
response = requests.
|
|
1896
|
-
f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/memory/
|
|
1897
|
-
headers=self.headers,
|
|
1925
|
+
response = requests.patch(
|
|
1926
|
+
f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/core-memory/blocks/detach/{block_id}", headers=self.headers
|
|
1898
1927
|
)
|
|
1899
1928
|
if response.status_code != 200:
|
|
1900
|
-
raise ValueError(f"Failed to
|
|
1901
|
-
return
|
|
1929
|
+
raise ValueError(f"Failed to detach block from agent: {response.text}")
|
|
1930
|
+
return AgentState(**response.json())
|
|
1902
1931
|
|
|
1903
|
-
def
|
|
1932
|
+
def list_agent_memory_blocks(self, agent_id: str) -> List[Block]:
|
|
1904
1933
|
"""
|
|
1905
1934
|
Get all the blocks in the agent's core memory
|
|
1906
1935
|
|
|
@@ -1910,7 +1939,7 @@ class RESTClient(AbstractClient):
|
|
|
1910
1939
|
Returns:
|
|
1911
1940
|
blocks (List[Block]): The blocks in the agent's core memory
|
|
1912
1941
|
"""
|
|
1913
|
-
response = requests.get(f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/memory/
|
|
1942
|
+
response = requests.get(f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/core-memory/blocks", headers=self.headers)
|
|
1914
1943
|
if response.status_code != 200:
|
|
1915
1944
|
raise ValueError(f"Failed to get agent memory blocks: {response.text}")
|
|
1916
1945
|
return [Block(**block) for block in response.json()]
|
|
@@ -1927,7 +1956,7 @@ class RESTClient(AbstractClient):
|
|
|
1927
1956
|
block (Block): The block corresponding to the label
|
|
1928
1957
|
"""
|
|
1929
1958
|
response = requests.get(
|
|
1930
|
-
f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/memory/
|
|
1959
|
+
f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/core-memory/blocks/{label}",
|
|
1931
1960
|
headers=self.headers,
|
|
1932
1961
|
)
|
|
1933
1962
|
if response.status_code != 200:
|
|
@@ -1960,7 +1989,7 @@ class RESTClient(AbstractClient):
|
|
|
1960
1989
|
if limit:
|
|
1961
1990
|
data["limit"] = limit
|
|
1962
1991
|
response = requests.patch(
|
|
1963
|
-
f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/memory/
|
|
1992
|
+
f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/core-memory/blocks/{label}",
|
|
1964
1993
|
headers=self.headers,
|
|
1965
1994
|
json=data,
|
|
1966
1995
|
)
|
|
@@ -2303,7 +2332,7 @@ class LocalClient(AbstractClient):
|
|
|
2303
2332
|
# Create the base parameters
|
|
2304
2333
|
create_params = {
|
|
2305
2334
|
"description": description,
|
|
2306
|
-
"
|
|
2335
|
+
"metadata": metadata,
|
|
2307
2336
|
"memory_blocks": [],
|
|
2308
2337
|
"block_ids": [b.id for b in memory.get_blocks()] + block_ids,
|
|
2309
2338
|
"tool_ids": tool_ids,
|
|
@@ -2337,7 +2366,7 @@ class LocalClient(AbstractClient):
|
|
|
2337
2366
|
role: Optional[MessageRole] = None,
|
|
2338
2367
|
text: Optional[str] = None,
|
|
2339
2368
|
name: Optional[str] = None,
|
|
2340
|
-
tool_calls: Optional[List[
|
|
2369
|
+
tool_calls: Optional[List[OpenAIToolCall]] = None,
|
|
2341
2370
|
tool_call_id: Optional[str] = None,
|
|
2342
2371
|
) -> Message:
|
|
2343
2372
|
message = self.server.update_agent_message(
|
|
@@ -2385,7 +2414,7 @@ class LocalClient(AbstractClient):
|
|
|
2385
2414
|
Returns:
|
|
2386
2415
|
agent_state (AgentState): State of the updated agent
|
|
2387
2416
|
"""
|
|
2388
|
-
# TODO: add the
|
|
2417
|
+
# TODO: add the ability to reset linked block_ids
|
|
2389
2418
|
self.interface.clear()
|
|
2390
2419
|
agent_state = self.server.agent_manager.update_agent(
|
|
2391
2420
|
agent_id,
|
|
@@ -2395,7 +2424,7 @@ class LocalClient(AbstractClient):
|
|
|
2395
2424
|
tool_ids=tool_ids,
|
|
2396
2425
|
tags=tags,
|
|
2397
2426
|
description=description,
|
|
2398
|
-
|
|
2427
|
+
metadata=metadata,
|
|
2399
2428
|
llm_config=llm_config,
|
|
2400
2429
|
embedding_config=embedding_config,
|
|
2401
2430
|
message_ids=message_ids,
|
|
@@ -2417,7 +2446,7 @@ class LocalClient(AbstractClient):
|
|
|
2417
2446
|
self.interface.clear()
|
|
2418
2447
|
return self.server.agent_manager.get_agent_by_id(agent_id=agent_id, actor=self.user).tools
|
|
2419
2448
|
|
|
2420
|
-
def
|
|
2449
|
+
def attach_tool(self, agent_id: str, tool_id: str) -> AgentState:
|
|
2421
2450
|
"""
|
|
2422
2451
|
Add tool to an existing agent
|
|
2423
2452
|
|
|
@@ -2432,7 +2461,7 @@ class LocalClient(AbstractClient):
|
|
|
2432
2461
|
agent_state = self.server.agent_manager.attach_tool(agent_id=agent_id, tool_id=tool_id, actor=self.user)
|
|
2433
2462
|
return agent_state
|
|
2434
2463
|
|
|
2435
|
-
def
|
|
2464
|
+
def detach_tool(self, agent_id: str, tool_id: str) -> AgentState:
|
|
2436
2465
|
"""
|
|
2437
2466
|
Removes tools from an existing agent
|
|
2438
2467
|
|
|
@@ -2447,17 +2476,20 @@ class LocalClient(AbstractClient):
|
|
|
2447
2476
|
agent_state = self.server.agent_manager.detach_tool(agent_id=agent_id, tool_id=tool_id, actor=self.user)
|
|
2448
2477
|
return agent_state
|
|
2449
2478
|
|
|
2450
|
-
def rename_agent(self, agent_id: str, new_name: str):
|
|
2479
|
+
def rename_agent(self, agent_id: str, new_name: str) -> AgentState:
|
|
2451
2480
|
"""
|
|
2452
2481
|
Rename an agent
|
|
2453
2482
|
|
|
2454
2483
|
Args:
|
|
2455
2484
|
agent_id (str): ID of the agent
|
|
2456
2485
|
new_name (str): New name for the agent
|
|
2486
|
+
|
|
2487
|
+
Returns:
|
|
2488
|
+
agent_state (AgentState): State of the updated agent
|
|
2457
2489
|
"""
|
|
2458
|
-
self.update_agent(agent_id, name=new_name)
|
|
2490
|
+
return self.update_agent(agent_id, name=new_name)
|
|
2459
2491
|
|
|
2460
|
-
def delete_agent(self, agent_id: str):
|
|
2492
|
+
def delete_agent(self, agent_id: str) -> None:
|
|
2461
2493
|
"""
|
|
2462
2494
|
Delete an agent
|
|
2463
2495
|
|
|
@@ -2870,7 +2902,7 @@ class LocalClient(AbstractClient):
|
|
|
2870
2902
|
|
|
2871
2903
|
def load_composio_tool(self, action: "ActionType") -> Tool:
|
|
2872
2904
|
tool_create = ToolCreate.from_composio(action_name=action.name)
|
|
2873
|
-
return self.server.tool_manager.
|
|
2905
|
+
return self.server.tool_manager.create_or_update_composio_tool(pydantic_tool=Tool(**tool_create.model_dump()), actor=self.user)
|
|
2874
2906
|
|
|
2875
2907
|
def create_tool(
|
|
2876
2908
|
self,
|
|
@@ -3032,6 +3064,18 @@ class LocalClient(AbstractClient):
|
|
|
3032
3064
|
tool = self.server.tool_manager.get_tool_by_name(tool_name=name, actor=self.user)
|
|
3033
3065
|
return tool.id if tool else None
|
|
3034
3066
|
|
|
3067
|
+
def list_attached_tools(self, agent_id: str) -> List[Tool]:
|
|
3068
|
+
"""
|
|
3069
|
+
List all tools attached to an agent.
|
|
3070
|
+
|
|
3071
|
+
Args:
|
|
3072
|
+
agent_id (str): ID of the agent
|
|
3073
|
+
|
|
3074
|
+
Returns:
|
|
3075
|
+
List[Tool]: List of tools attached to the agent
|
|
3076
|
+
"""
|
|
3077
|
+
return self.server.agent_manager.list_attached_tools(agent_id=agent_id, actor=self.user)
|
|
3078
|
+
|
|
3035
3079
|
def load_data(self, connector: DataConnector, source_name: str):
|
|
3036
3080
|
"""
|
|
3037
3081
|
Load data into a source
|
|
@@ -3057,7 +3101,7 @@ class LocalClient(AbstractClient):
|
|
|
3057
3101
|
job = Job(
|
|
3058
3102
|
user_id=self.user_id,
|
|
3059
3103
|
status=JobStatus.created,
|
|
3060
|
-
|
|
3104
|
+
metadata={"type": "embedding", "filename": filename, "source_id": source_id},
|
|
3061
3105
|
)
|
|
3062
3106
|
job = self.server.job_manager.create_job(pydantic_job=job, actor=self.user)
|
|
3063
3107
|
|
|
@@ -3065,14 +3109,14 @@ class LocalClient(AbstractClient):
|
|
|
3065
3109
|
self.server.load_file_to_source(source_id=source_id, file_path=filename, job_id=job.id, actor=self.user)
|
|
3066
3110
|
return job
|
|
3067
3111
|
|
|
3068
|
-
def delete_file_from_source(self, source_id: str, file_id: str):
|
|
3112
|
+
def delete_file_from_source(self, source_id: str, file_id: str) -> None:
|
|
3069
3113
|
self.server.source_manager.delete_file(file_id, actor=self.user)
|
|
3070
3114
|
|
|
3071
3115
|
def get_job(self, job_id: str):
|
|
3072
3116
|
return self.server.job_manager.get_job_by_id(job_id=job_id, actor=self.user)
|
|
3073
3117
|
|
|
3074
3118
|
def delete_job(self, job_id: str):
|
|
3075
|
-
return self.server.job_manager.
|
|
3119
|
+
return self.server.job_manager.delete_job_by_id(job_id=job_id, actor=self.user)
|
|
3076
3120
|
|
|
3077
3121
|
def list_jobs(self):
|
|
3078
3122
|
return self.server.job_manager.list_jobs(actor=self.user)
|
|
@@ -3131,7 +3175,7 @@ class LocalClient(AbstractClient):
|
|
|
3131
3175
|
"""
|
|
3132
3176
|
return self.server.source_manager.get_source_by_name(source_name=source_name, actor=self.user).id
|
|
3133
3177
|
|
|
3134
|
-
def
|
|
3178
|
+
def attach_source(self, agent_id: str, source_id: Optional[str] = None, source_name: Optional[str] = None) -> AgentState:
|
|
3135
3179
|
"""
|
|
3136
3180
|
Attach a source to an agent
|
|
3137
3181
|
|
|
@@ -3144,9 +3188,9 @@ class LocalClient(AbstractClient):
|
|
|
3144
3188
|
source = self.server.source_manager.get_source_by_id(source_id=source_id, actor=self.user)
|
|
3145
3189
|
source_id = source.id
|
|
3146
3190
|
|
|
3147
|
-
self.server.agent_manager.attach_source(source_id=source_id, agent_id=agent_id, actor=self.user)
|
|
3191
|
+
return self.server.agent_manager.attach_source(source_id=source_id, agent_id=agent_id, actor=self.user)
|
|
3148
3192
|
|
|
3149
|
-
def
|
|
3193
|
+
def detach_source(self, agent_id: str, source_id: Optional[str] = None, source_name: Optional[str] = None) -> AgentState:
|
|
3150
3194
|
"""
|
|
3151
3195
|
Detach a source from an agent by removing all `Passage` objects that were loaded from the source from archival memory.
|
|
3152
3196
|
Args:
|
|
@@ -3479,50 +3523,6 @@ class LocalClient(AbstractClient):
|
|
|
3479
3523
|
block = self.get_agent_memory_block(agent_id, current_label)
|
|
3480
3524
|
return self.update_block(block.id, label=new_label)
|
|
3481
3525
|
|
|
3482
|
-
# TODO: remove this
|
|
3483
|
-
def add_agent_memory_block(self, agent_id: str, create_block: CreateBlock) -> Memory:
|
|
3484
|
-
"""
|
|
3485
|
-
Create and link a memory block to an agent's core memory
|
|
3486
|
-
|
|
3487
|
-
Args:
|
|
3488
|
-
agent_id (str): The agent ID
|
|
3489
|
-
create_block (CreateBlock): The block to create
|
|
3490
|
-
|
|
3491
|
-
Returns:
|
|
3492
|
-
memory (Memory): The updated memory
|
|
3493
|
-
"""
|
|
3494
|
-
block_req = Block(**create_block.model_dump())
|
|
3495
|
-
block = self.server.block_manager.create_or_update_block(actor=self.user, block=block_req)
|
|
3496
|
-
# Link the block to the agent
|
|
3497
|
-
agent = self.server.agent_manager.attach_block(agent_id=agent_id, block_id=block.id, actor=self.user)
|
|
3498
|
-
return agent.memory
|
|
3499
|
-
|
|
3500
|
-
def link_agent_memory_block(self, agent_id: str, block_id: str) -> Memory:
|
|
3501
|
-
"""
|
|
3502
|
-
Link a block to an agent's core memory
|
|
3503
|
-
|
|
3504
|
-
Args:
|
|
3505
|
-
agent_id (str): The agent ID
|
|
3506
|
-
block_id (str): The block ID
|
|
3507
|
-
|
|
3508
|
-
Returns:
|
|
3509
|
-
memory (Memory): The updated memory
|
|
3510
|
-
"""
|
|
3511
|
-
return self.server.agent_manager.attach_block(agent_id=agent_id, block_id=block_id, actor=self.user)
|
|
3512
|
-
|
|
3513
|
-
def remove_agent_memory_block(self, agent_id: str, block_label: str) -> Memory:
|
|
3514
|
-
"""
|
|
3515
|
-
Unlike a block from the agent's core memory
|
|
3516
|
-
|
|
3517
|
-
Args:
|
|
3518
|
-
agent_id (str): The agent ID
|
|
3519
|
-
block_label (str): The block label
|
|
3520
|
-
|
|
3521
|
-
Returns:
|
|
3522
|
-
memory (Memory): The updated memory
|
|
3523
|
-
"""
|
|
3524
|
-
return self.server.agent_manager.detach_block_with_label(agent_id=agent_id, block_label=block_label, actor=self.user)
|
|
3525
|
-
|
|
3526
3526
|
def get_agent_memory_blocks(self, agent_id: str) -> List[Block]:
|
|
3527
3527
|
"""
|
|
3528
3528
|
Get all the blocks in the agent's core memory
|
|
@@ -3604,6 +3604,26 @@ class LocalClient(AbstractClient):
|
|
|
3604
3604
|
data["label"] = label
|
|
3605
3605
|
return self.server.block_manager.update_block(block_id, actor=self.user, block_update=BlockUpdate(**data))
|
|
3606
3606
|
|
|
3607
|
+
def attach_block(self, agent_id: str, block_id: str) -> AgentState:
|
|
3608
|
+
"""
|
|
3609
|
+
Attach a block to an agent.
|
|
3610
|
+
|
|
3611
|
+
Args:
|
|
3612
|
+
agent_id (str): ID of the agent
|
|
3613
|
+
block_id (str): ID of the block to attach
|
|
3614
|
+
"""
|
|
3615
|
+
return self.server.agent_manager.attach_block(agent_id=agent_id, block_id=block_id, actor=self.user)
|
|
3616
|
+
|
|
3617
|
+
def detach_block(self, agent_id: str, block_id: str) -> AgentState:
|
|
3618
|
+
"""
|
|
3619
|
+
Detach a block from an agent.
|
|
3620
|
+
|
|
3621
|
+
Args:
|
|
3622
|
+
agent_id (str): ID of the agent
|
|
3623
|
+
block_id (str): ID of the block to detach
|
|
3624
|
+
"""
|
|
3625
|
+
return self.server.agent_manager.detach_block(agent_id=agent_id, block_id=block_id, actor=self.user)
|
|
3626
|
+
|
|
3607
3627
|
def get_run_messages(
|
|
3608
3628
|
self,
|
|
3609
3629
|
run_id: str,
|