letta-nightly 0.11.7.dev20251007104119__py3-none-any.whl → 0.11.7.dev20251008104128__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.
Files changed (145) hide show
  1. letta/adapters/letta_llm_adapter.py +1 -0
  2. letta/adapters/letta_llm_request_adapter.py +0 -1
  3. letta/adapters/letta_llm_stream_adapter.py +7 -2
  4. letta/adapters/simple_llm_request_adapter.py +88 -0
  5. letta/adapters/simple_llm_stream_adapter.py +192 -0
  6. letta/agents/agent_loop.py +6 -0
  7. letta/agents/ephemeral_summary_agent.py +2 -1
  8. letta/agents/helpers.py +142 -6
  9. letta/agents/letta_agent.py +13 -33
  10. letta/agents/letta_agent_batch.py +2 -4
  11. letta/agents/letta_agent_v2.py +87 -77
  12. letta/agents/letta_agent_v3.py +899 -0
  13. letta/agents/voice_agent.py +2 -6
  14. letta/constants.py +8 -4
  15. letta/errors.py +40 -0
  16. letta/functions/function_sets/base.py +84 -4
  17. letta/functions/function_sets/multi_agent.py +0 -3
  18. letta/functions/schema_generator.py +113 -71
  19. letta/groups/dynamic_multi_agent.py +3 -2
  20. letta/groups/helpers.py +1 -2
  21. letta/groups/round_robin_multi_agent.py +3 -2
  22. letta/groups/sleeptime_multi_agent.py +3 -2
  23. letta/groups/sleeptime_multi_agent_v2.py +1 -1
  24. letta/groups/sleeptime_multi_agent_v3.py +17 -17
  25. letta/groups/supervisor_multi_agent.py +84 -80
  26. letta/helpers/converters.py +3 -0
  27. letta/helpers/message_helper.py +4 -0
  28. letta/helpers/tool_rule_solver.py +92 -5
  29. letta/interfaces/anthropic_streaming_interface.py +409 -0
  30. letta/interfaces/gemini_streaming_interface.py +296 -0
  31. letta/interfaces/openai_streaming_interface.py +752 -1
  32. letta/llm_api/anthropic_client.py +126 -16
  33. letta/llm_api/bedrock_client.py +4 -2
  34. letta/llm_api/deepseek_client.py +4 -1
  35. letta/llm_api/google_vertex_client.py +123 -42
  36. letta/llm_api/groq_client.py +4 -1
  37. letta/llm_api/llm_api_tools.py +11 -4
  38. letta/llm_api/llm_client_base.py +6 -2
  39. letta/llm_api/openai.py +32 -2
  40. letta/llm_api/openai_client.py +423 -18
  41. letta/llm_api/xai_client.py +4 -1
  42. letta/main.py +9 -5
  43. letta/memory.py +1 -0
  44. letta/orm/__init__.py +1 -1
  45. letta/orm/agent.py +10 -0
  46. letta/orm/block.py +7 -16
  47. letta/orm/blocks_agents.py +8 -2
  48. letta/orm/files_agents.py +2 -0
  49. letta/orm/job.py +7 -5
  50. letta/orm/mcp_oauth.py +1 -0
  51. letta/orm/message.py +21 -6
  52. letta/orm/organization.py +2 -0
  53. letta/orm/provider.py +6 -2
  54. letta/orm/run.py +71 -0
  55. letta/orm/sandbox_config.py +7 -1
  56. letta/orm/sqlalchemy_base.py +0 -306
  57. letta/orm/step.py +6 -5
  58. letta/orm/step_metrics.py +5 -5
  59. letta/otel/tracing.py +28 -3
  60. letta/plugins/defaults.py +4 -4
  61. letta/prompts/system_prompts/__init__.py +2 -0
  62. letta/prompts/system_prompts/letta_v1.py +25 -0
  63. letta/schemas/agent.py +3 -2
  64. letta/schemas/agent_file.py +9 -3
  65. letta/schemas/block.py +23 -10
  66. letta/schemas/enums.py +21 -2
  67. letta/schemas/job.py +17 -4
  68. letta/schemas/letta_message_content.py +71 -2
  69. letta/schemas/letta_stop_reason.py +5 -5
  70. letta/schemas/llm_config.py +53 -3
  71. letta/schemas/memory.py +1 -1
  72. letta/schemas/message.py +504 -117
  73. letta/schemas/openai/responses_request.py +64 -0
  74. letta/schemas/providers/__init__.py +2 -0
  75. letta/schemas/providers/anthropic.py +16 -0
  76. letta/schemas/providers/ollama.py +115 -33
  77. letta/schemas/providers/openrouter.py +52 -0
  78. letta/schemas/providers/vllm.py +2 -1
  79. letta/schemas/run.py +48 -42
  80. letta/schemas/step.py +2 -2
  81. letta/schemas/step_metrics.py +1 -1
  82. letta/schemas/tool.py +15 -107
  83. letta/schemas/tool_rule.py +88 -5
  84. letta/serialize_schemas/marshmallow_agent.py +1 -0
  85. letta/server/db.py +86 -408
  86. letta/server/rest_api/app.py +61 -10
  87. letta/server/rest_api/dependencies.py +14 -0
  88. letta/server/rest_api/redis_stream_manager.py +19 -8
  89. letta/server/rest_api/routers/v1/agents.py +364 -292
  90. letta/server/rest_api/routers/v1/blocks.py +14 -20
  91. letta/server/rest_api/routers/v1/identities.py +45 -110
  92. letta/server/rest_api/routers/v1/internal_templates.py +21 -0
  93. letta/server/rest_api/routers/v1/jobs.py +23 -6
  94. letta/server/rest_api/routers/v1/messages.py +1 -1
  95. letta/server/rest_api/routers/v1/runs.py +126 -85
  96. letta/server/rest_api/routers/v1/sandbox_configs.py +10 -19
  97. letta/server/rest_api/routers/v1/tools.py +281 -594
  98. letta/server/rest_api/routers/v1/voice.py +1 -1
  99. letta/server/rest_api/streaming_response.py +29 -29
  100. letta/server/rest_api/utils.py +122 -64
  101. letta/server/server.py +160 -887
  102. letta/services/agent_manager.py +236 -919
  103. letta/services/agent_serialization_manager.py +16 -0
  104. letta/services/archive_manager.py +0 -100
  105. letta/services/block_manager.py +211 -168
  106. letta/services/file_manager.py +1 -1
  107. letta/services/files_agents_manager.py +24 -33
  108. letta/services/group_manager.py +0 -142
  109. letta/services/helpers/agent_manager_helper.py +7 -2
  110. letta/services/helpers/run_manager_helper.py +85 -0
  111. letta/services/job_manager.py +96 -411
  112. letta/services/lettuce/__init__.py +6 -0
  113. letta/services/lettuce/lettuce_client_base.py +86 -0
  114. letta/services/mcp_manager.py +38 -6
  115. letta/services/message_manager.py +165 -362
  116. letta/services/organization_manager.py +0 -36
  117. letta/services/passage_manager.py +0 -345
  118. letta/services/provider_manager.py +0 -80
  119. letta/services/run_manager.py +301 -0
  120. letta/services/sandbox_config_manager.py +0 -234
  121. letta/services/step_manager.py +62 -39
  122. letta/services/summarizer/summarizer.py +9 -7
  123. letta/services/telemetry_manager.py +0 -16
  124. letta/services/tool_executor/builtin_tool_executor.py +35 -0
  125. letta/services/tool_executor/core_tool_executor.py +397 -2
  126. letta/services/tool_executor/files_tool_executor.py +3 -3
  127. letta/services/tool_executor/multi_agent_tool_executor.py +30 -15
  128. letta/services/tool_executor/tool_execution_manager.py +6 -8
  129. letta/services/tool_executor/tool_executor_base.py +3 -3
  130. letta/services/tool_manager.py +85 -339
  131. letta/services/tool_sandbox/base.py +24 -13
  132. letta/services/tool_sandbox/e2b_sandbox.py +16 -1
  133. letta/services/tool_schema_generator.py +123 -0
  134. letta/services/user_manager.py +0 -99
  135. letta/settings.py +20 -4
  136. {letta_nightly-0.11.7.dev20251007104119.dist-info → letta_nightly-0.11.7.dev20251008104128.dist-info}/METADATA +3 -5
  137. {letta_nightly-0.11.7.dev20251007104119.dist-info → letta_nightly-0.11.7.dev20251008104128.dist-info}/RECORD +140 -132
  138. letta/agents/temporal/activities/__init__.py +0 -4
  139. letta/agents/temporal/activities/example_activity.py +0 -7
  140. letta/agents/temporal/activities/prepare_messages.py +0 -10
  141. letta/agents/temporal/temporal_agent_workflow.py +0 -56
  142. letta/agents/temporal/types.py +0 -25
  143. {letta_nightly-0.11.7.dev20251007104119.dist-info → letta_nightly-0.11.7.dev20251008104128.dist-info}/WHEEL +0 -0
  144. {letta_nightly-0.11.7.dev20251007104119.dist-info → letta_nightly-0.11.7.dev20251008104128.dist-info}/entry_points.txt +0 -0
  145. {letta_nightly-0.11.7.dev20251007104119.dist-info → letta_nightly-0.11.7.dev20251008104128.dist-info}/licenses/LICENSE +0 -0
