amrita_core 0.10.0.dev1__tar.gz → 0.10.0.dev2__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.
Files changed (93) hide show
  1. {amrita_core-0.10.0.dev1/src/amrita_core.egg-info → amrita_core-0.10.0.dev2}/PKG-INFO +1 -1
  2. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/pyproject.toml +1 -1
  3. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/__init__.py +12 -21
  4. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/adapters/anthropic.py +3 -3
  5. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/adapters/openai.py +4 -4
  6. amrita_core-0.10.0.dev2/src/amrita_core/agent/functions.py +182 -0
  7. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/agent/strategy.py +2 -8
  8. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/base/adapter.py +2 -1
  9. amrita_core-0.10.0.dev2/src/amrita_core/base/backend.py +46 -0
  10. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/builtins/agent.py +2 -2
  11. amrita_core-0.10.0.dev2/src/amrita_core/builtins/backends.py +46 -0
  12. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/builtins/tools.py +3 -2
  13. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/chatmanager/chat_object.py +173 -125
  14. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/chatmanager/enums.py +2 -0
  15. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/chatmanager/memory_limiter.py +1 -1
  16. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/config.py +1 -1
  17. amrita_core-0.10.0.dev2/src/amrita_core/contexts.py +30 -0
  18. amrita_core-0.10.0.dev2/src/amrita_core/dirty.py +321 -0
  19. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/hook/event.py +4 -0
  20. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/libchat.py +1 -1
  21. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/tools/mcp.py +2 -9
  22. amrita_core-0.10.0.dev2/src/amrita_core/types/__init__.py +58 -0
  23. amrita_core-0.10.0.dev2/src/amrita_core/types/base.py +27 -0
  24. amrita_core-0.10.0.dev2/src/amrita_core/types/content.py +116 -0
  25. amrita_core-0.10.0.dev2/src/amrita_core/types/embedding.py +13 -0
  26. amrita_core-0.10.0.dev2/src/amrita_core/types/memory.py +16 -0
  27. amrita_core-0.10.0.dev2/src/amrita_core/types/message.py +153 -0
  28. amrita_core-0.10.0.dev2/src/amrita_core/types/preset.py +99 -0
  29. amrita_core-0.10.0.dev2/src/amrita_core/types/response.py +55 -0
  30. amrita_core-0.10.0.dev2/src/amrita_core/types/tool.py +38 -0
  31. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/utils.py +30 -14
  32. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2/src/amrita_core.egg-info}/PKG-INFO +1 -1
  33. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core.egg-info/SOURCES.txt +12 -8
  34. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/tests/test_agent.py +14 -2
  35. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/tests/test_chatmanager.py +77 -170
  36. amrita_core-0.10.0.dev2/tests/test_chatobject.py +114 -0
  37. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/tests/test_functions.py +72 -98
  38. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/tests/test_hooks.py +1 -1
  39. amrita_core-0.10.0.dev2/tests/test_integration.py +201 -0
  40. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/tests/test_libchat.py +1 -1
  41. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/tests/test_protocol.py +6 -4
  42. amrita_core-0.10.0.dev1/src/amrita_core/agent/functions.py +0 -203
  43. amrita_core-0.10.0.dev1/src/amrita_core/base/backend.py +0 -1
  44. amrita_core-0.10.0.dev1/src/amrita_core/hook/matcher.py +0 -11
  45. amrita_core-0.10.0.dev1/src/amrita_core/logging.py +0 -25
  46. amrita_core-0.10.0.dev1/src/amrita_core/protocol.py +0 -37
  47. amrita_core-0.10.0.dev1/src/amrita_core/sessions.py +0 -150
  48. amrita_core-0.10.0.dev1/src/amrita_core/streaming.py +0 -10
  49. amrita_core-0.10.0.dev1/src/amrita_core/types.py +0 -462
  50. amrita_core-0.10.0.dev1/src/amrita_core/weakcache.py +0 -10
  51. amrita_core-0.10.0.dev1/tests/test_chatobject.py +0 -98
  52. amrita_core-0.10.0.dev1/tests/test_integration.py +0 -274
  53. amrita_core-0.10.0.dev1/tests/test_sessions.py +0 -168
  54. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/LICENSE +0 -0
  55. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/README.md +0 -0
  56. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/setup.cfg +0 -0
  57. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/_env.py +0 -0
  58. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/agent/context.py +0 -0
  59. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/base/tokenizer.py +0 -0
  60. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/builtins/__init__.py +0 -0
  61. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/builtins/consts.py +0 -0
  62. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/builtins/hooks.py +0 -0
  63. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/builtins/types.py +0 -0
  64. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/chatmanager/__init__.py +0 -0
  65. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/chatmanager/chat_libs.py +0 -0
  66. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/chatmanager/chat_obj_meta.py +0 -0
  67. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/consts.py +0 -0
  68. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/contents.py +0 -0
  69. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/hook/exception.py +0 -0
  70. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/hook/on.py +0 -0
  71. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/preset.py +0 -0
  72. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/tokenizer.py +0 -0
  73. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/tokenizers/jieba_based.py +0 -0
  74. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/tokenizers/simple.py +0 -0
  75. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/tools/manager.py +0 -0
  76. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core/tools/models.py +0 -0
  77. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core.egg-info/dependency_links.txt +0 -0
  78. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core.egg-info/requires.txt +0 -0
  79. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/src/amrita_core.egg-info/top_level.txt +0 -0
  80. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/tests/test_adapter.py +0 -0
  81. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/tests/test_complete_content_validation.py +0 -0
  82. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/tests/test_content_deserialization.py +0 -0
  83. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/tests/test_manager.py +0 -0
  84. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/tests/test_mcp.py +0 -0
  85. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/tests/test_message_deserialization.py +0 -0
  86. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/tests/test_message_edge_cases.py +0 -0
  87. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/tests/test_preset.py +0 -0
  88. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/tests/test_register_content.py +0 -0
  89. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/tests/test_serialization_integrity.py +0 -0
  90. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/tests/test_simple_tool_extended.py +0 -0
  91. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/tests/test_tools.py +0 -0
  92. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/tests/test_types.py +0 -0
  93. {amrita_core-0.10.0.dev1 → amrita_core-0.10.0.dev2}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: amrita_core
