letta-nightly 0.5.5.dev20241122170833__py3-none-any.whl → 0.6.0.dev20241204051808__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 +155 -166
- letta/agent_store/chroma.py +2 -0
- letta/agent_store/db.py +1 -1
- letta/cli/cli.py +12 -8
- letta/cli/cli_config.py +1 -1
- letta/client/client.py +765 -137
- letta/config.py +2 -2
- letta/constants.py +10 -14
- letta/errors.py +12 -0
- letta/functions/function_sets/base.py +38 -1
- letta/functions/functions.py +40 -57
- letta/functions/helpers.py +0 -4
- letta/functions/schema_generator.py +279 -18
- letta/helpers/tool_rule_solver.py +6 -5
- letta/llm_api/helpers.py +99 -5
- letta/llm_api/openai.py +8 -2
- letta/local_llm/utils.py +13 -6
- letta/log.py +7 -9
- letta/main.py +1 -1
- letta/metadata.py +53 -38
- letta/o1_agent.py +1 -4
- letta/orm/__init__.py +2 -0
- letta/orm/block.py +7 -3
- letta/orm/blocks_agents.py +32 -0
- letta/orm/errors.py +8 -0
- letta/orm/mixins.py +8 -0
- letta/orm/organization.py +8 -1
- letta/orm/sandbox_config.py +56 -0
- letta/orm/sqlalchemy_base.py +68 -10
- letta/persistence_manager.py +1 -0
- letta/schemas/agent.py +57 -52
- letta/schemas/block.py +85 -26
- letta/schemas/blocks_agents.py +32 -0
- letta/schemas/enums.py +14 -0
- letta/schemas/letta_base.py +10 -1
- letta/schemas/letta_request.py +11 -23
- letta/schemas/letta_response.py +1 -2
- letta/schemas/memory.py +41 -76
- letta/schemas/message.py +3 -3
- letta/schemas/sandbox_config.py +114 -0
- letta/schemas/tool.py +37 -1
- letta/schemas/tool_rule.py +13 -5
- letta/server/rest_api/app.py +5 -4
- letta/server/rest_api/interface.py +12 -19
- letta/server/rest_api/routers/openai/assistants/threads.py +2 -3
- letta/server/rest_api/routers/openai/chat_completions/chat_completions.py +0 -2
- letta/server/rest_api/routers/v1/__init__.py +4 -9
- letta/server/rest_api/routers/v1/agents.py +145 -61
- letta/server/rest_api/routers/v1/blocks.py +50 -5
- letta/server/rest_api/routers/v1/sandbox_configs.py +127 -0
- letta/server/rest_api/routers/v1/sources.py +8 -1
- letta/server/rest_api/routers/v1/tools.py +139 -13
- letta/server/rest_api/utils.py +6 -0
- letta/server/server.py +397 -340
- letta/server/static_files/assets/index-9fa459a2.js +1 -1
- letta/services/block_manager.py +23 -2
- letta/services/blocks_agents_manager.py +106 -0
- letta/services/per_agent_lock_manager.py +18 -0
- letta/services/sandbox_config_manager.py +256 -0
- letta/services/tool_execution_sandbox.py +352 -0
- letta/services/tool_manager.py +16 -22
- letta/services/tool_sandbox_env/.gitkeep +0 -0
- letta/settings.py +4 -0
- letta/utils.py +0 -7
- {letta_nightly-0.5.5.dev20241122170833.dist-info → letta_nightly-0.6.0.dev20241204051808.dist-info}/METADATA +8 -6
- {letta_nightly-0.5.5.dev20241122170833.dist-info → letta_nightly-0.6.0.dev20241204051808.dist-info}/RECORD +70 -60
- {letta_nightly-0.5.5.dev20241122170833.dist-info → letta_nightly-0.6.0.dev20241204051808.dist-info}/LICENSE +0 -0
- {letta_nightly-0.5.5.dev20241122170833.dist-info → letta_nightly-0.6.0.dev20241204051808.dist-info}/WHEEL +0 -0
- {letta_nightly-0.5.5.dev20241122170833.dist-info → letta_nightly-0.6.0.dev20241204051808.dist-info}/entry_points.txt +0 -0
letta/client/client.py
CHANGED
|
@@ -5,20 +5,17 @@ from typing import Callable, Dict, Generator, List, Optional, Union
|
|
|
5
5
|
import requests
|
|
6
6
|
|
|
7
7
|
import letta.utils
|
|
8
|
-
from letta.constants import
|
|
8
|
+
from letta.constants import (
|
|
9
|
+
ADMIN_PREFIX,
|
|
10
|
+
BASE_MEMORY_TOOLS,
|
|
11
|
+
BASE_TOOLS,
|
|
12
|
+
DEFAULT_HUMAN,
|
|
13
|
+
DEFAULT_PERSONA,
|
|
14
|
+
)
|
|
9
15
|
from letta.data_sources.connectors import DataConnector
|
|
10
16
|
from letta.functions.functions import parse_source_code
|
|
11
|
-
from letta.memory import get_memory_functions
|
|
12
17
|
from letta.schemas.agent import AgentState, AgentType, CreateAgent, UpdateAgentState
|
|
13
|
-
from letta.schemas.block import
|
|
14
|
-
Block,
|
|
15
|
-
BlockCreate,
|
|
16
|
-
BlockUpdate,
|
|
17
|
-
Human,
|
|
18
|
-
Persona,
|
|
19
|
-
UpdateHuman,
|
|
20
|
-
UpdatePersona,
|
|
21
|
-
)
|
|
18
|
+
from letta.schemas.block import Block, BlockUpdate, CreateBlock, Human, Persona
|
|
22
19
|
from letta.schemas.embedding_config import EmbeddingConfig
|
|
23
20
|
|
|
24
21
|
# new schemas
|
|
@@ -39,6 +36,16 @@ from letta.schemas.message import Message, MessageCreate, UpdateMessage
|
|
|
39
36
|
from letta.schemas.openai.chat_completions import ToolCall
|
|
40
37
|
from letta.schemas.organization import Organization
|
|
41
38
|
from letta.schemas.passage import Passage
|
|
39
|
+
from letta.schemas.sandbox_config import (
|
|
40
|
+
E2BSandboxConfig,
|
|
41
|
+
LocalSandboxConfig,
|
|
42
|
+
SandboxConfig,
|
|
43
|
+
SandboxConfigCreate,
|
|
44
|
+
SandboxConfigUpdate,
|
|
45
|
+
SandboxEnvironmentVariable,
|
|
46
|
+
SandboxEnvironmentVariableCreate,
|
|
47
|
+
SandboxEnvironmentVariableUpdate,
|
|
48
|
+
)
|
|
42
49
|
from letta.schemas.source import Source, SourceCreate, SourceUpdate
|
|
43
50
|
from letta.schemas.tool import Tool, ToolCreate, ToolUpdate
|
|
44
51
|
from letta.schemas.tool_rule import BaseToolRule
|
|
@@ -72,7 +79,7 @@ class AbstractClient(object):
|
|
|
72
79
|
agent_type: Optional[AgentType] = AgentType.memgpt_agent,
|
|
73
80
|
embedding_config: Optional[EmbeddingConfig] = None,
|
|
74
81
|
llm_config: Optional[LLMConfig] = None,
|
|
75
|
-
memory
|
|
82
|
+
memory=None,
|
|
76
83
|
system: Optional[str] = None,
|
|
77
84
|
tools: Optional[List[str]] = None,
|
|
78
85
|
tool_rules: Optional[List[BaseToolRule]] = None,
|
|
@@ -144,11 +151,10 @@ class AbstractClient(object):
|
|
|
144
151
|
stream: Optional[bool] = False,
|
|
145
152
|
stream_steps: bool = False,
|
|
146
153
|
stream_tokens: bool = False,
|
|
147
|
-
include_full_message: Optional[bool] = False,
|
|
148
154
|
) -> LettaResponse:
|
|
149
155
|
raise NotImplementedError
|
|
150
156
|
|
|
151
|
-
def user_message(self, agent_id: str, message: str
|
|
157
|
+
def user_message(self, agent_id: str, message: str) -> LettaResponse:
|
|
152
158
|
raise NotImplementedError
|
|
153
159
|
|
|
154
160
|
def create_human(self, name: str, text: str) -> Human:
|
|
@@ -201,6 +207,14 @@ class AbstractClient(object):
|
|
|
201
207
|
) -> Tool:
|
|
202
208
|
raise NotImplementedError
|
|
203
209
|
|
|
210
|
+
def create_or_update_tool(
|
|
211
|
+
self,
|
|
212
|
+
func,
|
|
213
|
+
name: Optional[str] = None,
|
|
214
|
+
tags: Optional[List[str]] = None,
|
|
215
|
+
) -> Tool:
|
|
216
|
+
raise NotImplementedError
|
|
217
|
+
|
|
204
218
|
def update_tool(
|
|
205
219
|
self,
|
|
206
220
|
id: str,
|
|
@@ -296,6 +310,112 @@ class AbstractClient(object):
|
|
|
296
310
|
def delete_org(self, org_id: str) -> Organization:
|
|
297
311
|
raise NotImplementedError
|
|
298
312
|
|
|
313
|
+
def create_sandbox_config(self, config: Union[LocalSandboxConfig, E2BSandboxConfig]) -> SandboxConfig:
|
|
314
|
+
"""
|
|
315
|
+
Create a new sandbox configuration.
|
|
316
|
+
|
|
317
|
+
Args:
|
|
318
|
+
config (Union[LocalSandboxConfig, E2BSandboxConfig]): The sandbox settings.
|
|
319
|
+
|
|
320
|
+
Returns:
|
|
321
|
+
SandboxConfig: The created sandbox configuration.
|
|
322
|
+
"""
|
|
323
|
+
raise NotImplementedError
|
|
324
|
+
|
|
325
|
+
def update_sandbox_config(self, sandbox_config_id: str, config: Union[LocalSandboxConfig, E2BSandboxConfig]) -> SandboxConfig:
|
|
326
|
+
"""
|
|
327
|
+
Update an existing sandbox configuration.
|
|
328
|
+
|
|
329
|
+
Args:
|
|
330
|
+
sandbox_config_id (str): The ID of the sandbox configuration to update.
|
|
331
|
+
config (Union[LocalSandboxConfig, E2BSandboxConfig]): The updated sandbox settings.
|
|
332
|
+
|
|
333
|
+
Returns:
|
|
334
|
+
SandboxConfig: The updated sandbox configuration.
|
|
335
|
+
"""
|
|
336
|
+
raise NotImplementedError
|
|
337
|
+
|
|
338
|
+
def delete_sandbox_config(self, sandbox_config_id: str) -> None:
|
|
339
|
+
"""
|
|
340
|
+
Delete a sandbox configuration.
|
|
341
|
+
|
|
342
|
+
Args:
|
|
343
|
+
sandbox_config_id (str): The ID of the sandbox configuration to delete.
|
|
344
|
+
"""
|
|
345
|
+
raise NotImplementedError
|
|
346
|
+
|
|
347
|
+
def list_sandbox_configs(self, limit: int = 50, cursor: Optional[str] = None) -> List[SandboxConfig]:
|
|
348
|
+
"""
|
|
349
|
+
List all sandbox configurations.
|
|
350
|
+
|
|
351
|
+
Args:
|
|
352
|
+
limit (int, optional): The maximum number of sandbox configurations to return. Defaults to 50.
|
|
353
|
+
cursor (Optional[str], optional): The pagination cursor for retrieving the next set of results.
|
|
354
|
+
|
|
355
|
+
Returns:
|
|
356
|
+
List[SandboxConfig]: A list of sandbox configurations.
|
|
357
|
+
"""
|
|
358
|
+
raise NotImplementedError
|
|
359
|
+
|
|
360
|
+
def create_sandbox_env_var(
|
|
361
|
+
self, sandbox_config_id: str, key: str, value: str, description: Optional[str] = None
|
|
362
|
+
) -> SandboxEnvironmentVariable:
|
|
363
|
+
"""
|
|
364
|
+
Create a new environment variable for a sandbox configuration.
|
|
365
|
+
|
|
366
|
+
Args:
|
|
367
|
+
sandbox_config_id (str): The ID of the sandbox configuration to associate the environment variable with.
|
|
368
|
+
key (str): The name of the environment variable.
|
|
369
|
+
value (str): The value of the environment variable.
|
|
370
|
+
description (Optional[str], optional): A description of the environment variable. Defaults to None.
|
|
371
|
+
|
|
372
|
+
Returns:
|
|
373
|
+
SandboxEnvironmentVariable: The created environment variable.
|
|
374
|
+
"""
|
|
375
|
+
raise NotImplementedError
|
|
376
|
+
|
|
377
|
+
def update_sandbox_env_var(
|
|
378
|
+
self, env_var_id: str, key: Optional[str] = None, value: Optional[str] = None, description: Optional[str] = None
|
|
379
|
+
) -> SandboxEnvironmentVariable:
|
|
380
|
+
"""
|
|
381
|
+
Update an existing environment variable.
|
|
382
|
+
|
|
383
|
+
Args:
|
|
384
|
+
env_var_id (str): The ID of the environment variable to update.
|
|
385
|
+
key (Optional[str], optional): The updated name of the environment variable. Defaults to None.
|
|
386
|
+
value (Optional[str], optional): The updated value of the environment variable. Defaults to None.
|
|
387
|
+
description (Optional[str], optional): The updated description of the environment variable. Defaults to None.
|
|
388
|
+
|
|
389
|
+
Returns:
|
|
390
|
+
SandboxEnvironmentVariable: The updated environment variable.
|
|
391
|
+
"""
|
|
392
|
+
raise NotImplementedError
|
|
393
|
+
|
|
394
|
+
def delete_sandbox_env_var(self, env_var_id: str) -> None:
|
|
395
|
+
"""
|
|
396
|
+
Delete an environment variable by its ID.
|
|
397
|
+
|
|
398
|
+
Args:
|
|
399
|
+
env_var_id (str): The ID of the environment variable to delete.
|
|
400
|
+
"""
|
|
401
|
+
raise NotImplementedError
|
|
402
|
+
|
|
403
|
+
def list_sandbox_env_vars(
|
|
404
|
+
self, sandbox_config_id: str, limit: int = 50, cursor: Optional[str] = None
|
|
405
|
+
) -> List[SandboxEnvironmentVariable]:
|
|
406
|
+
"""
|
|
407
|
+
List all environment variables associated with a sandbox configuration.
|
|
408
|
+
|
|
409
|
+
Args:
|
|
410
|
+
sandbox_config_id (str): The ID of the sandbox configuration to retrieve environment variables for.
|
|
411
|
+
limit (int, optional): The maximum number of environment variables to return. Defaults to 50.
|
|
412
|
+
cursor (Optional[str], optional): The pagination cursor for retrieving the next set of results.
|
|
413
|
+
|
|
414
|
+
Returns:
|
|
415
|
+
List[SandboxEnvironmentVariable]: A list of environment variables.
|
|
416
|
+
"""
|
|
417
|
+
raise NotImplementedError
|
|
418
|
+
|
|
299
419
|
|
|
300
420
|
class RESTClient(AbstractClient):
|
|
301
421
|
"""
|
|
@@ -314,6 +434,7 @@ class RESTClient(AbstractClient):
|
|
|
314
434
|
debug: bool = False,
|
|
315
435
|
default_llm_config: Optional[LLMConfig] = None,
|
|
316
436
|
default_embedding_config: Optional[EmbeddingConfig] = None,
|
|
437
|
+
headers: Optional[Dict] = None,
|
|
317
438
|
):
|
|
318
439
|
"""
|
|
319
440
|
Initializes a new instance of Client class.
|
|
@@ -322,12 +443,16 @@ class RESTClient(AbstractClient):
|
|
|
322
443
|
auto_save (bool): Whether to automatically save changes.
|
|
323
444
|
user_id (str): The user ID.
|
|
324
445
|
debug (bool): Whether to print debug information.
|
|
325
|
-
default
|
|
446
|
+
default_llm_config (Optional[LLMConfig]): The default LLM configuration.
|
|
447
|
+
default_embedding_config (Optional[EmbeddingConfig]): The default embedding configuration.
|
|
448
|
+
headers (Optional[Dict]): The additional headers for the REST API.
|
|
326
449
|
"""
|
|
327
450
|
super().__init__(debug=debug)
|
|
328
451
|
self.base_url = base_url
|
|
329
452
|
self.api_prefix = api_prefix
|
|
330
453
|
self.headers = {"accept": "application/json", "authorization": f"Bearer {token}"}
|
|
454
|
+
if headers:
|
|
455
|
+
self.headers.update(headers)
|
|
331
456
|
self._default_llm_config = default_llm_config
|
|
332
457
|
self._default_embedding_config = default_embedding_config
|
|
333
458
|
|
|
@@ -399,27 +524,13 @@ class RESTClient(AbstractClient):
|
|
|
399
524
|
Returns:
|
|
400
525
|
agent_state (AgentState): State of the created agent
|
|
401
526
|
"""
|
|
402
|
-
|
|
403
|
-
# TODO: implement this check once name lookup works
|
|
404
|
-
# if name:
|
|
405
|
-
# exist_agent_id = self.get_agent_id(agent_name=name)
|
|
406
|
-
|
|
407
|
-
# raise ValueError(f"Agent with name {name} already exists")
|
|
408
|
-
|
|
409
|
-
# construct list of tools
|
|
410
527
|
tool_names = []
|
|
411
528
|
if tools:
|
|
412
529
|
tool_names += tools
|
|
413
530
|
if include_base_tools:
|
|
414
531
|
tool_names += BASE_TOOLS
|
|
532
|
+
tool_names += BASE_MEMORY_TOOLS
|
|
415
533
|
|
|
416
|
-
# add memory tools
|
|
417
|
-
memory_functions = get_memory_functions(memory)
|
|
418
|
-
for func_name, func in memory_functions.items():
|
|
419
|
-
tool = self.create_tool(func, name=func_name, tags=["memory", "letta-base"])
|
|
420
|
-
tool_names.append(tool.name)
|
|
421
|
-
|
|
422
|
-
# check if default configs are provided
|
|
423
534
|
assert embedding_config or self._default_embedding_config, f"Embedding config must be provided"
|
|
424
535
|
assert llm_config or self._default_llm_config, f"LLM config must be provided"
|
|
425
536
|
|
|
@@ -428,7 +539,7 @@ class RESTClient(AbstractClient):
|
|
|
428
539
|
name=name,
|
|
429
540
|
description=description,
|
|
430
541
|
metadata_=metadata,
|
|
431
|
-
|
|
542
|
+
memory_blocks=[],
|
|
432
543
|
tools=tool_names,
|
|
433
544
|
tool_rules=tool_rules,
|
|
434
545
|
system=system,
|
|
@@ -450,7 +561,20 @@ class RESTClient(AbstractClient):
|
|
|
450
561
|
|
|
451
562
|
if response.status_code != 200:
|
|
452
563
|
raise ValueError(f"Status {response.status_code} - Failed to create agent: {response.text}")
|
|
453
|
-
|
|
564
|
+
|
|
565
|
+
# gather agent state
|
|
566
|
+
agent_state = AgentState(**response.json())
|
|
567
|
+
|
|
568
|
+
# create and link blocks
|
|
569
|
+
for block in memory.get_blocks():
|
|
570
|
+
if not self.get_block(block.id):
|
|
571
|
+
# note: this does not update existing blocks
|
|
572
|
+
# WARNING: this resets the block ID - this method is a hack for backwards compat, should eventually use CreateBlock not Memory
|
|
573
|
+
block = self.create_block(label=block.label, value=block.value, limit=block.limit)
|
|
574
|
+
self.link_agent_memory_block(agent_id=agent_state.id, block_id=block.id)
|
|
575
|
+
|
|
576
|
+
# refresh and return agent
|
|
577
|
+
return self.get_agent(agent_state.id)
|
|
454
578
|
|
|
455
579
|
def update_message(
|
|
456
580
|
self,
|
|
@@ -483,12 +607,11 @@ class RESTClient(AbstractClient):
|
|
|
483
607
|
name: Optional[str] = None,
|
|
484
608
|
description: Optional[str] = None,
|
|
485
609
|
system: Optional[str] = None,
|
|
486
|
-
|
|
610
|
+
tool_names: Optional[List[str]] = None,
|
|
487
611
|
metadata: Optional[Dict] = None,
|
|
488
612
|
llm_config: Optional[LLMConfig] = None,
|
|
489
613
|
embedding_config: Optional[EmbeddingConfig] = None,
|
|
490
614
|
message_ids: Optional[List[str]] = None,
|
|
491
|
-
memory: Optional[Memory] = None,
|
|
492
615
|
tags: Optional[List[str]] = None,
|
|
493
616
|
):
|
|
494
617
|
"""
|
|
@@ -499,12 +622,11 @@ class RESTClient(AbstractClient):
|
|
|
499
622
|
name (str): Name of the agent
|
|
500
623
|
description (str): Description of the agent
|
|
501
624
|
system (str): System configuration
|
|
502
|
-
|
|
625
|
+
tool_names (List[str]): List of tools
|
|
503
626
|
metadata (Dict): Metadata
|
|
504
627
|
llm_config (LLMConfig): LLM configuration
|
|
505
628
|
embedding_config (EmbeddingConfig): Embedding configuration
|
|
506
629
|
message_ids (List[str]): List of message IDs
|
|
507
|
-
memory (Memory): Memory configuration
|
|
508
630
|
tags (List[str]): Tags for filtering agents
|
|
509
631
|
|
|
510
632
|
Returns:
|
|
@@ -514,14 +636,13 @@ class RESTClient(AbstractClient):
|
|
|
514
636
|
id=agent_id,
|
|
515
637
|
name=name,
|
|
516
638
|
system=system,
|
|
517
|
-
|
|
639
|
+
tool_names=tool_names,
|
|
518
640
|
tags=tags,
|
|
519
641
|
description=description,
|
|
520
642
|
metadata_=metadata,
|
|
521
643
|
llm_config=llm_config,
|
|
522
644
|
embedding_config=embedding_config,
|
|
523
645
|
message_ids=message_ids,
|
|
524
|
-
memory=memory,
|
|
525
646
|
)
|
|
526
647
|
response = requests.patch(f"{self.base_url}/{self.api_prefix}/agents/{agent_id}", json=request.model_dump(), headers=self.headers)
|
|
527
648
|
if response.status_code != 200:
|
|
@@ -715,7 +836,7 @@ class RESTClient(AbstractClient):
|
|
|
715
836
|
|
|
716
837
|
# agent interactions
|
|
717
838
|
|
|
718
|
-
def user_message(self, agent_id: str, message: str
|
|
839
|
+
def user_message(self, agent_id: str, message: str) -> LettaResponse:
|
|
719
840
|
"""
|
|
720
841
|
Send a message to an agent as a user
|
|
721
842
|
|
|
@@ -726,7 +847,7 @@ class RESTClient(AbstractClient):
|
|
|
726
847
|
Returns:
|
|
727
848
|
response (LettaResponse): Response from the agent
|
|
728
849
|
"""
|
|
729
|
-
return self.send_message(agent_id, message, role="user"
|
|
850
|
+
return self.send_message(agent_id=agent_id, message=message, role="user")
|
|
730
851
|
|
|
731
852
|
def save(self):
|
|
732
853
|
raise NotImplementedError
|
|
@@ -813,13 +934,13 @@ class RESTClient(AbstractClient):
|
|
|
813
934
|
|
|
814
935
|
def send_message(
|
|
815
936
|
self,
|
|
816
|
-
agent_id: str,
|
|
817
937
|
message: str,
|
|
818
938
|
role: str,
|
|
939
|
+
agent_id: Optional[str] = None,
|
|
819
940
|
name: Optional[str] = None,
|
|
941
|
+
stream: Optional[bool] = False,
|
|
820
942
|
stream_steps: bool = False,
|
|
821
943
|
stream_tokens: bool = False,
|
|
822
|
-
include_full_message: bool = False,
|
|
823
944
|
) -> Union[LettaResponse, Generator[LettaStreamingResponse, None, None]]:
|
|
824
945
|
"""
|
|
825
946
|
Send a message to an agent
|
|
@@ -840,17 +961,11 @@ class RESTClient(AbstractClient):
|
|
|
840
961
|
# TODO: figure out how to handle stream_steps and stream_tokens
|
|
841
962
|
|
|
842
963
|
# When streaming steps is True, stream_tokens must be False
|
|
843
|
-
request = LettaRequest(
|
|
844
|
-
messages=messages,
|
|
845
|
-
stream_steps=stream_steps,
|
|
846
|
-
stream_tokens=stream_tokens,
|
|
847
|
-
return_message_object=include_full_message,
|
|
848
|
-
)
|
|
964
|
+
request = LettaRequest(messages=messages)
|
|
849
965
|
if stream_tokens or stream_steps:
|
|
850
966
|
from letta.client.streaming import _sse_post
|
|
851
967
|
|
|
852
|
-
request.
|
|
853
|
-
return _sse_post(f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/messages", request.model_dump(), self.headers)
|
|
968
|
+
return _sse_post(f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/messages/stream", request.model_dump(), self.headers)
|
|
854
969
|
else:
|
|
855
970
|
response = requests.post(
|
|
856
971
|
f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/messages", json=request.model_dump(), headers=self.headers
|
|
@@ -884,8 +999,12 @@ class RESTClient(AbstractClient):
|
|
|
884
999
|
else:
|
|
885
1000
|
return [Block(**block) for block in response.json()]
|
|
886
1001
|
|
|
887
|
-
def create_block(
|
|
888
|
-
|
|
1002
|
+
def create_block(
|
|
1003
|
+
self, label: str, value: str, limit: Optional[int] = None, template_name: Optional[str] = None, is_template: bool = False
|
|
1004
|
+
) -> Block: #
|
|
1005
|
+
request = CreateBlock(label=label, value=value, template=is_template, template_name=template_name)
|
|
1006
|
+
if limit:
|
|
1007
|
+
request.limit = limit
|
|
889
1008
|
response = requests.post(f"{self.base_url}/{self.api_prefix}/blocks", json=request.model_dump(), headers=self.headers)
|
|
890
1009
|
if response.status_code != 200:
|
|
891
1010
|
raise ValueError(f"Failed to create block: {response.text}")
|
|
@@ -1324,18 +1443,39 @@ class RESTClient(AbstractClient):
|
|
|
1324
1443
|
Returns:
|
|
1325
1444
|
tool (Tool): The created tool.
|
|
1326
1445
|
"""
|
|
1446
|
+
source_code = parse_source_code(func)
|
|
1447
|
+
source_type = "python"
|
|
1327
1448
|
|
|
1328
|
-
#
|
|
1329
|
-
|
|
1449
|
+
# call server function
|
|
1450
|
+
request = ToolCreate(source_type=source_type, source_code=source_code, name=name, tags=tags)
|
|
1451
|
+
response = requests.post(f"{self.base_url}/{self.api_prefix}/tools", json=request.model_dump(), headers=self.headers)
|
|
1452
|
+
if response.status_code != 200:
|
|
1453
|
+
raise ValueError(f"Failed to create tool: {response.text}")
|
|
1454
|
+
return Tool(**response.json())
|
|
1330
1455
|
|
|
1331
|
-
|
|
1332
|
-
|
|
1456
|
+
def create_or_update_tool(
|
|
1457
|
+
self,
|
|
1458
|
+
func: Callable,
|
|
1459
|
+
name: Optional[str] = None,
|
|
1460
|
+
tags: Optional[List[str]] = None,
|
|
1461
|
+
) -> Tool:
|
|
1462
|
+
"""
|
|
1463
|
+
Creates or updates a tool. This stores the source code of function on the server, so that the server can execute the function and generate an OpenAI JSON schemas for it when using with an agent.
|
|
1464
|
+
|
|
1465
|
+
Args:
|
|
1466
|
+
func (callable): The function to create a tool for.
|
|
1467
|
+
name: (str): Name of the tool (must be unique per-user.)
|
|
1468
|
+
tags (Optional[List[str]], optional): Tags for the tool. Defaults to None.
|
|
1469
|
+
|
|
1470
|
+
Returns:
|
|
1471
|
+
tool (Tool): The created tool.
|
|
1472
|
+
"""
|
|
1333
1473
|
source_code = parse_source_code(func)
|
|
1334
1474
|
source_type = "python"
|
|
1335
1475
|
|
|
1336
1476
|
# call server function
|
|
1337
1477
|
request = ToolCreate(source_type=source_type, source_code=source_code, name=name, tags=tags)
|
|
1338
|
-
response = requests.
|
|
1478
|
+
response = requests.put(f"{self.base_url}/{self.api_prefix}/tools", json=request.model_dump(), headers=self.headers)
|
|
1339
1479
|
if response.status_code != 200:
|
|
1340
1480
|
raise ValueError(f"Failed to create tool: {response.text}")
|
|
1341
1481
|
return Tool(**response.json())
|
|
@@ -1373,45 +1513,6 @@ class RESTClient(AbstractClient):
|
|
|
1373
1513
|
raise ValueError(f"Failed to update tool: {response.text}")
|
|
1374
1514
|
return Tool(**response.json())
|
|
1375
1515
|
|
|
1376
|
-
# def create_tool(
|
|
1377
|
-
# self,
|
|
1378
|
-
# func,
|
|
1379
|
-
# name: Optional[str] = None,
|
|
1380
|
-
# update: Optional[bool] = True, # TODO: actually use this
|
|
1381
|
-
# tags: Optional[List[str]] = None,
|
|
1382
|
-
# ):
|
|
1383
|
-
# """Create a tool
|
|
1384
|
-
|
|
1385
|
-
# Args:
|
|
1386
|
-
# func (callable): The function to create a tool for.
|
|
1387
|
-
# tags (Optional[List[str]], optional): Tags for the tool. Defaults to None.
|
|
1388
|
-
# update (bool, optional): Update the tool if it already exists. Defaults to True.
|
|
1389
|
-
|
|
1390
|
-
# Returns:
|
|
1391
|
-
# Tool object
|
|
1392
|
-
# """
|
|
1393
|
-
|
|
1394
|
-
# # TODO: check if tool already exists
|
|
1395
|
-
# # TODO: how to load modules?
|
|
1396
|
-
# # parse source code/schema
|
|
1397
|
-
# source_code = parse_source_code(func)
|
|
1398
|
-
# json_schema = generate_schema(func, name)
|
|
1399
|
-
# source_type = "python"
|
|
1400
|
-
# json_schema["name"]
|
|
1401
|
-
|
|
1402
|
-
# # create data
|
|
1403
|
-
# data = {"source_code": source_code, "source_type": source_type, "tags": tags, "json_schema": json_schema, "update": update}
|
|
1404
|
-
# try:
|
|
1405
|
-
# CreateToolRequest(**data) # validate data
|
|
1406
|
-
# except Exception as e:
|
|
1407
|
-
# raise ValueError(f"Failed to create tool: {e}, invalid input {data}")
|
|
1408
|
-
|
|
1409
|
-
# # make REST request
|
|
1410
|
-
# response = requests.post(f"{self.base_url}/{self.api_prefix}/tools", json=data, headers=self.headers)
|
|
1411
|
-
# if response.status_code != 200:
|
|
1412
|
-
# raise ValueError(f"Failed to create tool: {response.text}")
|
|
1413
|
-
# return ToolModel(**response.json())
|
|
1414
|
-
|
|
1415
1516
|
def list_tools(self, cursor: Optional[str] = None, limit: Optional[int] = 50) -> List[Tool]:
|
|
1416
1517
|
"""
|
|
1417
1518
|
List available tools for the user.
|
|
@@ -1565,6 +1666,292 @@ class RESTClient(AbstractClient):
|
|
|
1565
1666
|
# Parse and return the deleted organization
|
|
1566
1667
|
return Organization(**response.json())
|
|
1567
1668
|
|
|
1669
|
+
def create_sandbox_config(self, config: Union[LocalSandboxConfig, E2BSandboxConfig]) -> SandboxConfig:
|
|
1670
|
+
"""
|
|
1671
|
+
Create a new sandbox configuration.
|
|
1672
|
+
"""
|
|
1673
|
+
payload = {
|
|
1674
|
+
"config": config.model_dump(),
|
|
1675
|
+
}
|
|
1676
|
+
response = requests.post(f"{self.base_url}/{self.api_prefix}/sandbox-config", headers=self.headers, json=payload)
|
|
1677
|
+
if response.status_code != 200:
|
|
1678
|
+
raise ValueError(f"Failed to create sandbox config: {response.text}")
|
|
1679
|
+
return SandboxConfig(**response.json())
|
|
1680
|
+
|
|
1681
|
+
def update_sandbox_config(self, sandbox_config_id: str, config: Union[LocalSandboxConfig, E2BSandboxConfig]) -> SandboxConfig:
|
|
1682
|
+
"""
|
|
1683
|
+
Update an existing sandbox configuration.
|
|
1684
|
+
"""
|
|
1685
|
+
payload = {
|
|
1686
|
+
"config": config.model_dump(),
|
|
1687
|
+
}
|
|
1688
|
+
response = requests.patch(
|
|
1689
|
+
f"{self.base_url}/{self.api_prefix}/sandbox-config/{sandbox_config_id}",
|
|
1690
|
+
headers=self.headers,
|
|
1691
|
+
json=payload,
|
|
1692
|
+
)
|
|
1693
|
+
if response.status_code != 200:
|
|
1694
|
+
raise ValueError(f"Failed to update sandbox config with ID '{sandbox_config_id}': {response.text}")
|
|
1695
|
+
return SandboxConfig(**response.json())
|
|
1696
|
+
|
|
1697
|
+
def delete_sandbox_config(self, sandbox_config_id: str) -> None:
|
|
1698
|
+
"""
|
|
1699
|
+
Delete a sandbox configuration.
|
|
1700
|
+
"""
|
|
1701
|
+
response = requests.delete(f"{self.base_url}/{self.api_prefix}/sandbox-config/{sandbox_config_id}", headers=self.headers)
|
|
1702
|
+
if response.status_code == 404:
|
|
1703
|
+
raise ValueError(f"Sandbox config with ID '{sandbox_config_id}' does not exist")
|
|
1704
|
+
elif response.status_code != 204:
|
|
1705
|
+
raise ValueError(f"Failed to delete sandbox config with ID '{sandbox_config_id}': {response.text}")
|
|
1706
|
+
|
|
1707
|
+
def list_sandbox_configs(self, limit: int = 50, cursor: Optional[str] = None) -> List[SandboxConfig]:
|
|
1708
|
+
"""
|
|
1709
|
+
List all sandbox configurations.
|
|
1710
|
+
"""
|
|
1711
|
+
params = {"limit": limit, "cursor": cursor}
|
|
1712
|
+
response = requests.get(f"{self.base_url}/{self.api_prefix}/sandbox-config", headers=self.headers, params=params)
|
|
1713
|
+
if response.status_code != 200:
|
|
1714
|
+
raise ValueError(f"Failed to list sandbox configs: {response.text}")
|
|
1715
|
+
return [SandboxConfig(**config_data) for config_data in response.json()]
|
|
1716
|
+
|
|
1717
|
+
def create_sandbox_env_var(
|
|
1718
|
+
self, sandbox_config_id: str, key: str, value: str, description: Optional[str] = None
|
|
1719
|
+
) -> SandboxEnvironmentVariable:
|
|
1720
|
+
"""
|
|
1721
|
+
Create a new environment variable for a sandbox configuration.
|
|
1722
|
+
"""
|
|
1723
|
+
payload = {"key": key, "value": value, "description": description}
|
|
1724
|
+
response = requests.post(
|
|
1725
|
+
f"{self.base_url}/{self.api_prefix}/sandbox-config/{sandbox_config_id}/environment-variable",
|
|
1726
|
+
headers=self.headers,
|
|
1727
|
+
json=payload,
|
|
1728
|
+
)
|
|
1729
|
+
if response.status_code != 200:
|
|
1730
|
+
raise ValueError(f"Failed to create environment variable for sandbox config ID '{sandbox_config_id}': {response.text}")
|
|
1731
|
+
return SandboxEnvironmentVariable(**response.json())
|
|
1732
|
+
|
|
1733
|
+
def update_sandbox_env_var(
|
|
1734
|
+
self, env_var_id: str, key: Optional[str] = None, value: Optional[str] = None, description: Optional[str] = None
|
|
1735
|
+
) -> SandboxEnvironmentVariable:
|
|
1736
|
+
"""
|
|
1737
|
+
Update an existing environment variable.
|
|
1738
|
+
"""
|
|
1739
|
+
payload = {k: v for k, v in {"key": key, "value": value, "description": description}.items() if v is not None}
|
|
1740
|
+
response = requests.patch(
|
|
1741
|
+
f"{self.base_url}/{self.api_prefix}/sandbox-config/environment-variable/{env_var_id}",
|
|
1742
|
+
headers=self.headers,
|
|
1743
|
+
json=payload,
|
|
1744
|
+
)
|
|
1745
|
+
if response.status_code != 200:
|
|
1746
|
+
raise ValueError(f"Failed to update environment variable with ID '{env_var_id}': {response.text}")
|
|
1747
|
+
return SandboxEnvironmentVariable(**response.json())
|
|
1748
|
+
|
|
1749
|
+
def delete_sandbox_env_var(self, env_var_id: str) -> None:
|
|
1750
|
+
"""
|
|
1751
|
+
Delete an environment variable by its ID.
|
|
1752
|
+
"""
|
|
1753
|
+
response = requests.delete(
|
|
1754
|
+
f"{self.base_url}/{self.api_prefix}/sandbox-config/environment-variable/{env_var_id}", headers=self.headers
|
|
1755
|
+
)
|
|
1756
|
+
if response.status_code == 404:
|
|
1757
|
+
raise ValueError(f"Environment variable with ID '{env_var_id}' does not exist")
|
|
1758
|
+
elif response.status_code != 204:
|
|
1759
|
+
raise ValueError(f"Failed to delete environment variable with ID '{env_var_id}': {response.text}")
|
|
1760
|
+
|
|
1761
|
+
def list_sandbox_env_vars(
|
|
1762
|
+
self, sandbox_config_id: str, limit: int = 50, cursor: Optional[str] = None
|
|
1763
|
+
) -> List[SandboxEnvironmentVariable]:
|
|
1764
|
+
"""
|
|
1765
|
+
List all environment variables associated with a sandbox configuration.
|
|
1766
|
+
"""
|
|
1767
|
+
params = {"limit": limit, "cursor": cursor}
|
|
1768
|
+
response = requests.get(
|
|
1769
|
+
f"{self.base_url}/{self.api_prefix}/sandbox-config/{sandbox_config_id}/environment-variable",
|
|
1770
|
+
headers=self.headers,
|
|
1771
|
+
params=params,
|
|
1772
|
+
)
|
|
1773
|
+
if response.status_code != 200:
|
|
1774
|
+
raise ValueError(f"Failed to list environment variables for sandbox config ID '{sandbox_config_id}': {response.text}")
|
|
1775
|
+
return [SandboxEnvironmentVariable(**var_data) for var_data in response.json()]
|
|
1776
|
+
|
|
1777
|
+
def update_agent_memory_block_label(self, agent_id: str, current_label: str, new_label: str) -> Memory:
|
|
1778
|
+
"""Rename a block in the agent's core memory
|
|
1779
|
+
|
|
1780
|
+
Args:
|
|
1781
|
+
agent_id (str): The agent ID
|
|
1782
|
+
current_label (str): The current label of the block
|
|
1783
|
+
new_label (str): The new label of the block
|
|
1784
|
+
|
|
1785
|
+
Returns:
|
|
1786
|
+
memory (Memory): The updated memory
|
|
1787
|
+
"""
|
|
1788
|
+
block = self.get_agent_memory_block(agent_id, current_label)
|
|
1789
|
+
return self.update_block(block.id, label=new_label)
|
|
1790
|
+
|
|
1791
|
+
# TODO: remove this
|
|
1792
|
+
def add_agent_memory_block(self, agent_id: str, create_block: CreateBlock) -> Memory:
|
|
1793
|
+
"""
|
|
1794
|
+
Create and link a memory block to an agent's core memory
|
|
1795
|
+
|
|
1796
|
+
Args:
|
|
1797
|
+
agent_id (str): The agent ID
|
|
1798
|
+
create_block (CreateBlock): The block to create
|
|
1799
|
+
|
|
1800
|
+
Returns:
|
|
1801
|
+
memory (Memory): The updated memory
|
|
1802
|
+
"""
|
|
1803
|
+
response = requests.post(
|
|
1804
|
+
f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/memory/block",
|
|
1805
|
+
headers=self.headers,
|
|
1806
|
+
json=create_block.model_dump(),
|
|
1807
|
+
)
|
|
1808
|
+
if response.status_code != 200:
|
|
1809
|
+
raise ValueError(f"Failed to add agent memory block: {response.text}")
|
|
1810
|
+
return Memory(**response.json())
|
|
1811
|
+
|
|
1812
|
+
def link_agent_memory_block(self, agent_id: str, block_id: str) -> Memory:
|
|
1813
|
+
"""
|
|
1814
|
+
Link a block to an agent's core memory
|
|
1815
|
+
|
|
1816
|
+
Args:
|
|
1817
|
+
agent_id (str): The agent ID
|
|
1818
|
+
block_id (str): The block ID
|
|
1819
|
+
|
|
1820
|
+
Returns:
|
|
1821
|
+
memory (Memory): The updated memory
|
|
1822
|
+
"""
|
|
1823
|
+
params = {"agent_id": agent_id}
|
|
1824
|
+
response = requests.patch(
|
|
1825
|
+
f"{self.base_url}/{self.api_prefix}/blocks/{block_id}/attach",
|
|
1826
|
+
params=params,
|
|
1827
|
+
headers=self.headers,
|
|
1828
|
+
)
|
|
1829
|
+
if response.status_code != 200:
|
|
1830
|
+
raise ValueError(f"Failed to link agent memory block: {response.text}")
|
|
1831
|
+
return Block(**response.json())
|
|
1832
|
+
|
|
1833
|
+
def remove_agent_memory_block(self, agent_id: str, block_label: str) -> Memory:
|
|
1834
|
+
"""
|
|
1835
|
+
Unlike a block from the agent's core memory
|
|
1836
|
+
|
|
1837
|
+
Args:
|
|
1838
|
+
agent_id (str): The agent ID
|
|
1839
|
+
block_label (str): The block label
|
|
1840
|
+
|
|
1841
|
+
Returns:
|
|
1842
|
+
memory (Memory): The updated memory
|
|
1843
|
+
"""
|
|
1844
|
+
response = requests.delete(
|
|
1845
|
+
f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/memory/block/{block_label}",
|
|
1846
|
+
headers=self.headers,
|
|
1847
|
+
)
|
|
1848
|
+
if response.status_code != 200:
|
|
1849
|
+
raise ValueError(f"Failed to remove agent memory block: {response.text}")
|
|
1850
|
+
return Memory(**response.json())
|
|
1851
|
+
|
|
1852
|
+
def get_agent_memory_blocks(self, agent_id: str) -> List[Block]:
|
|
1853
|
+
"""
|
|
1854
|
+
Get all the blocks in the agent's core memory
|
|
1855
|
+
|
|
1856
|
+
Args:
|
|
1857
|
+
agent_id (str): The agent ID
|
|
1858
|
+
|
|
1859
|
+
Returns:
|
|
1860
|
+
blocks (List[Block]): The blocks in the agent's core memory
|
|
1861
|
+
"""
|
|
1862
|
+
response = requests.get(f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/memory/block", headers=self.headers)
|
|
1863
|
+
if response.status_code != 200:
|
|
1864
|
+
raise ValueError(f"Failed to get agent memory blocks: {response.text}")
|
|
1865
|
+
return [Block(**block) for block in response.json()]
|
|
1866
|
+
|
|
1867
|
+
def get_agent_memory_block(self, agent_id: str, label: str) -> Block:
|
|
1868
|
+
"""
|
|
1869
|
+
Get a block in the agent's core memory by its label
|
|
1870
|
+
|
|
1871
|
+
Args:
|
|
1872
|
+
agent_id (str): The agent ID
|
|
1873
|
+
label (str): The label in the agent's core memory
|
|
1874
|
+
|
|
1875
|
+
Returns:
|
|
1876
|
+
block (Block): The block corresponding to the label
|
|
1877
|
+
"""
|
|
1878
|
+
response = requests.get(
|
|
1879
|
+
f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/memory/block/{label}",
|
|
1880
|
+
headers=self.headers,
|
|
1881
|
+
)
|
|
1882
|
+
if response.status_code != 200:
|
|
1883
|
+
raise ValueError(f"Failed to get agent memory block: {response.text}")
|
|
1884
|
+
return Block(**response.json())
|
|
1885
|
+
|
|
1886
|
+
def update_agent_memory_block(
|
|
1887
|
+
self,
|
|
1888
|
+
agent_id: str,
|
|
1889
|
+
label: str,
|
|
1890
|
+
value: Optional[str] = None,
|
|
1891
|
+
limit: Optional[int] = None,
|
|
1892
|
+
):
|
|
1893
|
+
"""
|
|
1894
|
+
Update a block in the agent's core memory by specifying its label
|
|
1895
|
+
|
|
1896
|
+
Args:
|
|
1897
|
+
agent_id (str): The agent ID
|
|
1898
|
+
label (str): The label of the block
|
|
1899
|
+
value (str): The new value of the block
|
|
1900
|
+
limit (int): The new limit of the block
|
|
1901
|
+
|
|
1902
|
+
Returns:
|
|
1903
|
+
block (Block): The updated block
|
|
1904
|
+
"""
|
|
1905
|
+
# setup data
|
|
1906
|
+
data = {}
|
|
1907
|
+
if value:
|
|
1908
|
+
data["value"] = value
|
|
1909
|
+
if limit:
|
|
1910
|
+
data["limit"] = limit
|
|
1911
|
+
response = requests.patch(
|
|
1912
|
+
f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/memory/block/{label}",
|
|
1913
|
+
headers=self.headers,
|
|
1914
|
+
json=data,
|
|
1915
|
+
)
|
|
1916
|
+
if response.status_code != 200:
|
|
1917
|
+
raise ValueError(f"Failed to update agent memory block: {response.text}")
|
|
1918
|
+
return Block(**response.json())
|
|
1919
|
+
|
|
1920
|
+
def update_block(
|
|
1921
|
+
self,
|
|
1922
|
+
block_id: str,
|
|
1923
|
+
label: Optional[str] = None,
|
|
1924
|
+
value: Optional[str] = None,
|
|
1925
|
+
limit: Optional[int] = None,
|
|
1926
|
+
):
|
|
1927
|
+
"""
|
|
1928
|
+
Update a block given the ID with the provided fields
|
|
1929
|
+
|
|
1930
|
+
Args:
|
|
1931
|
+
block_id (str): ID of the block
|
|
1932
|
+
label (str): Label to assign to the block
|
|
1933
|
+
value (str): Value to assign to the block
|
|
1934
|
+
limit (int): Token limit to assign to the block
|
|
1935
|
+
|
|
1936
|
+
Returns:
|
|
1937
|
+
block (Block): Updated block
|
|
1938
|
+
"""
|
|
1939
|
+
data = {}
|
|
1940
|
+
if value:
|
|
1941
|
+
data["value"] = value
|
|
1942
|
+
if limit:
|
|
1943
|
+
data["limit"] = limit
|
|
1944
|
+
if label:
|
|
1945
|
+
data["label"] = label
|
|
1946
|
+
response = requests.patch(
|
|
1947
|
+
f"{self.base_url}/{self.api_prefix}/blocks/{block_id}",
|
|
1948
|
+
headers=self.headers,
|
|
1949
|
+
json=data,
|
|
1950
|
+
)
|
|
1951
|
+
if response.status_code != 200:
|
|
1952
|
+
raise ValueError(f"Failed to update block: {response.text}")
|
|
1953
|
+
return Block(**response.json())
|
|
1954
|
+
|
|
1568
1955
|
|
|
1569
1956
|
class LocalClient(AbstractClient):
|
|
1570
1957
|
"""
|
|
@@ -1662,6 +2049,11 @@ class LocalClient(AbstractClient):
|
|
|
1662
2049
|
llm_config: LLMConfig = None,
|
|
1663
2050
|
# memory
|
|
1664
2051
|
memory: Memory = ChatMemory(human=get_human_text(DEFAULT_HUMAN), persona=get_persona_text(DEFAULT_PERSONA)),
|
|
2052
|
+
# TODO: change to this when we are ready to migrate all the tests/examples (matches the REST API)
|
|
2053
|
+
# memory_blocks=[
|
|
2054
|
+
# {"label": "human", "value": get_human_text(DEFAULT_HUMAN), "limit": 5000},
|
|
2055
|
+
# {"label": "persona", "value": get_persona_text(DEFAULT_PERSONA), "limit": 5000},
|
|
2056
|
+
# ],
|
|
1665
2057
|
# system
|
|
1666
2058
|
system: Optional[str] = None,
|
|
1667
2059
|
# tools
|
|
@@ -1680,7 +2072,7 @@ class LocalClient(AbstractClient):
|
|
|
1680
2072
|
name (str): Name of the agent
|
|
1681
2073
|
embedding_config (EmbeddingConfig): Embedding configuration
|
|
1682
2074
|
llm_config (LLMConfig): LLM configuration
|
|
1683
|
-
|
|
2075
|
+
memory_blocks (List[Dict]): List of configurations for the memory blocks (placed in core-memory)
|
|
1684
2076
|
system (str): System configuration
|
|
1685
2077
|
tools (List[str]): List of tools
|
|
1686
2078
|
tool_rules (Optional[List[BaseToolRule]]): List of tool rules
|
|
@@ -1702,14 +2094,7 @@ class LocalClient(AbstractClient):
|
|
|
1702
2094
|
tool_names += tools
|
|
1703
2095
|
if include_base_tools:
|
|
1704
2096
|
tool_names += BASE_TOOLS
|
|
1705
|
-
|
|
1706
|
-
# add memory tools
|
|
1707
|
-
memory_functions = get_memory_functions(memory)
|
|
1708
|
-
for func_name, func in memory_functions.items():
|
|
1709
|
-
tool = self.create_tool(func, name=func_name, tags=["memory", "letta-base"])
|
|
1710
|
-
tool_names.append(tool.name)
|
|
1711
|
-
|
|
1712
|
-
self.interface.clear()
|
|
2097
|
+
tool_names += BASE_MEMORY_TOOLS
|
|
1713
2098
|
|
|
1714
2099
|
# check if default configs are provided
|
|
1715
2100
|
assert embedding_config or self._default_embedding_config, f"Embedding config must be provided"
|
|
@@ -1721,7 +2106,10 @@ class LocalClient(AbstractClient):
|
|
|
1721
2106
|
name=name,
|
|
1722
2107
|
description=description,
|
|
1723
2108
|
metadata_=metadata,
|
|
1724
|
-
memory=memory,
|
|
2109
|
+
# memory=memory,
|
|
2110
|
+
memory_blocks=[],
|
|
2111
|
+
# memory_blocks = memory.get_blocks(),
|
|
2112
|
+
# memory_tools=memory_tools,
|
|
1725
2113
|
tools=tool_names,
|
|
1726
2114
|
tool_rules=tool_rules,
|
|
1727
2115
|
system=system,
|
|
@@ -1733,7 +2121,18 @@ class LocalClient(AbstractClient):
|
|
|
1733
2121
|
),
|
|
1734
2122
|
actor=self.user,
|
|
1735
2123
|
)
|
|
1736
|
-
|
|
2124
|
+
|
|
2125
|
+
# TODO: remove when we fully migrate to block creation CreateAgent model
|
|
2126
|
+
# Link additional blocks to the agent (block ids created on the client)
|
|
2127
|
+
# This needs to happen since the create agent does not allow passing in blocks which have already been persisted and have an ID
|
|
2128
|
+
# So we create the agent and then link the blocks afterwards
|
|
2129
|
+
user = self.server.get_user_or_default(self.user_id)
|
|
2130
|
+
for block in memory.get_blocks():
|
|
2131
|
+
self.server.block_manager.create_or_update_block(block, actor=user)
|
|
2132
|
+
self.server.link_block_to_agent_memory(user_id=self.user_id, agent_id=agent_state.id, block_id=block.id)
|
|
2133
|
+
|
|
2134
|
+
# TODO: get full agent state
|
|
2135
|
+
return self.server.get_agent(agent_state.id)
|
|
1737
2136
|
|
|
1738
2137
|
def update_message(
|
|
1739
2138
|
self,
|
|
@@ -1770,7 +2169,6 @@ class LocalClient(AbstractClient):
|
|
|
1770
2169
|
llm_config: Optional[LLMConfig] = None,
|
|
1771
2170
|
embedding_config: Optional[EmbeddingConfig] = None,
|
|
1772
2171
|
message_ids: Optional[List[str]] = None,
|
|
1773
|
-
memory: Optional[Memory] = None,
|
|
1774
2172
|
):
|
|
1775
2173
|
"""
|
|
1776
2174
|
Update an existing agent
|
|
@@ -1785,26 +2183,25 @@ class LocalClient(AbstractClient):
|
|
|
1785
2183
|
llm_config (LLMConfig): LLM configuration
|
|
1786
2184
|
embedding_config (EmbeddingConfig): Embedding configuration
|
|
1787
2185
|
message_ids (List[str]): List of message IDs
|
|
1788
|
-
memory (Memory): Memory configuration
|
|
1789
2186
|
tags (List[str]): Tags for filtering agents
|
|
1790
2187
|
|
|
1791
2188
|
Returns:
|
|
1792
2189
|
agent_state (AgentState): State of the updated agent
|
|
1793
2190
|
"""
|
|
2191
|
+
# TODO: add the abilitty to reset linked block_ids
|
|
1794
2192
|
self.interface.clear()
|
|
1795
2193
|
agent_state = self.server.update_agent(
|
|
1796
2194
|
UpdateAgentState(
|
|
1797
2195
|
id=agent_id,
|
|
1798
2196
|
name=name,
|
|
1799
2197
|
system=system,
|
|
1800
|
-
|
|
2198
|
+
tool_names=tools,
|
|
1801
2199
|
tags=tags,
|
|
1802
2200
|
description=description,
|
|
1803
2201
|
metadata_=metadata,
|
|
1804
2202
|
llm_config=llm_config,
|
|
1805
2203
|
embedding_config=embedding_config,
|
|
1806
2204
|
message_ids=message_ids,
|
|
1807
|
-
memory=memory,
|
|
1808
2205
|
),
|
|
1809
2206
|
actor=self.user,
|
|
1810
2207
|
)
|
|
@@ -1943,7 +2340,7 @@ class LocalClient(AbstractClient):
|
|
|
1943
2340
|
|
|
1944
2341
|
"""
|
|
1945
2342
|
# TODO: implement this (not sure what it should look like)
|
|
1946
|
-
memory = self.server.update_agent_core_memory(user_id=self.user_id, agent_id=agent_id,
|
|
2343
|
+
memory = self.server.update_agent_core_memory(user_id=self.user_id, agent_id=agent_id, label=section, value=value)
|
|
1947
2344
|
return memory
|
|
1948
2345
|
|
|
1949
2346
|
def get_archival_memory_summary(self, agent_id: str) -> ArchivalMemorySummary:
|
|
@@ -1989,7 +2386,6 @@ class LocalClient(AbstractClient):
|
|
|
1989
2386
|
self,
|
|
1990
2387
|
agent_id: str,
|
|
1991
2388
|
messages: List[Union[Message | MessageCreate]],
|
|
1992
|
-
include_full_message: Optional[bool] = False,
|
|
1993
2389
|
):
|
|
1994
2390
|
"""
|
|
1995
2391
|
Send pre-packed messages to an agent.
|
|
@@ -2009,15 +2405,7 @@ class LocalClient(AbstractClient):
|
|
|
2009
2405
|
self.save()
|
|
2010
2406
|
|
|
2011
2407
|
# format messages
|
|
2012
|
-
messages =
|
|
2013
|
-
if include_full_message:
|
|
2014
|
-
letta_messages = messages
|
|
2015
|
-
else:
|
|
2016
|
-
letta_messages = []
|
|
2017
|
-
for m in messages:
|
|
2018
|
-
letta_messages += m.to_letta_message()
|
|
2019
|
-
|
|
2020
|
-
return LettaResponse(messages=letta_messages, usage=usage)
|
|
2408
|
+
return LettaResponse(messages=messages, usage=usage)
|
|
2021
2409
|
|
|
2022
2410
|
def send_message(
|
|
2023
2411
|
self,
|
|
@@ -2028,7 +2416,6 @@ class LocalClient(AbstractClient):
|
|
|
2028
2416
|
agent_name: Optional[str] = None,
|
|
2029
2417
|
stream_steps: bool = False,
|
|
2030
2418
|
stream_tokens: bool = False,
|
|
2031
|
-
include_full_message: Optional[bool] = False,
|
|
2032
2419
|
) -> LettaResponse:
|
|
2033
2420
|
"""
|
|
2034
2421
|
Send a message to an agent
|
|
@@ -2077,16 +2464,13 @@ class LocalClient(AbstractClient):
|
|
|
2077
2464
|
|
|
2078
2465
|
# format messages
|
|
2079
2466
|
messages = self.interface.to_list()
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
letta_messages = []
|
|
2084
|
-
for m in messages:
|
|
2085
|
-
letta_messages += m.to_letta_message()
|
|
2467
|
+
letta_messages = []
|
|
2468
|
+
for m in messages:
|
|
2469
|
+
letta_messages += m.to_letta_message()
|
|
2086
2470
|
|
|
2087
2471
|
return LettaResponse(messages=letta_messages, usage=usage)
|
|
2088
2472
|
|
|
2089
|
-
def user_message(self, agent_id: str, message: str
|
|
2473
|
+
def user_message(self, agent_id: str, message: str) -> LettaResponse:
|
|
2090
2474
|
"""
|
|
2091
2475
|
Send a message to an agent as a user
|
|
2092
2476
|
|
|
@@ -2098,7 +2482,7 @@ class LocalClient(AbstractClient):
|
|
|
2098
2482
|
response (LettaResponse): Response from the agent
|
|
2099
2483
|
"""
|
|
2100
2484
|
self.interface.clear()
|
|
2101
|
-
return self.send_message(role="user", agent_id=agent_id, message=message
|
|
2485
|
+
return self.send_message(role="user", agent_id=agent_id, message=message)
|
|
2102
2486
|
|
|
2103
2487
|
def run_command(self, agent_id: str, command: str) -> LettaResponse:
|
|
2104
2488
|
"""
|
|
@@ -2302,7 +2686,6 @@ class LocalClient(AbstractClient):
|
|
|
2302
2686
|
tool_create = ToolCreate.from_composio(action=action)
|
|
2303
2687
|
return self.server.tool_manager.create_or_update_tool(pydantic_tool=Tool(**tool_create.model_dump()), actor=self.user)
|
|
2304
2688
|
|
|
2305
|
-
# TODO: Use the above function `add_tool` here as there is duplicate logic
|
|
2306
2689
|
def create_tool(
|
|
2307
2690
|
self,
|
|
2308
2691
|
func,
|
|
@@ -2330,6 +2713,42 @@ class LocalClient(AbstractClient):
|
|
|
2330
2713
|
if not tags:
|
|
2331
2714
|
tags = []
|
|
2332
2715
|
|
|
2716
|
+
# call server function
|
|
2717
|
+
return self.server.tool_manager.create_tool(
|
|
2718
|
+
Tool(
|
|
2719
|
+
source_type=source_type,
|
|
2720
|
+
source_code=source_code,
|
|
2721
|
+
name=name,
|
|
2722
|
+
tags=tags,
|
|
2723
|
+
description=description,
|
|
2724
|
+
),
|
|
2725
|
+
actor=self.user,
|
|
2726
|
+
)
|
|
2727
|
+
|
|
2728
|
+
def create_or_update_tool(
|
|
2729
|
+
self,
|
|
2730
|
+
func,
|
|
2731
|
+
name: Optional[str] = None,
|
|
2732
|
+
tags: Optional[List[str]] = None,
|
|
2733
|
+
description: Optional[str] = None,
|
|
2734
|
+
) -> Tool:
|
|
2735
|
+
"""
|
|
2736
|
+
Creates or updates a tool. This stores the source code of function on the server, so that the server can execute the function and generate an OpenAI JSON schemas for it when using with an agent.
|
|
2737
|
+
|
|
2738
|
+
Args:
|
|
2739
|
+
func (callable): The function to create a tool for.
|
|
2740
|
+
name: (str): Name of the tool (must be unique per-user.)
|
|
2741
|
+
tags (Optional[List[str]], optional): Tags for the tool. Defaults to None.
|
|
2742
|
+
description (str, optional): The description.
|
|
2743
|
+
|
|
2744
|
+
Returns:
|
|
2745
|
+
tool (Tool): The created tool.
|
|
2746
|
+
"""
|
|
2747
|
+
source_code = parse_source_code(func)
|
|
2748
|
+
source_type = "python"
|
|
2749
|
+
if not tags:
|
|
2750
|
+
tags = []
|
|
2751
|
+
|
|
2333
2752
|
# call server function
|
|
2334
2753
|
return self.server.tool_manager.create_or_update_tool(
|
|
2335
2754
|
Tool(
|
|
@@ -2655,7 +3074,6 @@ class LocalClient(AbstractClient):
|
|
|
2655
3074
|
after=after,
|
|
2656
3075
|
limit=limit,
|
|
2657
3076
|
reverse=True,
|
|
2658
|
-
return_message_object=True,
|
|
2659
3077
|
)
|
|
2660
3078
|
|
|
2661
3079
|
def list_blocks(self, label: Optional[str] = None, templates_only: Optional[bool] = True) -> List[Block]:
|
|
@@ -2671,7 +3089,9 @@ class LocalClient(AbstractClient):
|
|
|
2671
3089
|
"""
|
|
2672
3090
|
return self.server.block_manager.get_blocks(actor=self.user, label=label, is_template=templates_only)
|
|
2673
3091
|
|
|
2674
|
-
def create_block(
|
|
3092
|
+
def create_block(
|
|
3093
|
+
self, label: str, value: str, limit: Optional[int] = None, template_name: Optional[str] = None, is_template: bool = False
|
|
3094
|
+
) -> Block: #
|
|
2675
3095
|
"""
|
|
2676
3096
|
Create a block
|
|
2677
3097
|
|
|
@@ -2679,13 +3099,15 @@ class LocalClient(AbstractClient):
|
|
|
2679
3099
|
label (str): Label of the block
|
|
2680
3100
|
name (str): Name of the block
|
|
2681
3101
|
text (str): Text of the block
|
|
3102
|
+
limit (int): Character of the block
|
|
2682
3103
|
|
|
2683
3104
|
Returns:
|
|
2684
3105
|
block (Block): Created block
|
|
2685
3106
|
"""
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
3107
|
+
block = Block(label=label, template_name=template_name, value=value, is_template=is_template)
|
|
3108
|
+
if limit:
|
|
3109
|
+
block.limit = limit
|
|
3110
|
+
return self.server.block_manager.create_or_update_block(block, actor=self.user)
|
|
2689
3111
|
|
|
2690
3112
|
def update_block(self, block_id: str, name: Optional[str] = None, text: Optional[str] = None, limit: Optional[int] = None) -> Block:
|
|
2691
3113
|
"""
|
|
@@ -2773,3 +3195,209 @@ class LocalClient(AbstractClient):
|
|
|
2773
3195
|
|
|
2774
3196
|
def delete_org(self, org_id: str) -> Organization:
|
|
2775
3197
|
return self.server.organization_manager.delete_organization_by_id(org_id=org_id)
|
|
3198
|
+
|
|
3199
|
+
def create_sandbox_config(self, config: Union[LocalSandboxConfig, E2BSandboxConfig]) -> SandboxConfig:
|
|
3200
|
+
"""
|
|
3201
|
+
Create a new sandbox configuration.
|
|
3202
|
+
"""
|
|
3203
|
+
config_create = SandboxConfigCreate(config=config)
|
|
3204
|
+
return self.server.sandbox_config_manager.create_or_update_sandbox_config(sandbox_config_create=config_create, actor=self.user)
|
|
3205
|
+
|
|
3206
|
+
def update_sandbox_config(self, sandbox_config_id: str, config: Union[LocalSandboxConfig, E2BSandboxConfig]) -> SandboxConfig:
|
|
3207
|
+
"""
|
|
3208
|
+
Update an existing sandbox configuration.
|
|
3209
|
+
"""
|
|
3210
|
+
sandbox_update = SandboxConfigUpdate(config=config)
|
|
3211
|
+
return self.server.sandbox_config_manager.update_sandbox_config(
|
|
3212
|
+
sandbox_config_id=sandbox_config_id, sandbox_update=sandbox_update, actor=self.user
|
|
3213
|
+
)
|
|
3214
|
+
|
|
3215
|
+
def delete_sandbox_config(self, sandbox_config_id: str) -> None:
|
|
3216
|
+
"""
|
|
3217
|
+
Delete a sandbox configuration.
|
|
3218
|
+
"""
|
|
3219
|
+
return self.server.sandbox_config_manager.delete_sandbox_config(sandbox_config_id=sandbox_config_id, actor=self.user)
|
|
3220
|
+
|
|
3221
|
+
def list_sandbox_configs(self, limit: int = 50, cursor: Optional[str] = None) -> List[SandboxConfig]:
|
|
3222
|
+
"""
|
|
3223
|
+
List all sandbox configurations.
|
|
3224
|
+
"""
|
|
3225
|
+
return self.server.sandbox_config_manager.list_sandbox_configs(actor=self.user, limit=limit, cursor=cursor)
|
|
3226
|
+
|
|
3227
|
+
def create_sandbox_env_var(
|
|
3228
|
+
self, sandbox_config_id: str, key: str, value: str, description: Optional[str] = None
|
|
3229
|
+
) -> SandboxEnvironmentVariable:
|
|
3230
|
+
"""
|
|
3231
|
+
Create a new environment variable for a sandbox configuration.
|
|
3232
|
+
"""
|
|
3233
|
+
env_var_create = SandboxEnvironmentVariableCreate(key=key, value=value, description=description)
|
|
3234
|
+
return self.server.sandbox_config_manager.create_sandbox_env_var(
|
|
3235
|
+
env_var_create=env_var_create, sandbox_config_id=sandbox_config_id, actor=self.user
|
|
3236
|
+
)
|
|
3237
|
+
|
|
3238
|
+
def update_sandbox_env_var(
|
|
3239
|
+
self, env_var_id: str, key: Optional[str] = None, value: Optional[str] = None, description: Optional[str] = None
|
|
3240
|
+
) -> SandboxEnvironmentVariable:
|
|
3241
|
+
"""
|
|
3242
|
+
Update an existing environment variable.
|
|
3243
|
+
"""
|
|
3244
|
+
env_var_update = SandboxEnvironmentVariableUpdate(key=key, value=value, description=description)
|
|
3245
|
+
return self.server.sandbox_config_manager.update_sandbox_env_var(
|
|
3246
|
+
env_var_id=env_var_id, env_var_update=env_var_update, actor=self.user
|
|
3247
|
+
)
|
|
3248
|
+
|
|
3249
|
+
def delete_sandbox_env_var(self, env_var_id: str) -> None:
|
|
3250
|
+
"""
|
|
3251
|
+
Delete an environment variable by its ID.
|
|
3252
|
+
"""
|
|
3253
|
+
return self.server.sandbox_config_manager.delete_sandbox_env_var(env_var_id=env_var_id, actor=self.user)
|
|
3254
|
+
|
|
3255
|
+
def list_sandbox_env_vars(
|
|
3256
|
+
self, sandbox_config_id: str, limit: int = 50, cursor: Optional[str] = None
|
|
3257
|
+
) -> List[SandboxEnvironmentVariable]:
|
|
3258
|
+
"""
|
|
3259
|
+
List all environment variables associated with a sandbox configuration.
|
|
3260
|
+
"""
|
|
3261
|
+
return self.server.sandbox_config_manager.list_sandbox_env_vars(
|
|
3262
|
+
sandbox_config_id=sandbox_config_id, actor=self.user, limit=limit, cursor=cursor
|
|
3263
|
+
)
|
|
3264
|
+
|
|
3265
|
+
def update_agent_memory_block_label(self, agent_id: str, current_label: str, new_label: str) -> Memory:
|
|
3266
|
+
"""Rename a block in the agent's core memory
|
|
3267
|
+
|
|
3268
|
+
Args:
|
|
3269
|
+
agent_id (str): The agent ID
|
|
3270
|
+
current_label (str): The current label of the block
|
|
3271
|
+
new_label (str): The new label of the block
|
|
3272
|
+
|
|
3273
|
+
Returns:
|
|
3274
|
+
memory (Memory): The updated memory
|
|
3275
|
+
"""
|
|
3276
|
+
block = self.get_agent_memory_block(agent_id, current_label)
|
|
3277
|
+
return self.update_block(block.id, label=new_label)
|
|
3278
|
+
|
|
3279
|
+
# TODO: remove this
|
|
3280
|
+
def add_agent_memory_block(self, agent_id: str, create_block: CreateBlock) -> Memory:
|
|
3281
|
+
"""
|
|
3282
|
+
Create and link a memory block to an agent's core memory
|
|
3283
|
+
|
|
3284
|
+
Args:
|
|
3285
|
+
agent_id (str): The agent ID
|
|
3286
|
+
create_block (CreateBlock): The block to create
|
|
3287
|
+
|
|
3288
|
+
Returns:
|
|
3289
|
+
memory (Memory): The updated memory
|
|
3290
|
+
"""
|
|
3291
|
+
block_req = Block(**create_block.model_dump())
|
|
3292
|
+
block = self.server.block_manager.create_or_update_block(actor=self.user, block=block_req)
|
|
3293
|
+
# Link the block to the agent
|
|
3294
|
+
updated_memory = self.server.link_block_to_agent_memory(user_id=self.user_id, agent_id=agent_id, block_id=block.id)
|
|
3295
|
+
return updated_memory
|
|
3296
|
+
|
|
3297
|
+
def link_agent_memory_block(self, agent_id: str, block_id: str) -> Memory:
|
|
3298
|
+
"""
|
|
3299
|
+
Link a block to an agent's core memory
|
|
3300
|
+
|
|
3301
|
+
Args:
|
|
3302
|
+
agent_id (str): The agent ID
|
|
3303
|
+
block_id (str): The block ID
|
|
3304
|
+
|
|
3305
|
+
Returns:
|
|
3306
|
+
memory (Memory): The updated memory
|
|
3307
|
+
"""
|
|
3308
|
+
return self.server.link_block_to_agent_memory(user_id=self.user_id, agent_id=agent_id, block_id=block_id)
|
|
3309
|
+
|
|
3310
|
+
def remove_agent_memory_block(self, agent_id: str, block_label: str) -> Memory:
|
|
3311
|
+
"""
|
|
3312
|
+
Unlike a block from the agent's core memory
|
|
3313
|
+
|
|
3314
|
+
Args:
|
|
3315
|
+
agent_id (str): The agent ID
|
|
3316
|
+
block_label (str): The block label
|
|
3317
|
+
|
|
3318
|
+
Returns:
|
|
3319
|
+
memory (Memory): The updated memory
|
|
3320
|
+
"""
|
|
3321
|
+
return self.server.unlink_block_from_agent_memory(user_id=self.user_id, agent_id=agent_id, block_label=block_label)
|
|
3322
|
+
|
|
3323
|
+
def get_agent_memory_blocks(self, agent_id: str) -> List[Block]:
|
|
3324
|
+
"""
|
|
3325
|
+
Get all the blocks in the agent's core memory
|
|
3326
|
+
|
|
3327
|
+
Args:
|
|
3328
|
+
agent_id (str): The agent ID
|
|
3329
|
+
|
|
3330
|
+
Returns:
|
|
3331
|
+
blocks (List[Block]): The blocks in the agent's core memory
|
|
3332
|
+
"""
|
|
3333
|
+
block_ids = self.server.blocks_agents_manager.list_block_ids_for_agent(agent_id=agent_id)
|
|
3334
|
+
return [self.server.block_manager.get_block_by_id(block_id, actor=self.user) for block_id in block_ids]
|
|
3335
|
+
|
|
3336
|
+
def get_agent_memory_block(self, agent_id: str, label: str) -> Block:
|
|
3337
|
+
"""
|
|
3338
|
+
Get a block in the agent's core memory by its label
|
|
3339
|
+
|
|
3340
|
+
Args:
|
|
3341
|
+
agent_id (str): The agent ID
|
|
3342
|
+
label (str): The label in the agent's core memory
|
|
3343
|
+
|
|
3344
|
+
Returns:
|
|
3345
|
+
block (Block): The block corresponding to the label
|
|
3346
|
+
"""
|
|
3347
|
+
block_id = self.server.blocks_agents_manager.get_block_id_for_label(agent_id=agent_id, block_label=label)
|
|
3348
|
+
return self.server.block_manager.get_block_by_id(block_id, actor=self.user)
|
|
3349
|
+
|
|
3350
|
+
def update_agent_memory_block(
|
|
3351
|
+
self,
|
|
3352
|
+
agent_id: str,
|
|
3353
|
+
label: str,
|
|
3354
|
+
value: Optional[str] = None,
|
|
3355
|
+
limit: Optional[int] = None,
|
|
3356
|
+
):
|
|
3357
|
+
"""
|
|
3358
|
+
Update a block in the agent's core memory by specifying its label
|
|
3359
|
+
|
|
3360
|
+
Args:
|
|
3361
|
+
agent_id (str): The agent ID
|
|
3362
|
+
label (str): The label of the block
|
|
3363
|
+
value (str): The new value of the block
|
|
3364
|
+
limit (int): The new limit of the block
|
|
3365
|
+
|
|
3366
|
+
Returns:
|
|
3367
|
+
block (Block): The updated block
|
|
3368
|
+
"""
|
|
3369
|
+
block = self.get_agent_memory_block(agent_id, label)
|
|
3370
|
+
data = {}
|
|
3371
|
+
if value:
|
|
3372
|
+
data["value"] = value
|
|
3373
|
+
if limit:
|
|
3374
|
+
data["limit"] = limit
|
|
3375
|
+
return self.server.block_manager.update_block(block.id, actor=self.user, block_update=BlockUpdate(**data))
|
|
3376
|
+
|
|
3377
|
+
def update_block(
|
|
3378
|
+
self,
|
|
3379
|
+
block_id: str,
|
|
3380
|
+
label: Optional[str] = None,
|
|
3381
|
+
value: Optional[str] = None,
|
|
3382
|
+
limit: Optional[int] = None,
|
|
3383
|
+
):
|
|
3384
|
+
"""
|
|
3385
|
+
Update a block given the ID with the provided fields
|
|
3386
|
+
|
|
3387
|
+
Args:
|
|
3388
|
+
block_id (str): ID of the block
|
|
3389
|
+
label (str): Label to assign to the block
|
|
3390
|
+
value (str): Value to assign to the block
|
|
3391
|
+
limit (int): Token limit to assign to the block
|
|
3392
|
+
|
|
3393
|
+
Returns:
|
|
3394
|
+
block (Block): Updated block
|
|
3395
|
+
"""
|
|
3396
|
+
data = {}
|
|
3397
|
+
if value:
|
|
3398
|
+
data["value"] = value
|
|
3399
|
+
if limit:
|
|
3400
|
+
data["limit"] = limit
|
|
3401
|
+
if label:
|
|
3402
|
+
data["label"] = label
|
|
3403
|
+
return self.server.block_manager.update_block(block_id, actor=self.user, block_update=BlockUpdate(**data))
|