letta-nightly 0.6.19.dev20250131104014__tar.gz → 0.6.20.dev20250131222205__tar.gz
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_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/PKG-INFO +1 -1
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/__init__.py +1 -1
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/llm_api/anthropic.py +3 -26
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/llm_api/llm_api_tools.py +21 -21
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/llm_api/openai.py +12 -15
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/agent.py +6 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/custom_columns.py +3 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/agent.py +3 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/sandbox_config.py +43 -1
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/tool_rule.py +9 -6
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/app.py +4 -1
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/__init__.py +2 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/sandbox_configs.py +78 -1
- letta_nightly-0.6.20.dev20250131222205/letta/server/rest_api/routers/v1/steps.py +78 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/tools.py +23 -9
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/server.py +0 -3
- letta_nightly-0.6.20.dev20250131222205/letta/services/helpers/tool_execution_helper.py +155 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/services/step_manager.py +55 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/services/tool_execution_sandbox.py +25 -36
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/settings.py +1 -1
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/system.py +14 -1
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/pyproject.toml +1 -1
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/LICENSE +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/README.md +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/__main__.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/agent.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/benchmark/benchmark.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/benchmark/constants.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/chat_only_agent.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/cli/cli.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/cli/cli_config.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/cli/cli_load.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/client/__init__.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/client/client.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/client/streaming.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/client/utils.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/config.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/constants.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/data_sources/connectors.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/data_sources/connectors_helper.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/embeddings.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/errors.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/functions/__init__.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/functions/ast_parsers.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/functions/function_sets/base.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/functions/function_sets/extras.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/functions/function_sets/multi_agent.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/functions/functions.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/functions/helpers.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/functions/schema_generator.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/helpers/__init__.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/helpers/tool_rule_solver.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/humans/__init__.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/humans/examples/basic.txt +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/humans/examples/cs_phd.txt +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/interface.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/llm_api/__init__.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/llm_api/aws_bedrock.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/llm_api/azure_openai.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/llm_api/azure_openai_constants.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/llm_api/cohere.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/llm_api/google_ai.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/llm_api/helpers.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/llm_api/mistral.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/README.md +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/__init__.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/chat_completion_proxy.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/constants.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/function_parser.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/grammars/__init__.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/grammars/gbnf_grammar_generator.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/grammars/json.gbnf +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/grammars/json_func_calls_with_inner_thoughts.gbnf +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/json_parser.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/koboldcpp/api.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/koboldcpp/settings.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/llamacpp/api.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/llamacpp/settings.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/llm_chat_completion_wrappers/__init__.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/llm_chat_completion_wrappers/airoboros.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/llm_chat_completion_wrappers/chatml.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/llm_chat_completion_wrappers/configurable_wrapper.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/llm_chat_completion_wrappers/dolphin.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/llm_chat_completion_wrappers/llama3.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/llm_chat_completion_wrappers/simple_summary_wrapper.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/llm_chat_completion_wrappers/wrapper_base.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/llm_chat_completion_wrappers/zephyr.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/lmstudio/api.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/lmstudio/settings.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/ollama/api.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/ollama/settings.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/settings/__init__.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/settings/deterministic_mirostat.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/settings/settings.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/settings/simple.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/utils.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/vllm/api.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/webui/api.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/webui/legacy_api.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/webui/legacy_settings.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/webui/settings.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/log.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/main.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/memory.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/offline_memory_agent.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/openai_backcompat/__init__.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/openai_backcompat/openai_object.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/__all__.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/__init__.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/agents_tags.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/base.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/block.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/blocks_agents.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/enums.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/errors.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/file.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/job.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/job_messages.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/message.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/mixins.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/organization.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/passage.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/provider.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/sandbox_config.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/source.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/sources_agents.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/sqlalchemy_base.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/sqlite_functions.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/step.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/tool.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/tools_agents.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/user.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/personas/__init__.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/personas/examples/anna_pa.txt +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/personas/examples/google_search_persona.txt +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/personas/examples/memgpt_doc.txt +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/personas/examples/memgpt_starter.txt +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/personas/examples/o1_persona.txt +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/personas/examples/offline_memory_persona.txt +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/personas/examples/sam.txt +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/personas/examples/sam_pov.txt +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/personas/examples/sam_simple_pov_gpt35.txt +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/personas/examples/sqldb/test.db +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/__init__.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/gpt_summarize.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/gpt_system.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_base.txt +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_chat.txt +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_chat_compressed.txt +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_chat_fstring.txt +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_convo_only.txt +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_doc.txt +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_gpt35_extralong.txt +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_intuitive_knowledge.txt +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_modified_chat.txt +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_modified_o1.txt +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_offline_memory.txt +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_offline_memory_chat.txt +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/pytest.ini +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/block.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/embedding_config.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/embedding_config_overrides.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/enums.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/environment_variables.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/file.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/health.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/job.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/letta_base.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/letta_message.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/letta_request.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/letta_response.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/llm_config.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/llm_config_overrides.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/memory.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/message.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/openai/chat_completion_request.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/openai/chat_completion_response.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/openai/chat_completions.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/openai/embedding_response.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/openai/openai.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/organization.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/passage.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/providers.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/run.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/source.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/step.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/tool.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/usage.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/user.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/__init__.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/constants.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/generate_openapi_schema.sh +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/__init__.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/auth/__init__.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/auth/index.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/auth_token.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/chat_completions_interface.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/interface.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/optimistic_json_parser.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/__init__.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/openai/chat_completions/__init__.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/openai/chat_completions/chat_completions.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/agents.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/blocks.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/health.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/jobs.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/llms.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/organizations.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/providers.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/runs.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/sources.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/tags.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/users.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/static_files.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/utils.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/startup.sh +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/static_files/assets/index-048c9598.js +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/static_files/assets/index-0e31b727.css +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/static_files/favicon.ico +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/static_files/index.html +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/static_files/memgpt_logo_transparent.png +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/utils.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/ws_api/__init__.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/ws_api/example_client.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/ws_api/interface.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/ws_api/protocol.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/server/ws_api/server.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/services/__init__.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/services/agent_manager.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/services/block_manager.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/services/helpers/agent_manager_helper.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/services/job_manager.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/services/message_manager.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/services/organization_manager.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/services/passage_manager.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/services/per_agent_lock_manager.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/services/provider_manager.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/services/sandbox_config_manager.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/services/source_manager.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/services/tool_manager.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/services/user_manager.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/streaming_interface.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/streaming_utils.py +0 -0
- {letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/utils.py +0 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import re
|
|
3
3
|
import time
|
|
4
|
-
|
|
4
|
+
import warnings
|
|
5
|
+
from typing import Generator, List, Optional, Union
|
|
5
6
|
|
|
6
7
|
import anthropic
|
|
7
8
|
from anthropic import PermissionDeniedError
|
|
@@ -36,7 +37,7 @@ from letta.schemas.openai.chat_completion_response import MessageDelta, ToolCall
|
|
|
36
37
|
from letta.services.provider_manager import ProviderManager
|
|
37
38
|
from letta.settings import model_settings
|
|
38
39
|
from letta.streaming_interface import AgentChunkStreamingInterface, AgentRefreshStreamingInterface
|
|
39
|
-
from letta.utils import get_utc_time
|
|
40
|
+
from letta.utils import get_utc_time
|
|
40
41
|
|
|
41
42
|
BASE_URL = "https://api.anthropic.com/v1"
|
|
42
43
|
|
|
@@ -567,30 +568,6 @@ def _prepare_anthropic_request(
|
|
|
567
568
|
return data
|
|
568
569
|
|
|
569
570
|
|
|
570
|
-
def get_anthropic_endpoint_and_headers(
|
|
571
|
-
base_url: str,
|
|
572
|
-
api_key: str,
|
|
573
|
-
version: str = "2023-06-01",
|
|
574
|
-
beta: Optional[str] = "tools-2024-04-04",
|
|
575
|
-
) -> Tuple[str, dict]:
|
|
576
|
-
"""
|
|
577
|
-
Dynamically generate the Anthropic endpoint and headers.
|
|
578
|
-
"""
|
|
579
|
-
url = smart_urljoin(base_url, "messages")
|
|
580
|
-
|
|
581
|
-
headers = {
|
|
582
|
-
"Content-Type": "application/json",
|
|
583
|
-
"x-api-key": api_key,
|
|
584
|
-
"anthropic-version": version,
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
# Add beta header if specified
|
|
588
|
-
if beta:
|
|
589
|
-
headers["anthropic-beta"] = beta
|
|
590
|
-
|
|
591
|
-
return url, headers
|
|
592
|
-
|
|
593
|
-
|
|
594
571
|
def anthropic_chat_completions_request(
|
|
595
572
|
data: ChatCompletionRequest,
|
|
596
573
|
inner_thoughts_xml_tag: Optional[str] = "thinking",
|
|
@@ -29,7 +29,6 @@ from letta.schemas.openai.chat_completion_request import ChatCompletionRequest,
|
|
|
29
29
|
from letta.schemas.openai.chat_completion_response import ChatCompletionResponse
|
|
30
30
|
from letta.settings import ModelSettings
|
|
31
31
|
from letta.streaming_interface import AgentChunkStreamingInterface, AgentRefreshStreamingInterface
|
|
32
|
-
from letta.utils import run_async_task
|
|
33
32
|
|
|
34
33
|
LLM_API_PROVIDER_OPTIONS = ["openai", "azure", "anthropic", "google_ai", "cohere", "local", "groq"]
|
|
35
34
|
|
|
@@ -57,7 +56,9 @@ def retry_with_exponential_backoff(
|
|
|
57
56
|
while True:
|
|
58
57
|
try:
|
|
59
58
|
return func(*args, **kwargs)
|
|
60
|
-
|
|
59
|
+
except KeyboardInterrupt:
|
|
60
|
+
# Stop retrying if user hits Ctrl-C
|
|
61
|
+
raise KeyboardInterrupt("User intentionally stopped thread. Stopping...")
|
|
61
62
|
except requests.exceptions.HTTPError as http_err:
|
|
62
63
|
|
|
63
64
|
if not hasattr(http_err, "response") or not http_err.response:
|
|
@@ -142,6 +143,11 @@ def create(
|
|
|
142
143
|
if model_settings.openai_api_key is None and llm_config.model_endpoint == "https://api.openai.com/v1":
|
|
143
144
|
# only is a problem if we are *not* using an openai proxy
|
|
144
145
|
raise LettaConfigurationError(message="OpenAI key is missing from letta config file", missing_fields=["openai_api_key"])
|
|
146
|
+
elif model_settings.openai_api_key is None:
|
|
147
|
+
# the openai python client requires a dummy API key
|
|
148
|
+
api_key = "DUMMY_API_KEY"
|
|
149
|
+
else:
|
|
150
|
+
api_key = model_settings.openai_api_key
|
|
145
151
|
|
|
146
152
|
if function_call is None and functions is not None and len(functions) > 0:
|
|
147
153
|
# force function calling for reliability, see https://platform.openai.com/docs/api-reference/chat/create#chat-create-tool_choice
|
|
@@ -157,25 +163,21 @@ def create(
|
|
|
157
163
|
assert isinstance(stream_interface, AgentChunkStreamingInterface) or isinstance(
|
|
158
164
|
stream_interface, AgentRefreshStreamingInterface
|
|
159
165
|
), type(stream_interface)
|
|
160
|
-
response =
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
stream_interface=stream_interface,
|
|
166
|
-
)
|
|
166
|
+
response = openai_chat_completions_process_stream(
|
|
167
|
+
url=llm_config.model_endpoint,
|
|
168
|
+
api_key=api_key,
|
|
169
|
+
chat_completion_request=data,
|
|
170
|
+
stream_interface=stream_interface,
|
|
167
171
|
)
|
|
168
172
|
else: # Client did not request token streaming (expect a blocking backend response)
|
|
169
173
|
data.stream = False
|
|
170
174
|
if isinstance(stream_interface, AgentChunkStreamingInterface):
|
|
171
175
|
stream_interface.stream_start()
|
|
172
176
|
try:
|
|
173
|
-
response =
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
chat_completion_request=data,
|
|
178
|
-
)
|
|
177
|
+
response = openai_chat_completions_request(
|
|
178
|
+
url=llm_config.model_endpoint,
|
|
179
|
+
api_key=api_key,
|
|
180
|
+
chat_completion_request=data,
|
|
179
181
|
)
|
|
180
182
|
finally:
|
|
181
183
|
if isinstance(stream_interface, AgentChunkStreamingInterface):
|
|
@@ -349,12 +351,10 @@ def create(
|
|
|
349
351
|
stream_interface.stream_start()
|
|
350
352
|
try:
|
|
351
353
|
# groq uses the openai chat completions API, so this component should be reusable
|
|
352
|
-
response =
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
chat_completion_request=data,
|
|
357
|
-
)
|
|
354
|
+
response = openai_chat_completions_request(
|
|
355
|
+
url=llm_config.model_endpoint,
|
|
356
|
+
api_key=model_settings.groq_api_key,
|
|
357
|
+
chat_completion_request=data,
|
|
358
358
|
)
|
|
359
359
|
finally:
|
|
360
360
|
if isinstance(stream_interface, AgentChunkStreamingInterface):
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import warnings
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import Generator, List, Optional, Union
|
|
3
3
|
|
|
4
4
|
import requests
|
|
5
|
-
from openai import
|
|
5
|
+
from openai import OpenAI
|
|
6
6
|
|
|
7
7
|
from letta.llm_api.helpers import add_inner_thoughts_to_functions, convert_to_structured_output, make_post_request
|
|
8
8
|
from letta.local_llm.constants import INNER_THOUGHTS_KWARG, INNER_THOUGHTS_KWARG_DESCRIPTION, INNER_THOUGHTS_KWARG_DESCRIPTION_GO_FIRST
|
|
@@ -158,7 +158,7 @@ def build_openai_chat_completions_request(
|
|
|
158
158
|
return data
|
|
159
159
|
|
|
160
160
|
|
|
161
|
-
|
|
161
|
+
def openai_chat_completions_process_stream(
|
|
162
162
|
url: str,
|
|
163
163
|
api_key: str,
|
|
164
164
|
chat_completion_request: ChatCompletionRequest,
|
|
@@ -231,7 +231,7 @@ async def openai_chat_completions_process_stream(
|
|
|
231
231
|
n_chunks = 0 # approx == n_tokens
|
|
232
232
|
chunk_idx = 0
|
|
233
233
|
try:
|
|
234
|
-
|
|
234
|
+
for chat_completion_chunk in openai_chat_completions_request_stream(
|
|
235
235
|
url=url, api_key=api_key, chat_completion_request=chat_completion_request
|
|
236
236
|
):
|
|
237
237
|
assert isinstance(chat_completion_chunk, ChatCompletionChunkResponse), type(chat_completion_chunk)
|
|
@@ -382,24 +382,21 @@ async def openai_chat_completions_process_stream(
|
|
|
382
382
|
return chat_completion_response
|
|
383
383
|
|
|
384
384
|
|
|
385
|
-
|
|
385
|
+
def openai_chat_completions_request_stream(
|
|
386
386
|
url: str,
|
|
387
387
|
api_key: str,
|
|
388
388
|
chat_completion_request: ChatCompletionRequest,
|
|
389
|
-
) ->
|
|
389
|
+
) -> Generator[ChatCompletionChunkResponse, None, None]:
|
|
390
390
|
data = prepare_openai_payload(chat_completion_request)
|
|
391
391
|
data["stream"] = True
|
|
392
|
-
client =
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
)
|
|
396
|
-
stream = await client.chat.completions.create(**data)
|
|
397
|
-
async for chunk in stream:
|
|
392
|
+
client = OpenAI(api_key=api_key, base_url=url, max_retries=0)
|
|
393
|
+
stream = client.chat.completions.create(**data)
|
|
394
|
+
for chunk in stream:
|
|
398
395
|
# TODO: Use the native OpenAI objects here?
|
|
399
396
|
yield ChatCompletionChunkResponse(**chunk.model_dump(exclude_none=True))
|
|
400
397
|
|
|
401
398
|
|
|
402
|
-
|
|
399
|
+
def openai_chat_completions_request(
|
|
403
400
|
url: str,
|
|
404
401
|
api_key: str,
|
|
405
402
|
chat_completion_request: ChatCompletionRequest,
|
|
@@ -412,8 +409,8 @@ async def openai_chat_completions_request(
|
|
|
412
409
|
https://platform.openai.com/docs/guides/text-generation?lang=curl
|
|
413
410
|
"""
|
|
414
411
|
data = prepare_openai_payload(chat_completion_request)
|
|
415
|
-
client =
|
|
416
|
-
chat_completion =
|
|
412
|
+
client = OpenAI(api_key=api_key, base_url=url, max_retries=0)
|
|
413
|
+
chat_completion = client.chat.completions.create(**data)
|
|
417
414
|
return ChatCompletionResponse(**chat_completion.model_dump())
|
|
418
415
|
|
|
419
416
|
|
{letta_nightly-0.6.19.dev20250131104014 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/agent.py
RENAMED
|
@@ -56,6 +56,9 @@ class Agent(SqlalchemyBase, OrganizationMixin):
|
|
|
56
56
|
embedding_config: Mapped[Optional[EmbeddingConfig]] = mapped_column(
|
|
57
57
|
EmbeddingConfigColumn, doc="the embedding configuration object for this agent."
|
|
58
58
|
)
|
|
59
|
+
project_id: Mapped[Optional[str]] = mapped_column(String, nullable=True, doc="The id of the project the agent belongs to.")
|
|
60
|
+
template_id: Mapped[Optional[str]] = mapped_column(String, nullable=True, doc="The id of the template the agent belongs to.")
|
|
61
|
+
base_template_id: Mapped[Optional[str]] = mapped_column(String, nullable=True, doc="The base template id of the agent.")
|
|
59
62
|
|
|
60
63
|
# Tool rules
|
|
61
64
|
tool_rules: Mapped[Optional[List[ToolRule]]] = mapped_column(ToolRulesColumn, doc="the tool rules for this agent.")
|
|
@@ -146,6 +149,9 @@ class Agent(SqlalchemyBase, OrganizationMixin):
|
|
|
146
149
|
"created_at": self.created_at,
|
|
147
150
|
"updated_at": self.updated_at,
|
|
148
151
|
"tool_exec_environment_variables": self.tool_exec_environment_variables,
|
|
152
|
+
"project_id": self.project_id,
|
|
153
|
+
"template_id": self.template_id,
|
|
154
|
+
"base_template_id": self.base_template_id,
|
|
149
155
|
}
|
|
150
156
|
|
|
151
157
|
return self.__pydantic_model__(**state)
|
|
@@ -85,10 +85,13 @@ class ToolRulesColumn(TypeDecorator):
|
|
|
85
85
|
"""Deserialize a dictionary to the appropriate ToolRule subclass based on the 'type'."""
|
|
86
86
|
rule_type = ToolRuleType(data.get("type")) # Remove 'type' field if it exists since it is a class var
|
|
87
87
|
if rule_type == ToolRuleType.run_first or rule_type == "InitToolRule":
|
|
88
|
+
data["type"] = ToolRuleType.run_first
|
|
88
89
|
return InitToolRule(**data)
|
|
89
90
|
elif rule_type == ToolRuleType.exit_loop or rule_type == "TerminalToolRule":
|
|
91
|
+
data["type"] = ToolRuleType.exit_loop
|
|
90
92
|
return TerminalToolRule(**data)
|
|
91
93
|
elif rule_type == ToolRuleType.constrain_child_tools or rule_type == "ToolRule":
|
|
94
|
+
data["type"] = ToolRuleType.constrain_child_tools
|
|
92
95
|
rule = ChildToolRule(**data)
|
|
93
96
|
return rule
|
|
94
97
|
elif rule_type == ToolRuleType.conditional:
|
|
@@ -81,6 +81,9 @@ class AgentState(OrmMetadataBase, validate_assignment=True):
|
|
|
81
81
|
tool_exec_environment_variables: List[AgentEnvironmentVariable] = Field(
|
|
82
82
|
default_factory=list, description="The environment variables for tool execution specific to this agent."
|
|
83
83
|
)
|
|
84
|
+
project_id: Optional[str] = Field(None, description="The id of the project the agent belongs to.")
|
|
85
|
+
template_id: Optional[str] = Field(None, description="The id of the template the agent belongs to.")
|
|
86
|
+
base_template_id: Optional[str] = Field(None, description="The base template id of the agent.")
|
|
84
87
|
|
|
85
88
|
def get_agent_env_vars_as_dict(self) -> Dict[str, str]:
|
|
86
89
|
# Get environment variables for this agent specifically
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import hashlib
|
|
2
2
|
import json
|
|
3
|
+
import re
|
|
3
4
|
from enum import Enum
|
|
4
5
|
from typing import Any, Dict, List, Literal, Optional, Union
|
|
5
6
|
|
|
@@ -25,18 +26,55 @@ class SandboxRunResult(BaseModel):
|
|
|
25
26
|
sandbox_config_fingerprint: str = Field(None, description="The fingerprint of the config for the sandbox")
|
|
26
27
|
|
|
27
28
|
|
|
29
|
+
class PipRequirement(BaseModel):
|
|
30
|
+
name: str = Field(..., min_length=1, description="Name of the pip package.")
|
|
31
|
+
version: Optional[str] = Field(None, description="Optional version of the package, following semantic versioning.")
|
|
32
|
+
|
|
33
|
+
@classmethod
|
|
34
|
+
def validate_version(cls, version: Optional[str]) -> Optional[str]:
|
|
35
|
+
if version is None:
|
|
36
|
+
return None
|
|
37
|
+
semver_pattern = re.compile(r"^\d+(\.\d+){0,2}(-[a-zA-Z0-9.]+)?$")
|
|
38
|
+
if not semver_pattern.match(version):
|
|
39
|
+
raise ValueError(f"Invalid version format: {version}. Must follow semantic versioning (e.g., 1.2.3, 2.0, 1.5.0-alpha).")
|
|
40
|
+
return version
|
|
41
|
+
|
|
42
|
+
def __init__(self, **data):
|
|
43
|
+
super().__init__(**data)
|
|
44
|
+
self.version = self.validate_version(self.version)
|
|
45
|
+
|
|
46
|
+
|
|
28
47
|
class LocalSandboxConfig(BaseModel):
|
|
29
|
-
sandbox_dir: str = Field(
|
|
48
|
+
sandbox_dir: Optional[str] = Field(None, description="Directory for the sandbox environment.")
|
|
30
49
|
use_venv: bool = Field(False, description="Whether or not to use the venv, or run directly in the same run loop.")
|
|
31
50
|
venv_name: str = Field(
|
|
32
51
|
"venv",
|
|
33
52
|
description="The name for the venv in the sandbox directory. We first search for an existing venv with this name, otherwise, we make it from the requirements.txt.",
|
|
34
53
|
)
|
|
54
|
+
pip_requirements: List[PipRequirement] = Field(
|
|
55
|
+
default_factory=list,
|
|
56
|
+
description="List of pip packages to install with mandatory name and optional version following semantic versioning. This only is considered when use_venv is True.",
|
|
57
|
+
)
|
|
35
58
|
|
|
36
59
|
@property
|
|
37
60
|
def type(self) -> "SandboxType":
|
|
38
61
|
return SandboxType.LOCAL
|
|
39
62
|
|
|
63
|
+
@model_validator(mode="before")
|
|
64
|
+
@classmethod
|
|
65
|
+
def set_default_sandbox_dir(cls, data):
|
|
66
|
+
# If `data` is not a dict (e.g., it's another Pydantic model), just return it
|
|
67
|
+
if not isinstance(data, dict):
|
|
68
|
+
return data
|
|
69
|
+
|
|
70
|
+
if data.get("sandbox_dir") is None:
|
|
71
|
+
if tool_settings.local_sandbox_dir:
|
|
72
|
+
data["sandbox_dir"] = tool_settings.local_sandbox_dir
|
|
73
|
+
else:
|
|
74
|
+
data["sandbox_dir"] = "~/.letta"
|
|
75
|
+
|
|
76
|
+
return data
|
|
77
|
+
|
|
40
78
|
|
|
41
79
|
class E2BSandboxConfig(BaseModel):
|
|
42
80
|
timeout: int = Field(5 * 60, description="Time limit for the sandbox (in seconds).")
|
|
@@ -53,6 +91,10 @@ class E2BSandboxConfig(BaseModel):
|
|
|
53
91
|
"""
|
|
54
92
|
Assign a default template value if the template field is not provided.
|
|
55
93
|
"""
|
|
94
|
+
# If `data` is not a dict (e.g., it's another Pydantic model), just return it
|
|
95
|
+
if not isinstance(data, dict):
|
|
96
|
+
return data
|
|
97
|
+
|
|
56
98
|
if data.get("template") is None:
|
|
57
99
|
data["template"] = tool_settings.e2b_sandbox_template_id
|
|
58
100
|
return data
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Any, Dict, List, Optional, Union
|
|
1
|
+
from typing import Annotated, Any, Dict, List, Literal, Optional, Union
|
|
2
2
|
|
|
3
3
|
from pydantic import Field
|
|
4
4
|
|
|
@@ -17,7 +17,7 @@ class ChildToolRule(BaseToolRule):
|
|
|
17
17
|
A ToolRule represents a tool that can be invoked by the agent.
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
|
-
type: ToolRuleType = ToolRuleType.constrain_child_tools
|
|
20
|
+
type: Literal[ToolRuleType.constrain_child_tools] = ToolRuleType.constrain_child_tools
|
|
21
21
|
children: List[str] = Field(..., description="The children tools that can be invoked.")
|
|
22
22
|
|
|
23
23
|
|
|
@@ -26,7 +26,7 @@ class ConditionalToolRule(BaseToolRule):
|
|
|
26
26
|
A ToolRule that conditionally maps to different child tools based on the output.
|
|
27
27
|
"""
|
|
28
28
|
|
|
29
|
-
type: ToolRuleType = ToolRuleType.conditional
|
|
29
|
+
type: Literal[ToolRuleType.conditional] = ToolRuleType.conditional
|
|
30
30
|
default_child: Optional[str] = Field(None, description="The default child tool to be called. If None, any tool can be called.")
|
|
31
31
|
child_output_mapping: Dict[Any, str] = Field(..., description="The output case to check for mapping")
|
|
32
32
|
require_output_mapping: bool = Field(default=False, description="Whether to throw an error when output doesn't match any case")
|
|
@@ -37,7 +37,7 @@ class InitToolRule(BaseToolRule):
|
|
|
37
37
|
Represents the initial tool rule configuration.
|
|
38
38
|
"""
|
|
39
39
|
|
|
40
|
-
type: ToolRuleType = ToolRuleType.run_first
|
|
40
|
+
type: Literal[ToolRuleType.run_first] = ToolRuleType.run_first
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
class TerminalToolRule(BaseToolRule):
|
|
@@ -45,7 +45,10 @@ class TerminalToolRule(BaseToolRule):
|
|
|
45
45
|
Represents a terminal tool rule configuration where if this tool gets called, it must end the agent loop.
|
|
46
46
|
"""
|
|
47
47
|
|
|
48
|
-
type: ToolRuleType = ToolRuleType.exit_loop
|
|
48
|
+
type: Literal[ToolRuleType.exit_loop] = ToolRuleType.exit_loop
|
|
49
49
|
|
|
50
50
|
|
|
51
|
-
ToolRule =
|
|
51
|
+
ToolRule = Annotated[
|
|
52
|
+
Union[ChildToolRule, InitToolRule, TerminalToolRule, ConditionalToolRule],
|
|
53
|
+
Field(discriminator="type"),
|
|
54
|
+
]
|
|
@@ -97,7 +97,10 @@ class CheckPasswordMiddleware(BaseHTTPMiddleware):
|
|
|
97
97
|
if request.url.path == "/v1/health/" or request.url.path == "/latest/health/":
|
|
98
98
|
return await call_next(request)
|
|
99
99
|
|
|
100
|
-
if
|
|
100
|
+
if (
|
|
101
|
+
request.headers.get("X-BARE-PASSWORD") == f"password {random_password}"
|
|
102
|
+
or request.headers.get("Authorization") == f"Bearer {random_password}"
|
|
103
|
+
):
|
|
101
104
|
return await call_next(request)
|
|
102
105
|
|
|
103
106
|
return JSONResponse(
|
|
@@ -7,6 +7,7 @@ from letta.server.rest_api.routers.v1.providers import router as providers_route
|
|
|
7
7
|
from letta.server.rest_api.routers.v1.runs import router as runs_router
|
|
8
8
|
from letta.server.rest_api.routers.v1.sandbox_configs import router as sandbox_configs_router
|
|
9
9
|
from letta.server.rest_api.routers.v1.sources import router as sources_router
|
|
10
|
+
from letta.server.rest_api.routers.v1.steps import router as steps_router
|
|
10
11
|
from letta.server.rest_api.routers.v1.tags import router as tags_router
|
|
11
12
|
from letta.server.rest_api.routers.v1.tools import router as tools_router
|
|
12
13
|
|
|
@@ -21,5 +22,6 @@ ROUTERS = [
|
|
|
21
22
|
sandbox_configs_router,
|
|
22
23
|
providers_router,
|
|
23
24
|
runs_router,
|
|
25
|
+
steps_router,
|
|
24
26
|
tags_router,
|
|
25
27
|
]
|
|
@@ -1,16 +1,22 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import shutil
|
|
1
3
|
from typing import List, Optional
|
|
2
4
|
|
|
3
|
-
from fastapi import APIRouter, Depends, Query
|
|
5
|
+
from fastapi import APIRouter, Depends, HTTPException, Query
|
|
4
6
|
|
|
7
|
+
from letta.log import get_logger
|
|
5
8
|
from letta.schemas.environment_variables import SandboxEnvironmentVariable as PydanticEnvVar
|
|
6
9
|
from letta.schemas.environment_variables import SandboxEnvironmentVariableCreate, SandboxEnvironmentVariableUpdate
|
|
10
|
+
from letta.schemas.sandbox_config import LocalSandboxConfig
|
|
7
11
|
from letta.schemas.sandbox_config import SandboxConfig as PydanticSandboxConfig
|
|
8
12
|
from letta.schemas.sandbox_config import SandboxConfigCreate, SandboxConfigUpdate, SandboxType
|
|
9
13
|
from letta.server.rest_api.utils import get_letta_server, get_user_id
|
|
10
14
|
from letta.server.server import SyncServer
|
|
15
|
+
from letta.services.helpers.tool_execution_helper import create_venv_for_local_sandbox, install_pip_requirements_for_sandbox
|
|
11
16
|
|
|
12
17
|
router = APIRouter(prefix="/sandbox-config", tags=["sandbox-config"])
|
|
13
18
|
|
|
19
|
+
logger = get_logger(__name__)
|
|
14
20
|
|
|
15
21
|
### Sandbox Config Routes
|
|
16
22
|
|
|
@@ -44,6 +50,34 @@ def create_default_local_sandbox_config(
|
|
|
44
50
|
return server.sandbox_config_manager.get_or_create_default_sandbox_config(sandbox_type=SandboxType.LOCAL, actor=actor)
|
|
45
51
|
|
|
46
52
|
|
|
53
|
+
@router.post("/local", response_model=PydanticSandboxConfig)
|
|
54
|
+
def create_custom_local_sandbox_config(
|
|
55
|
+
local_sandbox_config: LocalSandboxConfig,
|
|
56
|
+
server: SyncServer = Depends(get_letta_server),
|
|
57
|
+
user_id: str = Depends(get_user_id),
|
|
58
|
+
):
|
|
59
|
+
"""
|
|
60
|
+
Create or update a custom LocalSandboxConfig, including pip_requirements.
|
|
61
|
+
"""
|
|
62
|
+
# Ensure the incoming config is of type LOCAL
|
|
63
|
+
if local_sandbox_config.type != SandboxType.LOCAL:
|
|
64
|
+
raise HTTPException(
|
|
65
|
+
status_code=400,
|
|
66
|
+
detail=f"Provided config must be of type '{SandboxType.LOCAL.value}'.",
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
# Retrieve the user (actor)
|
|
70
|
+
actor = server.user_manager.get_user_or_default(user_id=user_id)
|
|
71
|
+
|
|
72
|
+
# Wrap the LocalSandboxConfig into a SandboxConfigCreate
|
|
73
|
+
sandbox_config_create = SandboxConfigCreate(config=local_sandbox_config)
|
|
74
|
+
|
|
75
|
+
# Use the manager to create or update the sandbox config
|
|
76
|
+
sandbox_config = server.sandbox_config_manager.create_or_update_sandbox_config(sandbox_config_create, actor=actor)
|
|
77
|
+
|
|
78
|
+
return sandbox_config
|
|
79
|
+
|
|
80
|
+
|
|
47
81
|
@router.patch("/{sandbox_config_id}", response_model=PydanticSandboxConfig)
|
|
48
82
|
def update_sandbox_config(
|
|
49
83
|
sandbox_config_id: str,
|
|
@@ -77,6 +111,49 @@ def list_sandbox_configs(
|
|
|
77
111
|
return server.sandbox_config_manager.list_sandbox_configs(actor, limit=limit, after=after, sandbox_type=sandbox_type)
|
|
78
112
|
|
|
79
113
|
|
|
114
|
+
@router.post("/local/recreate-venv", response_model=PydanticSandboxConfig)
|
|
115
|
+
def force_recreate_local_sandbox_venv(
|
|
116
|
+
server: SyncServer = Depends(get_letta_server),
|
|
117
|
+
user_id: str = Depends(get_user_id),
|
|
118
|
+
):
|
|
119
|
+
"""
|
|
120
|
+
Forcefully recreate the virtual environment for the local sandbox.
|
|
121
|
+
Deletes and recreates the venv, then reinstalls required dependencies.
|
|
122
|
+
"""
|
|
123
|
+
actor = server.user_manager.get_user_or_default(user_id=user_id)
|
|
124
|
+
|
|
125
|
+
# Retrieve the local sandbox config
|
|
126
|
+
sbx_config = server.sandbox_config_manager.get_or_create_default_sandbox_config(sandbox_type=SandboxType.LOCAL, actor=actor)
|
|
127
|
+
|
|
128
|
+
local_configs = sbx_config.get_local_config()
|
|
129
|
+
sandbox_dir = os.path.expanduser(local_configs.sandbox_dir) # Expand tilde
|
|
130
|
+
venv_path = os.path.join(sandbox_dir, local_configs.venv_name)
|
|
131
|
+
|
|
132
|
+
# Check if venv exists, and delete if necessary
|
|
133
|
+
if os.path.isdir(venv_path):
|
|
134
|
+
try:
|
|
135
|
+
shutil.rmtree(venv_path)
|
|
136
|
+
logger.info(f"Deleted existing virtual environment at: {venv_path}")
|
|
137
|
+
except Exception as e:
|
|
138
|
+
raise HTTPException(status_code=500, detail=f"Failed to delete existing venv: {e}")
|
|
139
|
+
|
|
140
|
+
# Recreate the virtual environment
|
|
141
|
+
try:
|
|
142
|
+
create_venv_for_local_sandbox(sandbox_dir_path=sandbox_dir, venv_path=str(venv_path), env=os.environ.copy(), force_recreate=True)
|
|
143
|
+
logger.info(f"Successfully recreated virtual environment at: {venv_path}")
|
|
144
|
+
except Exception as e:
|
|
145
|
+
raise HTTPException(status_code=500, detail=f"Failed to recreate venv: {e}")
|
|
146
|
+
|
|
147
|
+
# Install pip requirements
|
|
148
|
+
try:
|
|
149
|
+
install_pip_requirements_for_sandbox(local_configs=local_configs, env=os.environ.copy())
|
|
150
|
+
logger.info(f"Successfully installed pip requirements for venv at: {venv_path}")
|
|
151
|
+
except Exception as e:
|
|
152
|
+
raise HTTPException(status_code=500, detail=f"Failed to install pip requirements: {e}")
|
|
153
|
+
|
|
154
|
+
return sbx_config
|
|
155
|
+
|
|
156
|
+
|
|
80
157
|
### Sandbox Environment Variable Routes
|
|
81
158
|
|
|
82
159
|
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from typing import List, Optional
|
|
3
|
+
|
|
4
|
+
from fastapi import APIRouter, Depends, Header, HTTPException, Query
|
|
5
|
+
|
|
6
|
+
from letta.orm.errors import NoResultFound
|
|
7
|
+
from letta.schemas.step import Step
|
|
8
|
+
from letta.server.rest_api.utils import get_letta_server
|
|
9
|
+
from letta.server.server import SyncServer
|
|
10
|
+
|
|
11
|
+
router = APIRouter(prefix="/steps", tags=["steps"])
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@router.get("", response_model=List[Step], operation_id="list_steps")
|
|
15
|
+
def list_steps(
|
|
16
|
+
before: Optional[str] = Query(None, description="Return steps before this step ID"),
|
|
17
|
+
after: Optional[str] = Query(None, description="Return steps after this step ID"),
|
|
18
|
+
limit: Optional[int] = Query(50, description="Maximum number of steps to return"),
|
|
19
|
+
order: Optional[str] = Query("desc", description="Sort order (asc or desc)"),
|
|
20
|
+
start_date: Optional[str] = Query(None, description='Return steps after this ISO datetime (e.g. "2025-01-29T15:01:19-08:00")'),
|
|
21
|
+
end_date: Optional[str] = Query(None, description='Return steps before this ISO datetime (e.g. "2025-01-29T15:01:19-08:00")'),
|
|
22
|
+
model: Optional[str] = Query(None, description="Filter by the name of the model used for the step"),
|
|
23
|
+
server: SyncServer = Depends(get_letta_server),
|
|
24
|
+
user_id: Optional[str] = Header(None, alias="user_id"),
|
|
25
|
+
):
|
|
26
|
+
"""
|
|
27
|
+
List steps with optional pagination and date filters.
|
|
28
|
+
Dates should be provided in ISO 8601 format (e.g. 2025-01-29T15:01:19-08:00)
|
|
29
|
+
"""
|
|
30
|
+
actor = server.user_manager.get_user_or_default(user_id=user_id)
|
|
31
|
+
|
|
32
|
+
# Convert ISO strings to datetime objects if provided
|
|
33
|
+
start_dt = datetime.fromisoformat(start_date) if start_date else None
|
|
34
|
+
end_dt = datetime.fromisoformat(end_date) if end_date else None
|
|
35
|
+
|
|
36
|
+
return server.step_manager.list_steps(
|
|
37
|
+
actor=actor,
|
|
38
|
+
before=before,
|
|
39
|
+
after=after,
|
|
40
|
+
start_date=start_dt,
|
|
41
|
+
end_date=end_dt,
|
|
42
|
+
limit=limit,
|
|
43
|
+
order=order,
|
|
44
|
+
model=model,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@router.get("/{step_id}", response_model=Step, operation_id="retrieve_step")
|
|
49
|
+
def retrieve_step(
|
|
50
|
+
step_id: str,
|
|
51
|
+
user_id: Optional[str] = Header(None, alias="user_id"),
|
|
52
|
+
server: SyncServer = Depends(get_letta_server),
|
|
53
|
+
):
|
|
54
|
+
"""
|
|
55
|
+
Get a step by ID.
|
|
56
|
+
"""
|
|
57
|
+
try:
|
|
58
|
+
return server.step_manager.get_step(step_id=step_id)
|
|
59
|
+
except NoResultFound:
|
|
60
|
+
raise HTTPException(status_code=404, detail="Step not found")
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@router.patch("/{step_id}/transaction/{transaction_id}", response_model=Step, operation_id="update_step_transaction_id")
|
|
64
|
+
def update_step_transaction_id(
|
|
65
|
+
step_id: str,
|
|
66
|
+
transaction_id: str,
|
|
67
|
+
user_id: Optional[str] = Header(None, alias="user_id"),
|
|
68
|
+
server: SyncServer = Depends(get_letta_server),
|
|
69
|
+
):
|
|
70
|
+
"""
|
|
71
|
+
Update the transaction ID for a step.
|
|
72
|
+
"""
|
|
73
|
+
actor = server.user_manager.get_user_or_default(user_id=user_id)
|
|
74
|
+
|
|
75
|
+
try:
|
|
76
|
+
return server.step_manager.update_step_transaction_id(actor, step_id=step_id, transaction_id=transaction_id)
|
|
77
|
+
except NoResultFound:
|
|
78
|
+
raise HTTPException(status_code=404, detail="Step not found")
|