3
- Version: 0.10.0.dev1
3
+ Version: 0.10.0.dev2
4
4
  Summary: High performance, flexible, lightweight agent framework.
5
5
  Project-URL: Homepage, https://github.com/AmritaBot/AmritaCore
6
6
  Project-URL: Source, https://github.com/AmritaBot/AmritaCore
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "amrita_core"
3
- version = "0.10.0.dev1"
3
+ version = "0.10.0.dev2"
4
4
  description = "High performance, flexible, lightweight agent framework."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10,<3.15"
@@ -1,6 +1,5 @@
1
1
  from amrita_sense.logging import debug_log, logger
2
2
  from amrita_sense.streaming import SuspendObjectStream
3
- from typing_extensions import deprecated
4
3
 
5
4
  from amrita_core.base.adapter import AdapterManager
6
5
  from amrita_core.base.tokenizer import TokenizerManager
@@ -8,8 +7,11 @@ from amrita_core.base.tokenizer import TokenizerManager
8
7
  from . import adapters, tokenizers
9
8
  from .agent.functions import AgentRuntime, create_agent
10
9
  from .agent.strategy import AgentStrategy
10
+ from .base.backend import AbilityBackend, BackendSlots, MemoryBackend
11
+ from .builtins.backends import LegacyBackend
11
12
  from .chatmanager import ChatManager, ChatObject, ChatObjectMeta, SuspendEnum
12
13
  from .config import AmritaConfig, get_config, set_config
14
+ from .contexts import AbilityContext, StateContext
13
15
  from .hook.event import CompletionEvent, EventTypeEnum, PreCompletionEvent
