amrita_core 0.9.4__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 (96) hide show
  1. {amrita_core-0.9.4/src/amrita_core.egg-info → amrita_core-0.10.0.dev2}/PKG-INFO +2 -2
  2. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/pyproject.toml +2 -2
  3. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/__init__.py +12 -21
  4. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/adapters/anthropic.py +3 -3
  5. {amrita_core-0.9.4 → 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.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/agent/strategy.py +2 -8
  8. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/base/adapter.py +3 -3
  9. amrita_core-0.10.0.dev2/src/amrita_core/base/backend.py +46 -0
  10. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/base/tokenizer.py +1 -3
  11. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/builtins/agent.py +330 -18
  12. amrita_core-0.10.0.dev2/src/amrita_core/builtins/backends.py +46 -0
  13. amrita_core-0.10.0.dev2/src/amrita_core/builtins/consts.py +261 -0
  14. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/builtins/tools.py +43 -2
  15. amrita_core-0.10.0.dev2/src/amrita_core/builtins/types.py +111 -0
  16. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/chatmanager/chat_object.py +173 -125
  17. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/chatmanager/enums.py +2 -0
  18. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/chatmanager/memory_limiter.py +1 -1
  19. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/config.py +59 -1
  20. amrita_core-0.10.0.dev2/src/amrita_core/contexts.py +30 -0
  21. amrita_core-0.10.0.dev2/src/amrita_core/dirty.py +321 -0
  22. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/hook/event.py +4 -0
  23. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/libchat.py +1 -1
  24. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/preset.py +1 -2
  25. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/tools/manager.py +5 -4
  26. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/tools/mcp.py +52 -61
  27. amrita_core-0.10.0.dev2/src/amrita_core/types/__init__.py +58 -0
  28. amrita_core-0.10.0.dev2/src/amrita_core/types/base.py +27 -0
  29. amrita_core-0.10.0.dev2/src/amrita_core/types/content.py +116 -0
  30. amrita_core-0.10.0.dev2/src/amrita_core/types/embedding.py +13 -0
  31. amrita_core-0.10.0.dev2/src/amrita_core/types/memory.py +16 -0
  32. amrita_core-0.10.0.dev2/src/amrita_core/types/message.py +153 -0
  33. amrita_core-0.10.0.dev2/src/amrita_core/types/preset.py +99 -0
  34. amrita_core-0.10.0.dev2/src/amrita_core/types/response.py +55 -0
  35. amrita_core-0.10.0.dev2/src/amrita_core/types/tool.py +38 -0
  36. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/utils.py +30 -14
  37. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2/src/amrita_core.egg-info}/PKG-INFO +2 -2
  38. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core.egg-info/SOURCES.txt +13 -10
  39. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core.egg-info/requires.txt +1 -1
  40. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/tests/test_agent.py +204 -5
  41. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/tests/test_chatmanager.py +77 -170
  42. amrita_core-0.10.0.dev2/tests/test_chatobject.py +114 -0
  43. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/tests/test_functions.py +72 -98
  44. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/tests/test_hooks.py +1 -1
  45. amrita_core-0.10.0.dev2/tests/test_integration.py +201 -0
  46. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/tests/test_libchat.py +1 -1
  47. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/tests/test_protocol.py +6 -4
  48. amrita_core-0.9.4/src/amrita_core/agent/functions.py +0 -203
  49. amrita_core-0.9.4/src/amrita_core/builtins/consts.py +0 -119
  50. amrita_core-0.9.4/src/amrita_core/builtins/types.py +0 -46
  51. amrita_core-0.9.4/src/amrita_core/hook/matcher.py +0 -11
  52. amrita_core-0.9.4/src/amrita_core/logging.py +0 -25
  53. amrita_core-0.9.4/src/amrita_core/protocol.py +0 -37
  54. amrita_core-0.9.4/src/amrita_core/sessions.py +0 -151
  55. amrita_core-0.9.4/src/amrita_core/streaming.py +0 -10
  56. amrita_core-0.9.4/src/amrita_core/threadsafe.py +0 -22
  57. amrita_core-0.9.4/src/amrita_core/types.py +0 -462
  58. amrita_core-0.9.4/src/amrita_core/weakcache.py +0 -10
  59. amrita_core-0.9.4/tests/test_chatobject.py +0 -98
  60. amrita_core-0.9.4/tests/test_integration.py +0 -274
  61. amrita_core-0.9.4/tests/test_sessions.py +0 -168
  62. amrita_core-0.9.4/tests/test_threadsafe.py +0 -45
  63. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/LICENSE +0 -0
  64. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/README.md +0 -0
  65. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/setup.cfg +0 -0
  66. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/_env.py +0 -0
  67. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/agent/context.py +0 -0
  68. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/builtins/__init__.py +0 -0
  69. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/builtins/hooks.py +0 -0
  70. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/chatmanager/__init__.py +0 -0
  71. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/chatmanager/chat_libs.py +0 -0
  72. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/chatmanager/chat_obj_meta.py +0 -0
  73. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/consts.py +0 -0
  74. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/contents.py +0 -0
  75. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/hook/exception.py +0 -0
  76. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/hook/on.py +0 -0
  77. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/tokenizer.py +0 -0
  78. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/tokenizers/jieba_based.py +0 -0
  79. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/tokenizers/simple.py +0 -0
  80. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core/tools/models.py +0 -0
  81. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core.egg-info/dependency_links.txt +0 -0
  82. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/src/amrita_core.egg-info/top_level.txt +0 -0
  83. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/tests/test_adapter.py +0 -0
  84. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/tests/test_complete_content_validation.py +0 -0
  85. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/tests/test_content_deserialization.py +0 -0
  86. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/tests/test_manager.py +0 -0
  87. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/tests/test_mcp.py +0 -0
  88. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/tests/test_message_deserialization.py +0 -0
  89. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/tests/test_message_edge_cases.py +0 -0
  90. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/tests/test_preset.py +0 -0
  91. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/tests/test_register_content.py +0 -0
  92. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/tests/test_serialization_integrity.py +0 -0
  93. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/tests/test_simple_tool_extended.py +0 -0
  94. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/tests/test_tools.py +0 -0
  95. {amrita_core-0.9.4 → amrita_core-0.10.0.dev2}/tests/test_types.py +0 -0
  96. {amrita_core-0.9.4 → 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.9.4
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
@@ -11,7 +11,7 @@ License-File: LICENSE
11
11
  Requires-Dist: aiofiles>=25.1.0
12
12
  Requires-Dist: aiohttp>=3.13.3
13
13
  Requires-Dist: aiologic>=0.16.0
14
- Requires-Dist: amrita-sense>=0.3.0
14
+ Requires-Dist: amrita-sense>=0.3.2
15
15
  Requires-Dist: fastmcp>=3.2.0
16
16
  Requires-Dist: filetype>=1.2.0
17
17
  Requires-Dist: importlib>=1.0.4
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "amrita_core"
3
- version = "0.9.4"
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"
@@ -8,7 +8,7 @@ dependencies = [
8
8
  "aiofiles>=25.1.0",
9
9
  "aiohttp>=3.13.3",
10
10
  "aiologic>=0.16.0",
11
- "amrita-sense>=0.3.0",
11
+ "amrita-sense>=0.3.2",
12
12
  "fastmcp>=3.2.0", # Updated, see https://github.com/advisories/GHSA-rww4-4w9c-7733 for details.
13
13
  "filetype>=1.2.0",
14
14
  "importlib>=1.0.4",
@@ -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,10 +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
- from amrita_core.threadsafe import ContextThreadsafe
10
11
 
11
- from ..logging import logger
12
12
  from ..tools.models import ToolChoice, ToolFunctionSchema
13
13
  from ..types import EmbeddingChunk, ModelPreset, ToolCall, UniResponse
14
14
 
@@ -93,7 +93,7 @@ class ModelAdapter:
93
93
  return self.get_adapter_protocol()
94
94
 
95
95
 
96
- class AdapterManager(ContextThreadsafe):
96
+ class AdapterManager:
97
97
  __instance = None
98
98
  __inited = False
99
99
  _adapter_class: dict[str, type[ModelAdapter]]
@@ -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
@@ -3,8 +3,6 @@ from typing import Literal
3
3
 
4
4
  from amrita_sense.logging import logger
5
5
 
6
- from amrita_core.threadsafe import ContextThreadsafe
7
-
8
6
 
9
7
  class BaseTokenizer(ABC):
10
8
  __override__: bool = False # Whether to allow overriding existing tokenizers
@@ -64,7 +62,7 @@ class BaseTokenizer(ABC):
64
62
  ...
65
63
 
66
64
 
67
- class TokenizerManager(ContextThreadsafe):
65
+ class TokenizerManager:
68
66
  __instance = None
69
67
  __inited = False
70
68
  _tokenizer_class: dict[str, type[BaseTokenizer]]