@@ -154,13 +154,10 @@ async def retrieve_block(
154
154
  headers: HeaderParams = Depends(get_headers),
155
155
  ):
156
156
  actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
157
- try:
158
- block = await server.block_manager.get_block_by_id_async(block_id=block_id, actor=actor)
159
- if block is None:
160
- raise HTTPException(status_code=404, detail="Block not found")
161
- return block
162
- except NoResultFound:
163
- raise HTTPException(status_code=404, detail="Block not found")
157
+ block = await server.block_manager.get_block_by_id_async(block_id=block_id, actor=actor)
158
+ if block is None:
159
+ raise NoResultFound(f"Block with id '{block_id}' not found")
160
+ return block
164
161
 
165
162
 
166
163
  @router.get("/{block_id}/agents", response_model=List[AgentState], operation_id="list_agents_for_block")
@@ -195,16 +192,13 @@ async def list_agents_for_block(
195
192
  Raises a 404 if the block does not exist.
196
193
  """
197
194
  actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
198
- try:
199
- agents = await server.block_manager.get_agents_for_block_async(
200
- block_id=block_id,
201
- before=before,
202
- after=after,
203
- limit=limit,
204
- ascending=(order == "asc"),
205
- include_relationships=include_relationships,
206
- actor=actor,
207
- )
208
- return agents
209
- except NoResultFound:
210
- raise HTTPException(status_code=404, detail=f"Block with id={block_id} not found")
195
+ agents = await server.block_manager.get_agents_for_block_async(
196
+ block_id=block_id,
197
+ before=before,
198
+ after=after,
199
+ limit=limit,
200
+ ascending=(order == "asc"),
201
+ include_relationships=include_relationships,
202
+ actor=actor,
203
+ )
204
+ return agents
@@ -1,6 +1,6 @@
1
1
  from typing import TYPE_CHECKING, List, Literal, Optional
2
2
 
3
- from fastapi import APIRouter, Body, Depends, Header, HTTPException, Query
3
+ from fastapi import APIRouter, Body, Depends, Header, Query
4
4
 
5
5
  from letta.orm.errors import NoResultFound, UniqueConstraintViolationError
6
6
  from letta.schemas.agent import AgentState
@@ -39,26 +39,19 @@ async def list_identities(
39
39
  """
40
40
  Get a list of all identities in the database
41
41
  """
42
- try:
43
- actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
44
-
45
- identities = await server.identity_manager.list_identities_async(
46
- name=name,
47
- project_id=project_id,
48
- identifier_key=identifier_key,
49
- identity_type=identity_type,
50
- before=before,
51
- after=after,
52
- limit=limit,
53
- ascending=(order == "asc"),
54
- actor=actor,
55
- )
56
- except HTTPException:
57
- raise
58
- except NoResultFound as e:
59
- raise HTTPException(status_code=404, detail=str(e))
60
- except Exception as e:
61
- raise HTTPException(status_code=500, detail=f"{e}")
42
+ actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
43
+
44
+ identities = await server.identity_manager.list_identities_async(
45
+ name=name,
46
+ project_id=project_id,
47
+ identifier_key=identifier_key,
48
+ identity_type=identity_type,
49
+ before=before,
50
+ after=after,
51
+ limit=limit,
52
+ ascending=(order == "asc"),
53
+ actor=actor,
54
+ )
62
55
  return identities
63
56
 
64
57
 
@@ -70,15 +63,11 @@ async def count_identities(
70
63
  """
71
64
  Get count of all identities for a user
72
65
  """
66
+ actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
73
67
  try:
74
- actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
75
68
  return await server.identity_manager.size_async(actor=actor)
76
69
  except NoResultFound:
77
70
  return 0
78
- except HTTPException:
79
- raise
80
- except Exception as e:
81
- raise HTTPException(status_code=500, detail=f"{e}")
82
71
 
83
72
 
84
73
  @router.get("/{identity_id}", tags=["identities"], response_model=Identity, operation_id="retrieve_identity")
@@ -87,11 +76,8 @@ async def retrieve_identity(
87
76
  server: "SyncServer" = Depends(get_letta_server),
88
77
  headers: HeaderParams = Depends(get_headers),
89
78
  ):
90
- try:
91
- actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
92
- return await server.identity_manager.get_identity_async(identity_id=identity_id, actor=actor)
93
- except NoResultFound as e:
94
- raise HTTPException(status_code=404, detail=str(e))
79
+ actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
80
+ return await server.identity_manager.get_identity_async(identity_id=identity_id, actor=actor)
95
81
 
96
82
 
97
83
  @router.post("/", tags=["identities"], response_model=Identity, operation_id="create_identity")
@@ -103,21 +89,8 @@ async def create_identity(
103
89
  None, alias="X-Project", description="The project slug to associate with the identity (cloud only)."
104
90
  ), # Only handled by next js middleware
105
91
  ):
106
- try:
107
- actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
108
- return await server.identity_manager.create_identity_async(identity=identity, actor=actor)
109
- except HTTPException:
110
- raise
111
- except UniqueConstraintViolationError:
112
- if identity.project_id:
113
- raise HTTPException(
114
- status_code=409,
115
- detail=f"An identity with identifier key {identity.identifier_key} already exists for project {identity.project_id}",
116
- )
117
- else:
118
- raise HTTPException(status_code=409, detail=f"An identity with identifier key {identity.identifier_key} already exists")
119
- except Exception as e:
120
- raise HTTPException(status_code=500, detail=f"{e}")
92
+ actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
93
+ return await server.identity_manager.create_identity_async(identity=identity, actor=actor)
121
94
 
122
95
 
123
96
  @router.put("/", tags=["identities"], response_model=Identity, operation_id="upsert_identity")
@@ -129,15 +102,8 @@ async def upsert_identity(
129
102
  None, alias="X-Project", description="The project slug to associate with the identity (cloud only)."
130
103
  ), # Only handled by next js middleware
131
104
  ):
132
- try:
133
- actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
134
- return await server.identity_manager.upsert_identity_async(identity=identity, actor=actor)
135
- except HTTPException:
136
- raise
137
- except NoResultFound as e:
138
- raise HTTPException(status_code=404, detail=str(e))
139
- except Exception as e:
140
- raise HTTPException(status_code=500, detail=f"{e}")
105
+ actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
106
+ return await server.identity_manager.upsert_identity_async(identity=identity, actor=actor)
141
107
 
142
108
 
143
109
  @router.patch("/{identity_id}", tags=["identities"], response_model=Identity, operation_id="update_identity")
@@ -147,15 +113,8 @@ async def modify_identity(
147
113
  server: "SyncServer" = Depends(get_letta_server),
148
114
  headers: HeaderParams = Depends(get_headers),
149
115
  ):
150
- try:
151
- actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
152
- return await server.identity_manager.update_identity_async(identity_id=identity_id, identity=identity, actor=actor)
153
- except HTTPException:
154
- raise
155
- except NoResultFound as e:
156
- raise HTTPException(status_code=404, detail=str(e))
157
- except Exception as e:
158
- raise HTTPException(status_code=500, detail=f"{e}")
116
+ actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
117
+ return await server.identity_manager.update_identity_async(identity_id=identity_id, identity=identity, actor=actor)
159
118
 
160
119
 
161
120
  @router.put("/{identity_id}/properties", tags=["identities"], operation_id="upsert_identity_properties")
@@ -165,15 +124,8 @@ async def upsert_identity_properties(
165
124
  server: "SyncServer" = Depends(get_letta_server),
166
125
  headers: HeaderParams = Depends(get_headers),
167
126
  ):
168
- try:
169
- actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
170
- return await server.identity_manager.upsert_identity_properties_async(identity_id=identity_id, properties=properties, actor=actor)
171
- except HTTPException:
172
- raise
173
- except NoResultFound as e:
174
- raise HTTPException(status_code=404, detail=str(e))
175
- except Exception as e:
176
- raise HTTPException(status_code=500, detail=f"{e}")
127
+ actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
128
+ return await server.identity_manager.upsert_identity_properties_async(identity_id=identity_id, properties=properties, actor=actor)
177
129
 
178
130
 
179
131
  @router.delete("/{identity_id}", tags=["identities"], operation_id="delete_identity")
@@ -185,15 +137,8 @@ async def delete_identity(
185
137
  """
186
138
  Delete an identity by its identifier key
187
139
  """
188
- try:
189
- actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
190
- await server.identity_manager.delete_identity_async(identity_id=identity_id, actor=actor)
191
- except HTTPException:
192
- raise
193
- except NoResultFound as e:
194
- raise HTTPException(status_code=404, detail=str(e))
195
- except Exception as e:
196
- raise HTTPException(status_code=500, detail=f"{e}")
140
+ actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
141
+ await server.identity_manager.delete_identity_async(identity_id=identity_id, actor=actor)
197
142
 
198
143
 
199
144
  @router.get("/{identity_id}/agents", response_model=List[AgentState], operation_id="list_agents_for_identity")
@@ -218,20 +163,15 @@ async def list_agents_for_identity(
218
163
  """
219
164
  Get all agents associated with the specified identity.
220
165
  """
221
- try:
222
- actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
223
- return await server.identity_manager.list_agents_for_identity_async(
224
- identity_id=identity_id,
225
- before=before,
226
- after=after,
227
- limit=limit,
228
- ascending=(order == "asc"),
229
- actor=actor,
230
- )
231
- except NoResultFound as e:
232
- raise HTTPException(status_code=404, detail=f"Identity with id={identity_id} not found")
233
- except Exception as e:
234
- raise HTTPException(status_code=500, detail=f"{e}")
166
+ actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
167
+ return await server.identity_manager.list_agents_for_identity_async(
168
+ identity_id=identity_id,
169
+ before=before,
170
+ after=after,
171
+ limit=limit,
172
+ ascending=(order == "asc"),
173
+ actor=actor,
174
+ )
235
175
 
236
176
 
237
177
  @router.get("/{identity_id}/blocks", response_model=List[Block], operation_id="list_blocks_for_identity")
@@ -256,17 +196,12 @@ async def list_blocks_for_identity(
256
196
  """
257
197
  Get all blocks associated with the specified identity.
258
198
  """
259
- try:
260
- actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
261
- return await server.identity_manager.list_blocks_for_identity_async(
262
- identity_id=identity_id,
263
- before=before,
264
- after=after,
265
- limit=limit,
266
- ascending=(order == "asc"),
267
- actor=actor,
268
- )
269
- except NoResultFound as e:
270
- raise HTTPException(status_code=404, detail=f"Identity with id={identity_id} not found")
271
- except Exception as e:
272
- raise HTTPException(status_code=500, detail=f"{e}")
199
+ actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
200
+ return await server.identity_manager.list_blocks_for_identity_async(
201
+ identity_id=identity_id,
202
+ before=before,
203
+ after=after,
204
+ limit=limit,
205
+ ascending=(order == "asc"),
206
+ actor=actor,
207
+ )
@@ -61,6 +61,27 @@ async def create_block(
61
61
  raise HTTPException(status_code=500, detail=str(e))
62
62
 
63
63
 
64
+ @router.post("/blocks/batch", response_model=List[Block], operation_id="create_internal_template_blocks_batch")
65
+ async def create_blocks_batch(
66
+ blocks: List[InternalTemplateBlockCreate] = Body(...),
67
+ server: "SyncServer" = Depends(get_letta_server),
68
+ headers: HeaderParams = Depends(get_headers),
69
+ ):
70
+ """
71
+ Create multiple blocks with template-related fields.
72
+ """
73
+ try:
74
+ actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
75
+ created_blocks = []
76
+ for block in blocks:
77
+ block_obj = Block(**block.model_dump())
78
+ created_block = await server.block_manager.create_or_update_block_async(block_obj, actor=actor)
79
+ created_blocks.append(created_block)
80
+ return created_blocks
81
+ except Exception as e:
82
+ raise HTTPException(status_code=500, detail=str(e))
83
+
84
+
64
85
  class DeploymentEntity(BaseModel):
65
86
  """A deployment entity."""
66
87
 
@@ -1,4 +1,4 @@
1
- from typing import List, Optional
1
+ from typing import List, Literal, Optional
2
2
 
3
3
  from fastapi import APIRouter, Depends, HTTPException, Query
4
4
 
@@ -16,11 +16,23 @@ router = APIRouter(prefix="/jobs", tags=["jobs"])
16
16
  async def list_jobs(
17
17
  server: "SyncServer" = Depends(get_letta_server),
18
18
  source_id: Optional[str] = Query(None, description="Only list jobs associated with the source."),
19
- before: Optional[str] = Query(None, description="Cursor for pagination"),
20
- after: Optional[str] = Query(None, description="Cursor for pagination"),
21
- limit: Optional[int] = Query(50, description="Limit for pagination"),
19
+ before: Optional[str] = Query(
20
+ None, description="Job ID cursor for pagination. Returns jobs that come before this job ID in the specified sort order"
21
+ ),
22
+ after: Optional[str] = Query(
23
+ None, description="Job ID cursor for pagination. Returns jobs that come after this job ID in the specified sort order"
24
+ ),
25
+ limit: Optional[int] = Query(100, description="Maximum number of jobs to return"),
26
+ order: Literal["asc", "desc"] = Query(
27
+ "desc", description="Sort order for jobs by creation time. 'asc' for oldest first, 'desc' for newest first"
28
+ ),
29
+ order_by: Literal["created_at"] = Query("created_at", description="Field to sort by"),
22
30
  active: bool = Query(False, description="Filter for active jobs."),
23
- ascending: bool = Query(True, description="Whether to sort jobs oldest to newest (True, default) or newest to oldest (False)"),
31
+ ascending: bool = Query(
32
+ True,
33
+ description="Whether to sort jobs oldest to newest (True, default) or newest to oldest (False). Deprecated in favor of order field.",
34
+ deprecated=True,
35
+ ),
24
36
  headers: HeaderParams = Depends(get_headers),
25
37
  ):
26
38
  """
@@ -32,6 +44,11 @@ async def list_jobs(
32
44
  if active:
33
45
  statuses = [JobStatus.created, JobStatus.running]
34
46
 
47
+ if ascending is not True:
48
+ sort_ascending = ascending
49
+ else:
50
+ sort_ascending = order == "asc"
51
+
35
52
  # TODO: add filtering by status
36
53
  return await server.job_manager.list_jobs_async(
37
54
  actor=actor,
@@ -40,7 +57,7 @@ async def list_jobs(
40
57
  before=before,
41
58
  after=after,
42
59
  limit=limit,
43
- ascending=ascending,
60
+ ascending=sort_ascending,
44
61
  )
45
62
 
46
63
 
@@ -122,7 +122,7 @@ async def list_batches(
122
122
  """
123
123
  actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
124
124
 
125
- jobs = server.job_manager.list_jobs(
125
+ jobs = await server.job_manager.list_jobs_async(
126
126
  actor=actor,
127
127
  statuses=[JobStatus.created, JobStatus.running],
128
128
  job_type=JobType.BATCH,