14
16
  from .hook.on import on_completion, on_event, on_precompletion
15
17
  from .libchat import (
@@ -20,7 +22,6 @@ from .libchat import (
20
22
  tools_caller,
21
23
  )
22
24
  from .preset import PresetManager, PresetReport
23
- from .sessions import SessionsManager
24
25
  from .tools import mcp
25
26
  from .tools.manager import ToolsManager, on_tools, simple_tool
26
27
  from .tools.models import (
@@ -43,20 +44,7 @@ from .types import (
43
44
  UniResponse,
44
45
  UniResponseUsage,
45
46
  )
46
- from .utils import side_effect_import
47
-
48
-
49
- @deprecated(
50
- "Init method is no longer necessary. Please use minimal_init or load_amrita() instead for async initialization. Will be removed in v0.10.0",
51
- category=DeprecationWarning,
52
- )
53
- def init(): ...
54
-
55
-
56
- def load_session(session_id: str):
57
- logger.info("Loading session %s......", session_id)
58
- sm = SessionsManager()
59
- sm.init_session(session_id)
47
+ from .utils import load_and_notice, side_effect_import
60
48
 
61
49
 
62
50
  async def load_amrita():
@@ -75,17 +63,19 @@ async def minimal_init(config: AmritaConfig = AmritaConfig()) -> None:
75
63
 
76
64
  logger.info("Loading tokenizers and adapters......")
77
65
 
78
-
79
- side_effect_import(adapters)
66
+ load_and_notice(adapters, "Adapters")
80
67
  logger.debug(f"Loaded adapters: {','.join(AdapterManager().get_adapters().keys())}")
81
- side_effect_import(tokenizers)
68
+ load_and_notice(tokenizers, "Tokenizers")
82
69
  logger.debug(
83
70
  f"Loaded tokenizers: {','.join(TokenizerManager().get_tokenizers().keys())}"
84
71
  )
85
72
 
86
73
  __all__ = [
74
+ "AbilityBackend",
75
+ "AbilityContext",
87
76
  "AgentRuntime",
88
77
  "AgentStrategy",
78
+ "BackendSlots",
89
79
  "BaseModel",
90
80
  "ChatManager",
91
81
  "ChatObject",
@@ -96,13 +86,15 @@ __all__ = [
96
86
  "FunctionDefinitionSchema",
97
87
  "FunctionParametersSchema",
98
88
  "FunctionPropertySchema",
89
+ "LegacyBackend",
90
+ "MemoryBackend",
99
91
  "MemoryModel",
100
92
  "ModelConfig",
101
93
  "ModelPreset",
102
94
  "PreCompletionEvent",
103
95
  "PresetManager",
104
96
  "PresetReport",
105
- "SessionsManager",
97
+ "StateContext",
106
98
  "SuspendEnum",
107
99
  "SuspendObjectStream",
108
100
  "TextContent",
@@ -121,7 +113,6 @@ __all__ = [
121
113
  "get_config",
122
114
  "get_last_response",
123
115
  "get_tokens",
124
- "logger",
125
116
  "mcp",
126
117
  "on_completion",
127
118
  "on_event",
@@ -6,12 +6,12 @@ from amrita_sense.logging import logger
6
6
  from pydantic import BaseModel, Field
7
7
  from typing_extensions import override
8
8
 
9
- from amrita_core.config import AmritaConfig
10
- from amrita_core.contents import MessageMetadataPayload, MessageWithMetadata
11
- from amrita_core.protocol import (
9
+ from amrita_core.base.adapter import (
12
10
  COMPLETION_RETURNING,
13
11
  ModelAdapter,
14
12
  )
13
+ from amrita_core.config import AmritaConfig
14
+ from amrita_core.contents import MessageMetadataPayload, MessageWithMetadata
15
15
  from amrita_core.tools.models import (
16
16
  FunctionParametersSchema,
17
17
  ToolChoice,
@@ -2,6 +2,7 @@ from collections.abc import AsyncGenerator, Iterable, Sequence
2
2
  from typing import cast
3
3
 
4
4
  import openai
5
+ from amrita_sense.logging import debug_log
5
6
  from openai._types import SequenceNotStr
6
7
  from openai.types.chat.chat_completion import ChatCompletion
7
8
  from openai.types.chat.chat_completion_chunk import ChatCompletionChunk
@@ -17,13 +18,12 @@ from openai.types.chat.chat_completion_tool_choice_option_param import (
17
18
  )
18
19
  from typing_extensions import override
19
20
 
20
- from amrita_core.config import AmritaConfig
21
- from amrita_core.contents import MessageMetadataPayload, MessageWithMetadata
22
- from amrita_core.logging import debug_log
23
- from amrita_core.protocol import (
21
+ from amrita_core.base.adapter import (
24
22
  COMPLETION_RETURNING,
25
23
  ModelAdapter,
26
24
  )
25
+ from amrita_core.config import AmritaConfig
26
+ from amrita_core.contents import MessageMetadataPayload, MessageWithMetadata
27
27
  from amrita_core.tools.models import (
28
28
  ToolChoice,
29
29
  ToolFunctionSchema,
@@ -0,0 +1,182 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+ from uuid import uuid4
5
+
6
+ from jinja2 import Template
7
+
8
+ from amrita_core.base.backend import BackendSlots
9
+ from amrita_core.builtins.agent import ReActAgentStrategy
10
+ from amrita_core.builtins.backends import LegacyBackend
11
+ from amrita_core.chatmanager import ChatObject
12
+ from amrita_core.config import get_config
13
+ from amrita_core.consts import DEFAULT_INSTRUCTIONS, DEFAULT_TEMPLATE
14
+ from amrita_core.types import USER_INPUT, Message, ModelConfig, ModelPreset
15
+
16
+ if TYPE_CHECKING:
17
+ from amrita_core.config import AmritaConfig
18
+
19
+ from .strategy import AgentStrategy
20
+
21
+
22
+ class AgentRuntime:
23
+ """
24
+ AgentRuntime is a high-level wrapper around ChatObject that provides a reusable
25
+ agent operation interface.
26
+
27
+ This class encapsulates the complexity of ChatObject and provides a simplified
28
+ API for agent interactions. It maintains session state, configuration, and
29
+ strategy settings, making it a reusable object for multiple agent operations
30
+ within the same context.
31
+
32
+ Session and memory management is delegated to the Backend mechanism
33
+ (:class:`BackendSlots`), which handles memory loading, committing, and
34
+ ability resolution transparently. AgentRuntime itself only holds a
35
+ ``session_id`` string and a ``slot`` reference — the actual state lives
36
+ inside the Backend and is lazily resolved by :class:`ChatObject` at
37
+ runtime.
38
+ """
39
+
40
+ strategy: type[AgentStrategy]
41
+ session_id: str
42
+ slot: BackendSlots
43
+ preset: ModelPreset
44
+ config: AmritaConfig
45
+ train: Message[str]
46
+ template: Template
47
+
48
+ def __init__(
49
+ self,
50
+ config: AmritaConfig,
51
+ preset: ModelPreset,
52
+ train: dict[str, str] | Message[str],
53
+ strategy: type[AgentStrategy] = ReActAgentStrategy,
54
+ template: Template | str = DEFAULT_TEMPLATE,
55
+ session_id: str | None = None,
56
+ backend: BackendSlots | None = None,
57
+ ):
58
+ """
59
+ Initialize an AgentRuntime instance.
60
+
61
+ Args:
62
+ config: Amrita configuration object containing global configuration settings.
63
+ preset: Model preset configuration defining basic model parameters and settings.
64
+ train: System prompt for the agent (dict or Message).
65
+ strategy: Agent strategy class, defaults to ReActAgentStrategy.
66
+ template: Jinja2 template (or template string) used to render the system prompt.
67
+ session_id: Session identifier string. If None, a new UUID-based ID is generated.
68
+ The session_id is passed to every ChatObject created by this runtime,
69
+ allowing the Backend to isolate memory and abilities per session.
70
+ backend: Backend slots providing memory and ability backends. If None, a
71
+ :class:`LegacyBackend` is used for both slots, which stores data in
72
+ global in-process containers.
73
+ """
74
+ self.session_id = session_id or uuid4().hex
75
+ bkd = LegacyBackend()
76
+ self.slot = backend or BackendSlots(bkd, bkd)
77
+ self.template = Template(template) if isinstance(template, str) else template
78
+ self.strategy = strategy
79
+ self.preset = preset
80
+ self.config = config
81
+ self.train = (
82
+ train if isinstance(train, Message) else Message[str].model_validate(train)
83
+ )
84
+
85
+ def set_strategy(self, strategy: type[AgentStrategy]) -> None:
86
+ """
87
+ Set the agent strategy to be used for execution.
88
+
89
+ Args:
90
+ strategy: The agent strategy class to be used for execution.
91
+ """
92
+ self.strategy = strategy
93
+
94
+ def get_chatobject(self, user_input: USER_INPUT, **kwargs) -> ChatObject:
95
+ """Create a :class:`ChatObject` bound to this runtime's configuration.
96
+
97
+ The returned ChatObject reuses the runtime's preset, config, strategy,
98
+ system prompt template, session_id and backend slots. Memory and
99
+ ability resolution is handled lazily by ChatObject via the backend.
100
+
101
+ Args:
102
+ user_input: The user's input message.
103
+ **kwargs: Additional keyword arguments forwarded to :class:`ChatObject`
104
+ (e.g. ``io_stream``, ``hook_args``, ``middleware``, etc.).
105
+
106
+ Returns:
107
+ A fully configured ChatObject ready for execution.
108
+ """
109
+ return ChatObject(
110
+ train=self.train,
111
+ user_input=user_input,
112
+ context=None,
113
+ session_id=self.session_id,
114
+ backend=self.slot,
115
+ config=self.config,
116
+ preset=self.preset,
117
+ agent_strategy=self.strategy,
118
+ train_template=self.template,
119
+ **kwargs,
120
+ )
121
+
122
+
123
+ def create_agent(
124
+ base_url: str,
125
+ api_key: str,
126
+ model: str = "auto",
127
+ *,
128
+ train: str | None = None,
129
+ model_config: ModelConfig | dict | None = None,
130
+ config: AmritaConfig | None = None,
131
+ **kwargs,
132
+ ) -> AgentRuntime:
133
+ """
134
+ Create an agent with minimal parameters by automatically creating a temporary preset.
135
+
136
+ This factory function simplifies agent creation by only requiring essential
137
+ parameters like URL and API key, automatically creating a temporary preset.
138
+
139
+ Args:
140
+ base_url: The API endpoint URL.
141
+ api_key: The API key for authentication.
142
+ model: The model to use. Defaults to "auto".
143
+ model_config: Optional model configuration (dict or ModelConfig).
144
+ config: Configuration for the agent. Defaults to global config.
145
+ **kwargs: Additional keyword arguments forwarded to :class:`AgentRuntime`
146
+ (e.g. ``strategy``, ``template``, ``session_id``, ``backend``).
147
+
148
+ Returns:
149
+ A configured :class:`AgentRuntime` instance.
150
+
151
+ Example:
152
+ ```python
153
+ agent = create_agent(
154
+ "https://api.example.com",
155
+ "your-api-key",
156
+ model="gpt-4",
157
+ model_config={"temperature": 0.7},
158
+ )
159
+ ```
160
+ """
161
+ if train is None:
162
+ train = DEFAULT_INSTRUCTIONS
163
+ final_config = config or get_config()
164
+ if isinstance(model_config, dict):
165
+ model_config = ModelConfig(**model_config)
166
+ elif not model_config:
167
+ model_config = ModelConfig()
168
+
169
+ preset = ModelPreset(
170
+ name=f"temp_{uuid4().hex[:8]}",
171
+ base_url=base_url,
172
+ api_key=api_key,
173
+ config=model_config,
174
+ model=model,
175
+ )
176
+
177
+ return AgentRuntime(
178
+ config=final_config,
179
+ preset=preset,
180
+ train=Message(content=train, role="system"),
181
+ **{k: v for k, v in kwargs.items() if k not in ["config", "model_config"]},
182
+ )
@@ -9,10 +9,7 @@ from typing import TYPE_CHECKING, Any, Literal
9
9
  from typing_extensions import Self
10
10
 
11
11
  from amrita_core.agent.context import StrategyContext
12
- from amrita_core.contents import MessageMetadataPayloadSystem
13
- from amrita_core.protocol import MessageWithMetadata
14
- from amrita_core.sessions import SessionData, SessionsManager
15
- from amrita_core.tools.manager import ToolsManager
12
+ from amrita_core.contents import MessageMetadataPayloadSystem, MessageWithMetadata
16
13
  from amrita_core.tools.models import ToolContext
17
14
  from amrita_core.types import Message, ToolCall
18
15
 
@@ -31,7 +28,6 @@ class _StrategyBase(ABC):
31
28
  """Shared execution logic for AgentStrategy and StrategyLikedObject, which
32
29
  differ only in how the context is injected (``__init__`` vs ``__call__``)."""
33
30
 
34
- session: SessionData | None = None
35
31
  tools_manager: "MultiToolsManager"
36
32
  chat_object: "ChatObject"
37
33
  ctx: StrategyContext
@@ -39,9 +35,7 @@ class _StrategyBase(ABC):
39
35
  def _bind(self, ctx: StrategyContext) -> None:
40
36
  self.ctx = ctx
41
37
  self.chat_object = ctx.chat_object
42
- session_id = ctx.chat_object.session_id
43
- self.session = SessionsManager().get_session_data(session_id, None)
44
- self.tools_manager = self.session.tools if self.session else ToolsManager()
38
+ self.tools_manager = ctx.chat_object.state.ability.tools
45
39
 
46
40
  async def single_execute(
47
41
  self,
@@ -5,9 +5,10 @@ from collections.abc import AsyncGenerator, Iterable, Sequence
5
5
  from dataclasses import dataclass, field
6
6
  from typing import TYPE_CHECKING, Literal
7
7
 
8
+ from amrita_sense.logging import logger
9
+
8
10
  from amrita_core.config import AmritaConfig, get_config
9
11
 
10
- from ..logging import logger
11
12
  from ..tools.models import ToolChoice, ToolFunctionSchema
12
13
  from ..types import EmbeddingChunk, ModelPreset, ToolCall, UniResponse
13
14
 
@@ -0,0 +1,46 @@
1
+ from __future__ import annotations
2
+
3
+ from abc import abstractmethod
4
+ from dataclasses import dataclass
5
+ from typing import TYPE_CHECKING
6
+
7
+ if TYPE_CHECKING:
8
+ from amrita_core.contexts import AbilityContext
9
+ from amrita_core.preset import MultiPresetManager
10
+ from amrita_core.tools.manager import MultiToolsManager
11
+ from amrita_core.tools.mcp import MultiClientManager
12
+ from amrita_core.types import MemoryModel
13
+
14
+
15
+ class AbilityBackend:
16
+ @abstractmethod
17
+ async def load_ability_all(self, session_id: str) -> AbilityContext:
18
+ """Load ability"""
19
+ ...
20
+
21
+ @abstractmethod
22
+ async def load_mcp_clients(self, session_id: str) -> MultiClientManager: ...
23
+
24
+ @abstractmethod
25
+ async def load_tools(self, session_id: str) -> MultiToolsManager: ...
26
+
27
+ @abstractmethod
28
+ async def load_presets(self, session_id: str) -> MultiPresetManager: ...
29
+
30
+
31
+ class MemoryBackend:
32
+ @abstractmethod
33
+ async def load_memory(self, session_id: str) -> MemoryModel:
34
+ """Load memory"""
35
+ ...
36
+
37
+ @abstractmethod
38
+ async def commit_memory(self, session_id: str, memory: MemoryModel) -> None:
39
+ """Commit memory"""
40
+ ...
41
+
42
+
43
+ @dataclass
44
+ class BackendSlots:
45
+ ability: AbilityBackend
46
+ memory: MemoryBackend
@@ -7,18 +7,18 @@ from abc import ABC, abstractmethod
7
7
  from collections.abc import Awaitable, Callable
8
8
  from typing import Any, ClassVar, Literal, cast
9
9
 
10
+ from amrita_sense.logging import debug_log, logger
10
11
  from jinja2 import Template
11
12
  from typing_extensions import Self, override
12
13
 
13
14
  from amrita_core.agent.context import StrategyContext
14
15
  from amrita_core.agent.strategy import AgentStrategy
16
+ from amrita_core.contents import MessageWithMetadata
15
17
  from amrita_core.libchat import (
16
18
  call_completion,
17
19
  get_last_response,
18
20
  tools_caller,
19
21
  )
20
- from amrita_core.logging import debug_log, logger
21
- from amrita_core.protocol import MessageWithMetadata
22
22
  from amrita_core.types import (
23
23
  CONTENT_LIST_TYPE_ITEM,
24
24
  Message,
@@ -0,0 +1,46 @@
1
+ from typing import ClassVar
2
+
3
+ from amrita_core.base.backend import AbilityBackend, MemoryBackend
4
+ from amrita_core.contexts import AbilityContext, StateContext
5
+ from amrita_core.preset import MultiPresetManager
6
+ from amrita_core.tools.manager import MultiToolsManager
7
+ from amrita_core.tools.mcp import MultiClientManager
8
+ from amrita_core.types.memory import MemoryModel
9
+
10
+
11
+ class LegacyBackend(AbilityBackend, MemoryBackend):
12
+ ctx: StateContext
13
+ glb: ClassVar[AbilityContext] = AbilityContext()
14
+
15
+ def __init__(self, ctx: StateContext | None = None):
16
+ if ctx:
17
+ self.ctx = ctx
18
+
19
+ def _init_ctx(self, session_id: str):
20
+ if not hasattr(self, "ctx"):
21
+ self.ctx = StateContext(session_id, ability=self.glb)
22
+
23
+ async def load_ability_all(self, session_id: str) -> AbilityContext:
24
+ """Load ability context from global container"""
25
+
26
+ return self.glb
27
+
28
+ async def load_mcp_clients(self, session_id: str) -> MultiClientManager:
29
+ return self.glb.mcp
30
+
31
+ async def load_tools(self, session_id: str) -> MultiToolsManager:
32
+ return self.glb.tools
33
+
34
+ async def load_presets(self, session_id: str) -> MultiPresetManager:
35
+
36
+ return self.glb.presets
37
+
38
+ async def commit_memory(self, session_id: str, memory: MemoryModel) -> None:
39
+ """Commit memory to global container"""
40
+ self._init_ctx(session_id)
41
+ self.ctx.memory = memory
42
+
43
+ async def load_memory(self, session_id: str) -> MemoryModel:
44
+ """Load memory from global container"""
45
+ self._init_ctx(session_id)
46
+ return self.ctx.memory
@@ -1,6 +1,7 @@
1
+ from amrita_sense.logging import logger
2
+
1
3
  from amrita_core.config import get_config
2
- from amrita_core.logging import logger
3
- from amrita_core.protocol import MessageWithMetadata
4
+ from amrita_core.contents import MessageWithMetadata
4
5
  from amrita_core.tools.manager import on_tools
5
6
  from amrita_core.tools.models import (
6
7
  FunctionDefinitionSchema,