letta-nightly 0.11.7.dev20250915104130__py3-none-any.whl → 0.11.7.dev20250917104122__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.
- letta/__init__.py +10 -2
- letta/adapters/letta_llm_request_adapter.py +0 -1
- letta/adapters/letta_llm_stream_adapter.py +0 -1
- letta/agent.py +1 -1
- letta/agents/letta_agent.py +1 -4
- letta/agents/letta_agent_v2.py +2 -1
- letta/agents/voice_agent.py +1 -1
- letta/functions/function_sets/multi_agent.py +1 -1
- letta/functions/helpers.py +1 -1
- letta/helpers/converters.py +8 -2
- letta/helpers/crypto_utils.py +144 -0
- letta/llm_api/llm_api_tools.py +0 -1
- letta/llm_api/llm_client_base.py +0 -2
- letta/orm/__init__.py +1 -0
- letta/orm/agent.py +5 -1
- letta/orm/job.py +3 -1
- letta/orm/mcp_oauth.py +6 -0
- letta/orm/mcp_server.py +7 -1
- letta/orm/sqlalchemy_base.py +2 -1
- letta/prompts/gpt_system.py +13 -15
- letta/prompts/system_prompts/__init__.py +27 -0
- letta/prompts/{system/memgpt_chat.txt → system_prompts/memgpt_chat.py} +2 -0
- letta/prompts/{system/memgpt_generate_tool.txt → system_prompts/memgpt_generate_tool.py} +4 -2
- letta/prompts/{system/memgpt_v2_chat.txt → system_prompts/memgpt_v2_chat.py} +2 -0
- letta/prompts/{system/react.txt → system_prompts/react.py} +2 -0
- letta/prompts/{system/sleeptime_doc_ingest.txt → system_prompts/sleeptime_doc_ingest.py} +2 -0
- letta/prompts/{system/sleeptime_v2.txt → system_prompts/sleeptime_v2.py} +2 -0
- letta/prompts/{system/summary_system_prompt.txt → system_prompts/summary_system_prompt.py} +2 -0
- letta/prompts/{system/voice_chat.txt → system_prompts/voice_chat.py} +2 -0
- letta/prompts/{system/voice_sleeptime.txt → system_prompts/voice_sleeptime.py} +2 -0
- letta/prompts/{system/workflow.txt → system_prompts/workflow.py} +2 -0
- letta/schemas/agent.py +10 -7
- letta/schemas/job.py +10 -0
- letta/schemas/mcp.py +146 -6
- letta/schemas/provider_trace.py +0 -2
- letta/schemas/run.py +2 -0
- letta/schemas/secret.py +378 -0
- letta/serialize_schemas/marshmallow_agent.py +4 -0
- letta/server/rest_api/dependencies.py +37 -0
- letta/server/rest_api/routers/openai/chat_completions/chat_completions.py +4 -3
- letta/server/rest_api/routers/v1/__init__.py +2 -0
- letta/server/rest_api/routers/v1/agents.py +115 -107
- letta/server/rest_api/routers/v1/archives.py +113 -0
- letta/server/rest_api/routers/v1/blocks.py +44 -20
- letta/server/rest_api/routers/v1/embeddings.py +3 -3
- letta/server/rest_api/routers/v1/folders.py +107 -47
- letta/server/rest_api/routers/v1/groups.py +52 -32
- letta/server/rest_api/routers/v1/identities.py +110 -21
- letta/server/rest_api/routers/v1/internal_templates.py +28 -13
- letta/server/rest_api/routers/v1/jobs.py +19 -14
- letta/server/rest_api/routers/v1/llms.py +6 -8
- letta/server/rest_api/routers/v1/messages.py +14 -14
- letta/server/rest_api/routers/v1/organizations.py +1 -1
- letta/server/rest_api/routers/v1/providers.py +40 -16
- letta/server/rest_api/routers/v1/runs.py +28 -20
- letta/server/rest_api/routers/v1/sandbox_configs.py +25 -25
- letta/server/rest_api/routers/v1/sources.py +44 -45
- letta/server/rest_api/routers/v1/steps.py +27 -25
- letta/server/rest_api/routers/v1/tags.py +11 -7
- letta/server/rest_api/routers/v1/telemetry.py +11 -6
- letta/server/rest_api/routers/v1/tools.py +78 -80
- letta/server/rest_api/routers/v1/users.py +1 -1
- letta/server/rest_api/routers/v1/voice.py +6 -5
- letta/server/rest_api/utils.py +1 -18
- letta/services/agent_manager.py +17 -9
- letta/services/agent_serialization_manager.py +11 -3
- letta/services/archive_manager.py +73 -0
- letta/services/file_manager.py +6 -0
- letta/services/group_manager.py +2 -1
- letta/services/helpers/agent_manager_helper.py +6 -1
- letta/services/identity_manager.py +67 -0
- letta/services/job_manager.py +18 -2
- letta/services/mcp_manager.py +198 -82
- letta/services/provider_manager.py +14 -1
- letta/services/source_manager.py +11 -1
- letta/services/telemetry_manager.py +2 -0
- letta/services/tool_executor/composio_tool_executor.py +1 -1
- letta/services/tool_manager.py +46 -9
- letta/services/tool_sandbox/base.py +2 -3
- letta/utils.py +4 -2
- {letta_nightly-0.11.7.dev20250915104130.dist-info → letta_nightly-0.11.7.dev20250917104122.dist-info}/METADATA +5 -2
- {letta_nightly-0.11.7.dev20250915104130.dist-info → letta_nightly-0.11.7.dev20250917104122.dist-info}/RECORD +85 -94
- letta/prompts/system/memgpt_base.txt +0 -54
- letta/prompts/system/memgpt_chat_compressed.txt +0 -13
- letta/prompts/system/memgpt_chat_fstring.txt +0 -51
- letta/prompts/system/memgpt_convo_only.txt +0 -12
- letta/prompts/system/memgpt_doc.txt +0 -50
- letta/prompts/system/memgpt_gpt35_extralong.txt +0 -53
- letta/prompts/system/memgpt_intuitive_knowledge.txt +0 -31
- letta/prompts/system/memgpt_memory_only.txt +0 -29
- letta/prompts/system/memgpt_modified_chat.txt +0 -23
- letta/prompts/system/memgpt_modified_o1.txt +0 -31
- letta/prompts/system/memgpt_offline_memory.txt +0 -23
- letta/prompts/system/memgpt_offline_memory_chat.txt +0 -35
- letta/prompts/system/memgpt_sleeptime_chat.txt +0 -52
- letta/prompts/system/sleeptime.txt +0 -37
- {letta_nightly-0.11.7.dev20250915104130.dist-info → letta_nightly-0.11.7.dev20250917104122.dist-info}/WHEEL +0 -0
- {letta_nightly-0.11.7.dev20250915104130.dist-info → letta_nightly-0.11.7.dev20250917104122.dist-info}/entry_points.txt +0 -0
- {letta_nightly-0.11.7.dev20250915104130.dist-info → letta_nightly-0.11.7.dev20250917104122.dist-info}/licenses/LICENSE +0 -0
@@ -13,7 +13,6 @@ from sqlalchemy.exc import IntegrityError, OperationalError
|
|
13
13
|
from starlette.responses import Response, StreamingResponse
|
14
14
|
|
15
15
|
from letta.agents.agent_loop import AgentLoop
|
16
|
-
from letta.agents.letta_agent import LettaAgent
|
17
16
|
from letta.agents.letta_agent_v2 import LettaAgentV2
|
18
17
|
from letta.constants import AGENT_ID_PATTERN, DEFAULT_MAX_STEPS, DEFAULT_MESSAGE_TOOL, DEFAULT_MESSAGE_TOOL_KWARG, REDIS_RUN_ID_PREFIX
|
19
18
|
from letta.data_sources.redis_client import NoopAsyncRedisClient, get_redis_client
|
@@ -24,13 +23,12 @@ from letta.errors import (
|
|
24
23
|
AgentNotFoundForExportError,
|
25
24
|
PendingApprovalError,
|
26
25
|
)
|
27
|
-
from letta.groups.sleeptime_multi_agent_v2 import SleeptimeMultiAgentV2
|
28
26
|
from letta.helpers.datetime_helpers import get_utc_timestamp_ns
|
29
27
|
from letta.log import get_logger
|
30
28
|
from letta.orm.errors import NoResultFound
|
31
29
|
from letta.otel.context import get_ctx_attributes
|
32
30
|
from letta.otel.metric_registry import MetricRegistry
|
33
|
-
from letta.schemas.agent import AgentState,
|
31
|
+
from letta.schemas.agent import AgentState, CreateAgent, UpdateAgent
|
34
32
|
from letta.schemas.agent_file import AgentFileSchema
|
35
33
|
from letta.schemas.block import Block, BlockUpdate
|
36
34
|
from letta.schemas.enums import JobType
|
@@ -40,6 +38,7 @@ from letta.schemas.job import JobStatus, JobUpdate, LettaRequestConfig
|
|
40
38
|
from letta.schemas.letta_message import LettaMessageUnion, LettaMessageUpdateUnion, MessageType
|
41
39
|
from letta.schemas.letta_request import LettaAsyncRequest, LettaRequest, LettaStreamingRequest
|
42
40
|
from letta.schemas.letta_response import LettaResponse
|
41
|
+
from letta.schemas.letta_stop_reason import StopReasonType
|
43
42
|
from letta.schemas.memory import (
|
44
43
|
ArchivalMemorySearchResponse,
|
45
44
|
ArchivalMemorySearchResult,
|
@@ -54,11 +53,9 @@ from letta.schemas.source import Source
|
|
54
53
|
from letta.schemas.tool import Tool
|
55
54
|
from letta.schemas.user import User
|
56
55
|
from letta.serialize_schemas.pydantic_agent_schema import AgentSchema
|
56
|
+
from letta.server.rest_api.dependencies import HeaderParams, get_headers, get_letta_server
|
57
57
|
from letta.server.rest_api.redis_stream_manager import create_background_stream_processor, redis_sse_stream_generator
|
58
|
-
from letta.server.rest_api.utils import get_letta_server
|
59
58
|
from letta.server.server import SyncServer
|
60
|
-
from letta.services.summarizer.enums import SummarizationMode
|
61
|
-
from letta.services.telemetry_manager import NoopTelemetryManager
|
62
59
|
from letta.settings import settings
|
63
60
|
from letta.utils import safe_create_shielded_task, safe_create_task, truncate_file_visible_content
|
64
61
|
|
@@ -79,7 +76,7 @@ async def list_agents(
|
|
79
76
|
description="If True, only returns agents that match ALL given tags. Otherwise, return agents that have ANY of the passed-in tags.",
|
80
77
|
),
|
81
78
|
server: SyncServer = Depends(get_letta_server),
|
82
|
-
|
79
|
+
headers: HeaderParams = Depends(get_headers),
|
83
80
|
before: str | None = Query(None, description="Cursor for pagination"),
|
84
81
|
after: str | None = Query(None, description="Cursor for pagination"),
|
85
82
|
limit: int | None = Query(50, description="Limit for pagination"),
|
@@ -97,13 +94,19 @@ async def list_agents(
|
|
97
94
|
"Using this can optimize performance by reducing unnecessary joins."
|
98
95
|
),
|
99
96
|
),
|
97
|
+
order: Literal["asc", "desc"] = Query(
|
98
|
+
"desc", description="Sort order for agents by creation time. 'asc' for oldest first, 'desc' for newest first"
|
99
|
+
),
|
100
|
+
order_by: Literal["created_at", "last_run_completion"] = Query("created_at", description="Field to sort by"),
|
100
101
|
ascending: bool = Query(
|
101
102
|
False,
|
102
103
|
description="Whether to sort agents oldest to newest (True) or newest to oldest (False, default)",
|
104
|
+
deprecated=True,
|
103
105
|
),
|
104
106
|
sort_by: str | None = Query(
|
105
107
|
"created_at",
|
106
108
|
description="Field to sort by. Options: 'created_at' (default), 'last_run_completion'",
|
109
|
+
deprecated=True,
|
107
110
|
),
|
108
111
|
show_hidden_agents: bool | None = Query(
|
109
112
|
False,
|
@@ -112,14 +115,15 @@ async def list_agents(
|
|
112
115
|
),
|
113
116
|
):
|
114
117
|
"""
|
115
|
-
|
116
|
-
|
117
|
-
This endpoint retrieves a list of all agents and their configurations
|
118
|
-
associated with the specified user ID.
|
118
|
+
Get a list of all agents.
|
119
119
|
"""
|
120
120
|
|
121
121
|
# Retrieve the actor (user) details
|
122
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
122
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
123
|
+
|
124
|
+
# Handle backwards compatibility - prefer new parameters over legacy ones
|
125
|
+
final_ascending = (order == "asc") if order else ascending
|
126
|
+
final_sort_by = order_by if order_by else sort_by
|
123
127
|
|
124
128
|
# Call list_agents directly without unnecessary dict handling
|
125
129
|
return await server.agent_manager.list_agents_async(
|
@@ -137,8 +141,8 @@ async def list_agents(
|
|
137
141
|
identity_id=identity_id,
|
138
142
|
identifier_keys=identifier_keys,
|
139
143
|
include_relationships=include_relationships,
|
140
|
-
ascending=
|
141
|
-
sort_by=
|
144
|
+
ascending=final_ascending,
|
145
|
+
sort_by=final_sort_by,
|
142
146
|
show_hidden_agents=show_hidden_agents,
|
143
147
|
)
|
144
148
|
|
@@ -146,12 +150,12 @@ async def list_agents(
|
|
146
150
|
@router.get("/count", response_model=int, operation_id="count_agents")
|
147
151
|
async def count_agents(
|
148
152
|
server: SyncServer = Depends(get_letta_server),
|
149
|
-
|
153
|
+
headers: HeaderParams = Depends(get_headers),
|
150
154
|
):
|
151
155
|
"""
|
152
|
-
Get the
|
156
|
+
Get the total number of agents.
|
153
157
|
"""
|
154
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
158
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
155
159
|
return await server.agent_manager.size_async(actor=actor)
|
156
160
|
|
157
161
|
|
@@ -167,7 +171,7 @@ async def export_agent(
|
|
167
171
|
agent_id: str,
|
168
172
|
max_steps: int = 100,
|
169
173
|
server: "SyncServer" = Depends(get_letta_server),
|
170
|
-
|
174
|
+
headers: HeaderParams = Depends(get_headers),
|
171
175
|
use_legacy_format: bool = Query(
|
172
176
|
False,
|
173
177
|
description="If true, exports using the legacy single-agent format (v1). If false, exports using the new multi-entity format (v2).",
|
@@ -184,7 +188,7 @@ async def export_agent(
|
|
184
188
|
- Legacy format (use_legacy_format=true): Single agent with inline tools/blocks
|
185
189
|
- New format (default): Multi-entity format with separate agents, tools, blocks, files, etc.
|
186
190
|
"""
|
187
|
-
actor = server.user_manager.get_user_or_default(user_id=actor_id)
|
191
|
+
actor = server.user_manager.get_user_or_default(user_id=headers.actor_id)
|
188
192
|
|
189
193
|
if use_legacy_format:
|
190
194
|
# Use the legacy serialization method
|
@@ -317,7 +321,7 @@ async def _import_agent(
|
|
317
321
|
async def import_agent(
|
318
322
|
file: UploadFile = File(...),
|
319
323
|
server: "SyncServer" = Depends(get_letta_server),
|
320
|
-
|
324
|
+
headers: HeaderParams = Depends(get_headers),
|
321
325
|
x_override_embedding_model: str | None = Header(None, alias="x-override-embedding-model"),
|
322
326
|
append_copy_suffix: bool = Form(True, description='If set to True, appends "_copy" to the end of the agent name.'),
|
323
327
|
override_existing_tools: bool = Form(
|
@@ -341,7 +345,7 @@ async def import_agent(
|
|
341
345
|
Import a serialized agent file and recreate the agent(s) in the system.
|
342
346
|
Returns the IDs of all imported agents.
|
343
347
|
"""
|
344
|
-
actor = server.user_manager.get_user_or_default(user_id=actor_id)
|
348
|
+
actor = server.user_manager.get_user_or_default(user_id=headers.actor_id)
|
345
349
|
|
346
350
|
try:
|
347
351
|
serialized_data = file.file.read()
|
@@ -398,12 +402,12 @@ async def import_agent(
|
|
398
402
|
async def retrieve_agent_context_window(
|
399
403
|
agent_id: str,
|
400
404
|
server: "SyncServer" = Depends(get_letta_server),
|
401
|
-
|
405
|
+
headers: HeaderParams = Depends(get_headers),
|
402
406
|
):
|
403
407
|
"""
|
404
408
|
Retrieve the context window of a specific agent.
|
405
409
|
"""
|
406
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
410
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
407
411
|
try:
|
408
412
|
return await server.agent_manager.get_context_window(agent_id=agent_id, actor=actor)
|
409
413
|
except Exception as e:
|
@@ -424,16 +428,16 @@ class CreateAgentRequest(CreateAgent):
|
|
424
428
|
async def create_agent(
|
425
429
|
agent: CreateAgentRequest = Body(...),
|
426
430
|
server: "SyncServer" = Depends(get_letta_server),
|
427
|
-
|
431
|
+
headers: HeaderParams = Depends(get_headers),
|
428
432
|
x_project: str | None = Header(
|
429
433
|
None, alias="X-Project", description="The project slug to associate with the agent (cloud only)."
|
430
434
|
), # Only handled by next js middleware
|
431
435
|
):
|
432
436
|
"""
|
433
|
-
Create
|
437
|
+
Create an agent.
|
434
438
|
"""
|
435
439
|
try:
|
436
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
440
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
437
441
|
return await server.create_agent_async(agent, actor=actor)
|
438
442
|
except Exception as e:
|
439
443
|
traceback.print_exc()
|
@@ -445,10 +449,10 @@ async def modify_agent(
|
|
445
449
|
agent_id: str,
|
446
450
|
update_agent: UpdateAgent = Body(...),
|
447
451
|
server: "SyncServer" = Depends(get_letta_server),
|
448
|
-
|
452
|
+
headers: HeaderParams = Depends(get_headers),
|
449
453
|
):
|
450
|
-
"""Update an existing agent"""
|
451
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
454
|
+
"""Update an existing agent."""
|
455
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
452
456
|
return await server.update_agent_async(agent_id=agent_id, request=update_agent, actor=actor)
|
453
457
|
|
454
458
|
|
@@ -456,10 +460,10 @@ async def modify_agent(
|
|
456
460
|
async def list_agent_tools(
|
457
461
|
agent_id: str,
|
458
462
|
server: "SyncServer" = Depends(get_letta_server),
|
459
|
-
|
463
|
+
headers: HeaderParams = Depends(get_headers),
|
460
464
|
):
|
461
465
|
"""Get tools from an existing agent"""
|
462
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
466
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
463
467
|
return await server.agent_manager.list_attached_tools_async(agent_id=agent_id, actor=actor)
|
464
468
|
|
465
469
|
|
@@ -468,12 +472,12 @@ async def attach_tool(
|
|
468
472
|
agent_id: str,
|
469
473
|
tool_id: str,
|
470
474
|
server: "SyncServer" = Depends(get_letta_server),
|
471
|
-
|
475
|
+
headers: HeaderParams = Depends(get_headers),
|
472
476
|
):
|
473
477
|
"""
|
474
478
|
Attach a tool to an agent.
|
475
479
|
"""
|
476
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
480
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
477
481
|
await server.agent_manager.attach_tool_async(agent_id=agent_id, tool_id=tool_id, actor=actor)
|
478
482
|
# TODO: Unfortunately we need this to preserve our current API behavior
|
479
483
|
return await server.agent_manager.get_agent_by_id_async(agent_id=agent_id, actor=actor)
|
@@ -484,12 +488,12 @@ async def detach_tool(
|
|
484
488
|
agent_id: str,
|
485
489
|
tool_id: str,
|
486
490
|
server: "SyncServer" = Depends(get_letta_server),
|
487
|
-
|
491
|
+
headers: HeaderParams = Depends(get_headers),
|
488
492
|
):
|
489
493
|
"""
|
490
494
|
Detach a tool from an agent.
|
491
495
|
"""
|
492
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
496
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
493
497
|
await server.agent_manager.detach_tool_async(agent_id=agent_id, tool_id=tool_id, actor=actor)
|
494
498
|
# TODO: Unfortunately we need this to preserve our current API behavior
|
495
499
|
return await server.agent_manager.get_agent_by_id_async(agent_id=agent_id, actor=actor)
|
@@ -501,12 +505,12 @@ async def modify_approval(
|
|
501
505
|
tool_name: str,
|
502
506
|
requires_approval: bool,
|
503
507
|
server: "SyncServer" = Depends(get_letta_server),
|
504
|
-
|
508
|
+
headers: HeaderParams = Depends(get_headers),
|
505
509
|
):
|
506
510
|
"""
|
507
511
|
Attach a tool to an agent.
|
508
512
|
"""
|
509
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
513
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
510
514
|
await server.agent_manager.modify_approvals_async(
|
511
515
|
agent_id=agent_id, tool_name=tool_name, requires_approval=requires_approval, actor=actor
|
512
516
|
)
|
@@ -519,12 +523,12 @@ async def attach_source(
|
|
519
523
|
agent_id: str,
|
520
524
|
source_id: str,
|
521
525
|
server: "SyncServer" = Depends(get_letta_server),
|
522
|
-
|
526
|
+
headers: HeaderParams = Depends(get_headers),
|
523
527
|
):
|
524
528
|
"""
|
525
529
|
Attach a source to an agent.
|
526
530
|
"""
|
527
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
531
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
528
532
|
agent_state = await server.agent_manager.attach_source_async(agent_id=agent_id, source_id=source_id, actor=actor)
|
529
533
|
|
530
534
|
# Check if the agent is missing any files tools
|
@@ -546,12 +550,12 @@ async def attach_folder_to_agent(
|
|
546
550
|
agent_id: str,
|
547
551
|
folder_id: str,
|
548
552
|
server: "SyncServer" = Depends(get_letta_server),
|
549
|
-
|
553
|
+
headers: HeaderParams = Depends(get_headers),
|
550
554
|
):
|
551
555
|
"""
|
552
556
|
Attach a folder to an agent.
|
553
557
|
"""
|
554
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
558
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
555
559
|
agent_state = await server.agent_manager.attach_source_async(agent_id=agent_id, source_id=folder_id, actor=actor)
|
556
560
|
|
557
561
|
# Check if the agent is missing any files tools
|
@@ -573,12 +577,12 @@ async def detach_source(
|
|
573
577
|
agent_id: str,
|
574
578
|
source_id: str,
|
575
579
|
server: "SyncServer" = Depends(get_letta_server),
|
576
|
-
|
580
|
+
headers: HeaderParams = Depends(get_headers),
|
577
581
|
):
|
578
582
|
"""
|
579
583
|
Detach a source from an agent.
|
580
584
|
"""
|
581
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
585
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
582
586
|
agent_state = await server.agent_manager.detach_source_async(agent_id=agent_id, source_id=source_id, actor=actor)
|
583
587
|
|
584
588
|
if not agent_state.sources:
|
@@ -603,12 +607,12 @@ async def detach_folder_from_agent(
|
|
603
607
|
agent_id: str,
|
604
608
|
folder_id: str,
|
605
609
|
server: "SyncServer" = Depends(get_letta_server),
|
606
|
-
|
610
|
+
headers: HeaderParams = Depends(get_headers),
|
607
611
|
):
|
608
612
|
"""
|
609
613
|
Detach a folder from an agent.
|
610
614
|
"""
|
611
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
615
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
612
616
|
agent_state = await server.agent_manager.detach_source_async(agent_id=agent_id, source_id=folder_id, actor=actor)
|
613
617
|
|
614
618
|
if not agent_state.sources:
|
@@ -632,7 +636,7 @@ async def detach_folder_from_agent(
|
|
632
636
|
async def close_all_open_files(
|
633
637
|
agent_id: str,
|
634
638
|
server: "SyncServer" = Depends(get_letta_server),
|
635
|
-
|
639
|
+
headers: HeaderParams = Depends(get_headers),
|
636
640
|
):
|
637
641
|
"""
|
638
642
|
Closes all currently open files for a given agent.
|
@@ -640,7 +644,7 @@ async def close_all_open_files(
|
|
640
644
|
This endpoint updates the file state for the agent so that no files are marked as open.
|
641
645
|
Typically used to reset the working memory view for the agent.
|
642
646
|
"""
|
643
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
647
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
644
648
|
|
645
649
|
return await server.file_agent_manager.close_all_other_files(agent_id=agent_id, keep_file_names=[], actor=actor)
|
646
650
|
|
@@ -650,7 +654,7 @@ async def open_file(
|
|
650
654
|
agent_id: str,
|
651
655
|
file_id: str,
|
652
656
|
server: "SyncServer" = Depends(get_letta_server),
|
653
|
-
|
657
|
+
headers: HeaderParams = Depends(get_headers),
|
654
658
|
):
|
655
659
|
"""
|
656
660
|
Opens a specific file for a given agent.
|
@@ -659,7 +663,7 @@ async def open_file(
|
|
659
663
|
The file will be included in the agent's working memory view.
|
660
664
|
Returns a list of file names that were closed due to LRU eviction.
|
661
665
|
"""
|
662
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
666
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
663
667
|
|
664
668
|
# Get the agent to access files configuration
|
665
669
|
try:
|
@@ -702,7 +706,7 @@ async def close_file(
|
|
702
706
|
agent_id: str,
|
703
707
|
file_id: str,
|
704
708
|
server: "SyncServer" = Depends(get_letta_server),
|
705
|
-
|
709
|
+
headers: HeaderParams = Depends(get_headers),
|
706
710
|
):
|
707
711
|
"""
|
708
712
|
Closes a specific file for a given agent.
|
@@ -710,7 +714,7 @@ async def close_file(
|
|
710
714
|
This endpoint marks a specific file as closed in the agent's file state.
|
711
715
|
The file will be removed from the agent's working memory view.
|
712
716
|
"""
|
713
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
717
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
714
718
|
|
715
719
|
# Use update_file_agent_by_id to close the file
|
716
720
|
try:
|
@@ -737,7 +741,7 @@ async def retrieve_agent(
|
|
737
741
|
),
|
738
742
|
),
|
739
743
|
server: "SyncServer" = Depends(get_letta_server),
|
740
|
-
|
744
|
+
headers: HeaderParams = Depends(get_headers),
|
741
745
|
):
|
742
746
|
"""
|
743
747
|
Get the state of the agent.
|
@@ -746,7 +750,7 @@ async def retrieve_agent(
|
|
746
750
|
if not AGENT_ID_PATTERN.match(agent_id):
|
747
751
|
raise HTTPException(status_code=400, detail=f"agent_id {agent_id} is not in the valid format 'agent-<uuid4>'")
|
748
752
|
|
749
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
753
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
750
754
|
|
751
755
|
try:
|
752
756
|
return await server.agent_manager.get_agent_by_id_async(agent_id=agent_id, include_relationships=include_relationships, actor=actor)
|
@@ -758,12 +762,12 @@ async def retrieve_agent(
|
|
758
762
|
async def delete_agent(
|
759
763
|
agent_id: str,
|
760
764
|
server: "SyncServer" = Depends(get_letta_server),
|
761
|
-
|
765
|
+
headers: HeaderParams = Depends(get_headers),
|
762
766
|
):
|
763
767
|
"""
|
764
768
|
Delete an agent.
|
765
769
|
"""
|
766
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
770
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
767
771
|
try:
|
768
772
|
await server.agent_manager.delete_agent_async(agent_id=agent_id, actor=actor)
|
769
773
|
return JSONResponse(status_code=status.HTTP_200_OK, content={"message": f"Agent id={agent_id} successfully deleted"})
|
@@ -775,12 +779,12 @@ async def delete_agent(
|
|
775
779
|
async def list_agent_sources(
|
776
780
|
agent_id: str,
|
777
781
|
server: "SyncServer" = Depends(get_letta_server),
|
778
|
-
|
782
|
+
headers: HeaderParams = Depends(get_headers),
|
779
783
|
):
|
780
784
|
"""
|
781
785
|
Get the sources associated with an agent.
|
782
786
|
"""
|
783
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
787
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
784
788
|
return await server.agent_manager.list_attached_sources_async(agent_id=agent_id, actor=actor)
|
785
789
|
|
786
790
|
|
@@ -788,12 +792,12 @@ async def list_agent_sources(
|
|
788
792
|
async def list_agent_folders(
|
789
793
|
agent_id: str,
|
790
794
|
server: "SyncServer" = Depends(get_letta_server),
|
791
|
-
|
795
|
+
headers: HeaderParams = Depends(get_headers),
|
792
796
|
):
|
793
797
|
"""
|
794
798
|
Get the folders associated with an agent.
|
795
799
|
"""
|
796
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
800
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
797
801
|
return await server.agent_manager.list_attached_sources_async(agent_id=agent_id, actor=actor)
|
798
802
|
|
799
803
|
|
@@ -804,12 +808,12 @@ async def list_agent_files(
|
|
804
808
|
limit: int = Query(20, ge=1, le=100, description="Number of items to return (1-100)"),
|
805
809
|
is_open: Optional[bool] = Query(None, description="Filter by open status (true for open files, false for closed files)"),
|
806
810
|
server: "SyncServer" = Depends(get_letta_server),
|
807
|
-
|
811
|
+
headers: HeaderParams = Depends(get_headers),
|
808
812
|
):
|
809
813
|
"""
|
810
814
|
Get the files attached to an agent with their open/closed status (paginated).
|
811
815
|
"""
|
812
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
816
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
813
817
|
|
814
818
|
# get paginated file-agent relationships for this agent
|
815
819
|
file_agents, next_cursor, has_more = await server.file_agent_manager.list_files_for_agent_paginated(
|
@@ -845,13 +849,13 @@ async def list_agent_files(
|
|
845
849
|
async def retrieve_agent_memory(
|
846
850
|
agent_id: str,
|
847
851
|
server: "SyncServer" = Depends(get_letta_server),
|
848
|
-
|
852
|
+
headers: HeaderParams = Depends(get_headers),
|
849
853
|
):
|
850
854
|
"""
|
851
855
|
Retrieve the memory state of a specific agent.
|
852
856
|
This endpoint fetches the current memory state of the agent identified by the user ID and agent ID.
|
853
857
|
"""
|
854
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
858
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
855
859
|
|
856
860
|
return await server.get_agent_memory_async(agent_id=agent_id, actor=actor)
|
857
861
|
|
@@ -861,12 +865,12 @@ async def retrieve_block(
|
|
861
865
|
agent_id: str,
|
862
866
|
block_label: str,
|
863
867
|
server: "SyncServer" = Depends(get_letta_server),
|
864
|
-
|
868
|
+
headers: HeaderParams = Depends(get_headers),
|
865
869
|
):
|
866
870
|
"""
|
867
871
|
Retrieve a core memory block from an agent.
|
868
872
|
"""
|
869
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
873
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
870
874
|
|
871
875
|
try:
|
872
876
|
return await server.agent_manager.get_block_with_label_async(agent_id=agent_id, block_label=block_label, actor=actor)
|
@@ -878,12 +882,12 @@ async def retrieve_block(
|
|
878
882
|
async def list_blocks(
|
879
883
|
agent_id: str,
|
880
884
|
server: "SyncServer" = Depends(get_letta_server),
|
881
|
-
|
885
|
+
headers: HeaderParams = Depends(get_headers),
|
882
886
|
):
|
883
887
|
"""
|
884
888
|
Retrieve the core memory blocks of a specific agent.
|
885
889
|
"""
|
886
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
890
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
887
891
|
try:
|
888
892
|
agent = await server.agent_manager.get_agent_by_id_async(agent_id=agent_id, include_relationships=["memory"], actor=actor)
|
889
893
|
return agent.memory.blocks
|
@@ -897,12 +901,12 @@ async def modify_block(
|
|
897
901
|
block_label: str,
|
898
902
|
block_update: BlockUpdate = Body(...),
|
899
903
|
server: "SyncServer" = Depends(get_letta_server),
|
900
|
-
|
904
|
+
headers: HeaderParams = Depends(get_headers),
|
901
905
|
):
|
902
906
|
"""
|
903
907
|
Updates a core memory block of an agent.
|
904
908
|
"""
|
905
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
909
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
906
910
|
|
907
911
|
block = await server.agent_manager.modify_block_by_label_async(
|
908
912
|
agent_id=agent_id, block_label=block_label, block_update=block_update, actor=actor
|
@@ -919,12 +923,12 @@ async def attach_block(
|
|
919
923
|
agent_id: str,
|
920
924
|
block_id: str,
|
921
925
|
server: "SyncServer" = Depends(get_letta_server),
|
922
|
-
|
926
|
+
headers: HeaderParams = Depends(get_headers),
|
923
927
|
):
|
924
928
|
"""
|
925
929
|
Attach a core memory block to an agent.
|
926
930
|
"""
|
927
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
931
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
928
932
|
return await server.agent_manager.attach_block_async(agent_id=agent_id, block_id=block_id, actor=actor)
|
929
933
|
|
930
934
|
|
@@ -933,12 +937,12 @@ async def detach_block(
|
|
933
937
|
agent_id: str,
|
934
938
|
block_id: str,
|
935
939
|
server: "SyncServer" = Depends(get_letta_server),
|
936
|
-
|
940
|
+
headers: HeaderParams = Depends(get_headers),
|
937
941
|
):
|
938
942
|
"""
|
939
943
|
Detach a core memory block from an agent.
|
940
944
|
"""
|
941
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
945
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
942
946
|
return await server.agent_manager.detach_block_async(agent_id=agent_id, block_id=block_id, actor=actor)
|
943
947
|
|
944
948
|
|
@@ -953,12 +957,12 @@ async def list_passages(
|
|
953
957
|
ascending: bool | None = Query(
|
954
958
|
True, description="Whether to sort passages oldest to newest (True, default) or newest to oldest (False)"
|
955
959
|
),
|
956
|
-
|
960
|
+
headers: HeaderParams = Depends(get_headers),
|
957
961
|
):
|
958
962
|
"""
|
959
963
|
Retrieve the memories in an agent's archival memory store (paginated query).
|
960
964
|
"""
|
961
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
965
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
962
966
|
|
963
967
|
return await server.get_agent_archival_async(
|
964
968
|
agent_id=agent_id,
|
@@ -976,12 +980,12 @@ async def create_passage(
|
|
976
980
|
agent_id: str,
|
977
981
|
request: CreateArchivalMemory = Body(...),
|
978
982
|
server: "SyncServer" = Depends(get_letta_server),
|
979
|
-
|
983
|
+
headers: HeaderParams = Depends(get_headers),
|
980
984
|
):
|
981
985
|
"""
|
982
986
|
Insert a memory into an agent's archival memory store.
|
983
987
|
"""
|
984
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
988
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
985
989
|
|
986
990
|
return await server.insert_archival_memory_async(
|
987
991
|
agent_id=agent_id, memory_contents=request.text, actor=actor, tags=request.tags, created_at=request.created_at
|
@@ -1000,7 +1004,7 @@ async def search_archival_memory(
|
|
1000
1004
|
start_datetime: Optional[datetime] = Query(None, description="Filter results to passages created after this datetime"),
|
1001
1005
|
end_datetime: Optional[datetime] = Query(None, description="Filter results to passages created before this datetime"),
|
1002
1006
|
server: "SyncServer" = Depends(get_letta_server),
|
1003
|
-
|
1007
|
+
headers: HeaderParams = Depends(get_headers),
|
1004
1008
|
):
|
1005
1009
|
"""
|
1006
1010
|
Search archival memory using semantic (embedding-based) search with optional temporal filtering.
|
@@ -1009,7 +1013,7 @@ async def search_archival_memory(
|
|
1009
1013
|
an agent's archival memory store directly via the API. The search uses the same functionality
|
1010
1014
|
as the agent's archival_memory_search tool but is accessible for external API usage.
|
1011
1015
|
"""
|
1012
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
1016
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
1013
1017
|
|
1014
1018
|
try:
|
1015
1019
|
# convert datetime to string in ISO 8601 format
|
@@ -1049,12 +1053,12 @@ async def delete_passage(
|
|
1049
1053
|
memory_id: str,
|
1050
1054
|
# memory_id: str = Query(..., description="Unique ID of the memory to be deleted."),
|
1051
1055
|
server: "SyncServer" = Depends(get_letta_server),
|
1052
|
-
|
1056
|
+
headers: HeaderParams = Depends(get_headers),
|
1053
1057
|
):
|
1054
1058
|
"""
|
1055
1059
|
Delete a memory from an agent's archival memory store.
|
1056
1060
|
"""
|
1057
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
1061
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
1058
1062
|
|
1059
1063
|
await server.delete_archival_memory_async(memory_id=memory_id, actor=actor)
|
1060
1064
|
return JSONResponse(status_code=status.HTTP_200_OK, content={"message": f"Memory id={memory_id} successfully deleted"})
|
@@ -1079,12 +1083,12 @@ async def list_messages(
|
|
1079
1083
|
include_err: bool | None = Query(
|
1080
1084
|
None, description="Whether to include error messages and error statuses. For debugging purposes only."
|
1081
1085
|
),
|
1082
|
-
|
1086
|
+
headers: HeaderParams = Depends(get_headers),
|
1083
1087
|
):
|
1084
1088
|
"""
|
1085
1089
|
Retrieve message history for an agent.
|
1086
1090
|
"""
|
1087
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
1091
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
1088
1092
|
|
1089
1093
|
return await server.get_agent_recall_async(
|
1090
1094
|
agent_id=agent_id,
|
@@ -1108,13 +1112,13 @@ def modify_message(
|
|
1108
1112
|
message_id: str,
|
1109
1113
|
request: LettaMessageUpdateUnion = Body(...),
|
1110
1114
|
server: "SyncServer" = Depends(get_letta_server),
|
1111
|
-
|
1115
|
+
headers: HeaderParams = Depends(get_headers),
|
1112
1116
|
):
|
1113
1117
|
"""
|
1114
1118
|
Update the details of a message associated with an agent.
|
1115
1119
|
"""
|
1116
1120
|
# TODO: support modifying tool calls/returns
|
1117
|
-
actor = server.user_manager.get_user_or_default(user_id=actor_id)
|
1121
|
+
actor = server.user_manager.get_user_or_default(user_id=headers.actor_id)
|
1118
1122
|
return server.message_manager.update_message_by_letta_message(message_id=message_id, letta_message_update=request, actor=actor)
|
1119
1123
|
|
1120
1124
|
|
@@ -1129,7 +1133,7 @@ async def send_message(
|
|
1129
1133
|
request_obj: Request, # FastAPI Request
|
1130
1134
|
server: SyncServer = Depends(get_letta_server),
|
1131
1135
|
request: LettaRequest = Body(...),
|
1132
|
-
|
1136
|
+
headers: HeaderParams = Depends(get_headers),
|
1133
1137
|
):
|
1134
1138
|
"""
|
1135
1139
|
Process a user message and return the agent's response.
|
@@ -1140,7 +1144,7 @@ async def send_message(
|
|
1140
1144
|
request_start_timestamp_ns = get_utc_timestamp_ns()
|
1141
1145
|
MetricRegistry().user_message_counter.add(1, get_ctx_attributes())
|
1142
1146
|
|
1143
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
1147
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
1144
1148
|
# TODO: This is redundant, remove soon
|
1145
1149
|
agent = await server.agent_manager.get_agent_by_id_async(
|
1146
1150
|
agent_id, actor, include_relationships=["memory", "multi_agent_group", "sources", "tool_exec_environment_variables", "tools"]
|
@@ -1189,6 +1193,7 @@ async def send_message(
|
|
1189
1193
|
await redis_client.set(f"{REDIS_RUN_ID_PREFIX}:{agent_id}", run.id if run else None)
|
1190
1194
|
|
1191
1195
|
try:
|
1196
|
+
result = None
|
1192
1197
|
if agent_eligible and model_compatible:
|
1193
1198
|
agent_loop = AgentLoop.load(agent_state=agent, actor=actor)
|
1194
1199
|
result = await agent_loop.step(
|
@@ -1226,11 +1231,17 @@ async def send_message(
|
|
1226
1231
|
raise
|
1227
1232
|
finally:
|
1228
1233
|
if settings.track_agent_run:
|
1234
|
+
if result:
|
1235
|
+
stop_reason = result.stop_reason.stop_reason
|
1236
|
+
else:
|
1237
|
+
# NOTE: we could also consider this an error?
|
1238
|
+
stop_reason = None
|
1229
1239
|
await server.job_manager.safe_update_job_status_async(
|
1230
1240
|
job_id=run.id,
|
1231
1241
|
new_status=job_status,
|
1232
1242
|
actor=actor,
|
1233
1243
|
metadata=job_update_metadata,
|
1244
|
+
stop_reason=stop_reason,
|
1234
1245
|
)
|
1235
1246
|
|
1236
1247
|
|
@@ -1253,7 +1264,7 @@ async def send_message_streaming(
|
|
1253
1264
|
request_obj: Request, # FastAPI Request
|
1254
1265
|
server: SyncServer = Depends(get_letta_server),
|
1255
1266
|
request: LettaStreamingRequest = Body(...),
|
1256
|
-
|
1267
|
+
headers: HeaderParams = Depends(get_headers),
|
1257
1268
|
) -> StreamingResponse | LettaResponse:
|
1258
1269
|
"""
|
1259
1270
|
Process a user message and return the agent's response.
|
@@ -1266,7 +1277,7 @@ async def send_message_streaming(
|
|
1266
1277
|
# TODO (cliandy): clean this up
|
1267
1278
|
redis_client = await get_redis_client()
|
1268
1279
|
|
1269
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
1280
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
1270
1281
|
# TODO: This is redundant, remove soon
|
1271
1282
|
agent = await server.agent_manager.get_agent_by_id_async(
|
1272
1283
|
agent_id, actor, include_relationships=["memory", "multi_agent_group", "sources", "tool_exec_environment_variables", "tools"]
|
@@ -1437,10 +1448,7 @@ async def send_message_streaming(
|
|
1437
1448
|
finally:
|
1438
1449
|
if settings.track_agent_run:
|
1439
1450
|
await server.job_manager.safe_update_job_status_async(
|
1440
|
-
job_id=run.id,
|
1441
|
-
new_status=job_status,
|
1442
|
-
actor=actor,
|
1443
|
-
metadata=job_update_metadata,
|
1451
|
+
job_id=run.id, new_status=job_status, actor=actor, metadata=job_update_metadata
|
1444
1452
|
)
|
1445
1453
|
|
1446
1454
|
|
@@ -1453,14 +1461,14 @@ async def cancel_agent_run(
|
|
1453
1461
|
agent_id: str,
|
1454
1462
|
request: CancelAgentRunRequest = Body(None),
|
1455
1463
|
server: SyncServer = Depends(get_letta_server),
|
1456
|
-
|
1464
|
+
headers: HeaderParams = Depends(get_headers),
|
1457
1465
|
) -> dict:
|
1458
1466
|
"""
|
1459
1467
|
Cancel runs associated with an agent. If run_ids are passed in, cancel those in particular.
|
1460
1468
|
|
1461
1469
|
Note to cancel active runs associated with an agent, redis is required.
|
1462
1470
|
"""
|
1463
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
1471
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
1464
1472
|
if not settings.track_agent_run:
|
1465
1473
|
raise HTTPException(status_code=400, detail="Agent run tracking is disabled")
|
1466
1474
|
run_ids = request.run_ids if request else None
|
@@ -1494,14 +1502,14 @@ async def cancel_agent_run(
|
|
1494
1502
|
async def search_messages(
|
1495
1503
|
request: MessageSearchRequest = Body(...),
|
1496
1504
|
server: SyncServer = Depends(get_letta_server),
|
1497
|
-
|
1505
|
+
headers: HeaderParams = Depends(get_headers),
|
1498
1506
|
):
|
1499
1507
|
"""
|
1500
1508
|
Search messages across the entire organization with optional project and template filtering. Returns messages with FTS/vector ranks and total RRF score.
|
1501
1509
|
|
1502
1510
|
This is a cloud-only feature.
|
1503
1511
|
"""
|
1504
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
1512
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
1505
1513
|
|
1506
1514
|
# get embedding config from the default agent if needed
|
1507
1515
|
# check if any agents exist in the org
|
@@ -1617,7 +1625,7 @@ async def send_message_async(
|
|
1617
1625
|
agent_id: str,
|
1618
1626
|
server: SyncServer = Depends(get_letta_server),
|
1619
1627
|
request: LettaAsyncRequest = Body(...),
|
1620
|
-
|
1628
|
+
headers: HeaderParams = Depends(get_headers),
|
1621
1629
|
):
|
1622
1630
|
"""
|
1623
1631
|
Asynchronously process a user message and return a run object.
|
@@ -1627,7 +1635,7 @@ async def send_message_async(
|
|
1627
1635
|
This is more like `send_message_job`
|
1628
1636
|
"""
|
1629
1637
|
MetricRegistry().user_message_counter.add(1, get_ctx_attributes())
|
1630
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
1638
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
1631
1639
|
|
1632
1640
|
# Create a new job
|
1633
1641
|
run = Run(
|
@@ -1696,10 +1704,10 @@ async def reset_messages(
|
|
1696
1704
|
agent_id: str,
|
1697
1705
|
add_default_initial_messages: bool = Query(default=False, description="If true, adds the default initial messages after resetting."),
|
1698
1706
|
server: "SyncServer" = Depends(get_letta_server),
|
1699
|
-
|
1707
|
+
headers: HeaderParams = Depends(get_headers),
|
1700
1708
|
):
|
1701
1709
|
"""Resets the messages for an agent"""
|
1702
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
1710
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
1703
1711
|
return await server.agent_manager.reset_messages_async(
|
1704
1712
|
agent_id=agent_id, actor=actor, add_default_initial_messages=add_default_initial_messages
|
1705
1713
|
)
|
@@ -1710,10 +1718,10 @@ async def list_agent_groups(
|
|
1710
1718
|
agent_id: str,
|
1711
1719
|
manager_type: str | None = Query(None, description="Manager type to filter groups by"),
|
1712
1720
|
server: "SyncServer" = Depends(get_letta_server),
|
1713
|
-
|
1721
|
+
headers: HeaderParams = Depends(get_headers),
|
1714
1722
|
):
|
1715
1723
|
"""Lists the groups for an agent"""
|
1716
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
1724
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
1717
1725
|
logger.info("in list agents with manager_type", manager_type)
|
1718
1726
|
return server.agent_manager.list_groups(agent_id=agent_id, manager_type=manager_type, actor=actor)
|
1719
1727
|
|
@@ -1727,7 +1735,7 @@ async def preview_raw_payload(
|
|
1727
1735
|
agent_id: str,
|
1728
1736
|
request: Union[LettaRequest, LettaStreamingRequest] = Body(...),
|
1729
1737
|
server: SyncServer = Depends(get_letta_server),
|
1730
|
-
|
1738
|
+
headers: HeaderParams = Depends(get_headers),
|
1731
1739
|
):
|
1732
1740
|
"""
|
1733
1741
|
Inspect the raw LLM request payload without sending it.
|
@@ -1736,7 +1744,7 @@ async def preview_raw_payload(
|
|
1736
1744
|
the LLM request, then returns the raw request payload that would
|
1737
1745
|
be sent to the LLM provider. Useful for debugging and inspection.
|
1738
1746
|
"""
|
1739
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
1747
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
1740
1748
|
agent = await server.agent_manager.get_agent_by_id_async(agent_id, actor, include_relationships=["multi_agent_group"])
|
1741
1749
|
agent_eligible = agent.multi_agent_group is None or agent.multi_agent_group.manager_type in ["sleeptime", "voice_sleeptime"]
|
1742
1750
|
model_compatible = agent.llm_config.model_endpoint_type in [
|
@@ -1771,7 +1779,7 @@ async def summarize_agent_conversation(
|
|
1771
1779
|
request_obj: Request, # FastAPI Request
|
1772
1780
|
max_message_length: int = Query(..., description="Maximum number of messages to retain after summarization."),
|
1773
1781
|
server: SyncServer = Depends(get_letta_server),
|
1774
|
-
|
1782
|
+
headers: HeaderParams = Depends(get_headers),
|
1775
1783
|
):
|
1776
1784
|
"""
|
1777
1785
|
Summarize an agent's conversation history to a target message length.
|
@@ -1780,7 +1788,7 @@ async def summarize_agent_conversation(
|
|
1780
1788
|
truncating and compressing it down to the specified `max_message_length`.
|
1781
1789
|
"""
|
1782
1790
|
|
1783
|
-
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
|
1791
|
+
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
1784
1792
|
agent = await server.agent_manager.get_agent_by_id_async(agent_id, actor, include_relationships=["multi_agent_group"])
|
1785
1793
|
agent_eligible = agent.multi_agent_group is None or agent.multi_agent_group.manager_type in ["sleeptime", "voice_sleeptime"]
|
1786
1794
|
model_compatible = agent.llm_config.model_endpoint_type in [
|