AbstractRuntime 0.4.0__py3-none-any.whl → 0.4.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. abstractruntime/__init__.py +76 -1
  2. abstractruntime/core/config.py +68 -1
  3. abstractruntime/core/models.py +5 -0
  4. abstractruntime/core/policy.py +74 -3
  5. abstractruntime/core/runtime.py +1002 -126
  6. abstractruntime/core/vars.py +8 -2
  7. abstractruntime/evidence/recorder.py +1 -1
  8. abstractruntime/history_bundle.py +772 -0
  9. abstractruntime/integrations/abstractcore/__init__.py +3 -0
  10. abstractruntime/integrations/abstractcore/default_tools.py +127 -3
  11. abstractruntime/integrations/abstractcore/effect_handlers.py +2440 -99
  12. abstractruntime/integrations/abstractcore/embeddings_client.py +69 -0
  13. abstractruntime/integrations/abstractcore/factory.py +68 -20
  14. abstractruntime/integrations/abstractcore/llm_client.py +447 -15
  15. abstractruntime/integrations/abstractcore/mcp_worker.py +1 -0
  16. abstractruntime/integrations/abstractcore/session_attachments.py +946 -0
  17. abstractruntime/integrations/abstractcore/tool_executor.py +31 -10
  18. abstractruntime/integrations/abstractcore/workspace_scoped_tools.py +561 -0
  19. abstractruntime/integrations/abstractmemory/__init__.py +3 -0
  20. abstractruntime/integrations/abstractmemory/effect_handlers.py +946 -0
  21. abstractruntime/memory/active_context.py +6 -1
  22. abstractruntime/memory/kg_packets.py +164 -0
  23. abstractruntime/memory/memact_composer.py +175 -0
  24. abstractruntime/memory/recall_levels.py +163 -0
  25. abstractruntime/memory/token_budget.py +86 -0
  26. abstractruntime/storage/__init__.py +4 -1
  27. abstractruntime/storage/artifacts.py +158 -30
  28. abstractruntime/storage/base.py +17 -1
  29. abstractruntime/storage/commands.py +339 -0
  30. abstractruntime/storage/in_memory.py +41 -1
  31. abstractruntime/storage/json_files.py +195 -12
  32. abstractruntime/storage/observable.py +38 -1
  33. abstractruntime/storage/offloading.py +433 -0
  34. abstractruntime/storage/sqlite.py +836 -0
  35. abstractruntime/visualflow_compiler/__init__.py +29 -0
  36. abstractruntime/visualflow_compiler/adapters/__init__.py +11 -0
  37. abstractruntime/visualflow_compiler/adapters/agent_adapter.py +126 -0
  38. abstractruntime/visualflow_compiler/adapters/context_adapter.py +109 -0
  39. abstractruntime/visualflow_compiler/adapters/control_adapter.py +615 -0
  40. abstractruntime/visualflow_compiler/adapters/effect_adapter.py +1051 -0
  41. abstractruntime/visualflow_compiler/adapters/event_adapter.py +307 -0
  42. abstractruntime/visualflow_compiler/adapters/function_adapter.py +97 -0
  43. abstractruntime/visualflow_compiler/adapters/memact_adapter.py +114 -0
  44. abstractruntime/visualflow_compiler/adapters/subflow_adapter.py +74 -0
  45. abstractruntime/visualflow_compiler/adapters/variable_adapter.py +316 -0
  46. abstractruntime/visualflow_compiler/compiler.py +3832 -0
  47. abstractruntime/visualflow_compiler/flow.py +247 -0
  48. abstractruntime/visualflow_compiler/visual/__init__.py +13 -0
  49. abstractruntime/visualflow_compiler/visual/agent_ids.py +29 -0
  50. abstractruntime/visualflow_compiler/visual/builtins.py +1376 -0
  51. abstractruntime/visualflow_compiler/visual/code_executor.py +214 -0
  52. abstractruntime/visualflow_compiler/visual/executor.py +2804 -0
  53. abstractruntime/visualflow_compiler/visual/models.py +211 -0
  54. abstractruntime/workflow_bundle/__init__.py +52 -0
  55. abstractruntime/workflow_bundle/models.py +236 -0
  56. abstractruntime/workflow_bundle/packer.py +317 -0
  57. abstractruntime/workflow_bundle/reader.py +87 -0
  58. abstractruntime/workflow_bundle/registry.py +587 -0
  59. abstractruntime-0.4.1.dist-info/METADATA +177 -0
  60. abstractruntime-0.4.1.dist-info/RECORD +86 -0
  61. abstractruntime-0.4.0.dist-info/METADATA +0 -167
  62. abstractruntime-0.4.0.dist-info/RECORD +0 -49
  63. {abstractruntime-0.4.0.dist-info → abstractruntime-0.4.1.dist-info}/WHEEL +0 -0
  64. {abstractruntime-0.4.0.dist-info → abstractruntime-0.4.1.dist-info}/entry_points.txt +0 -0
  65. {abstractruntime-0.4.0.dist-info → abstractruntime-0.4.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,69 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Any, List, Sequence
5
+
6
+
7
+ @dataclass(frozen=True)
8
+ class EmbeddingsResult:
9
+ provider: str
10
+ model: str
11
+ embeddings: List[List[float]]
12
+ dimension: int
13
+
14
+
15
+ class AbstractCoreEmbeddingsClient:
16
+ """Thin adapter around AbstractCore's EmbeddingManager.
17
+
18
+ Notes:
19
+ - AbstractCore is an optional dependency of AbstractRuntime; importing this module is an explicit opt-in.
20
+ - The embedding provider/model should be treated as a runtime-instance property (singleton) so all vectors
21
+ live in the same embedding space.
22
+ """
23
+
24
+ def __init__(
25
+ self,
26
+ *,
27
+ provider: str,
28
+ model: str,
29
+ manager_kwargs: dict[str, Any] | None = None,
30
+ ) -> None:
31
+ # Monorepo import hygiene:
32
+ # When running from the repo root, `abstractcore/` (project folder) can be imported as a
33
+ # namespace package and shadow the real python package at `abstractcore/abstractcore/`.
34
+ # In that situation, `abstractcore.embeddings.manager` may not resolve even though the
35
+ # implementation exists. Prefer the public import, but fall back to the concrete path.
36
+ try:
37
+ from abstractcore.embeddings.manager import EmbeddingManager # type: ignore
38
+ except Exception: # pragma: no cover
39
+ from abstractcore.abstractcore.embeddings.manager import EmbeddingManager # type: ignore
40
+
41
+ prov = str(provider or "").strip().lower()
42
+ mod = str(model or "").strip()
43
+ if not prov:
44
+ raise ValueError("provider is required for embeddings")
45
+ if not mod:
46
+ raise ValueError("model is required for embeddings")
47
+
48
+ self._provider = prov
49
+ self._model = mod
50
+ self._mgr = EmbeddingManager(provider=prov, model=mod, **(manager_kwargs or {}))
51
+
52
+ @property
53
+ def provider(self) -> str:
54
+ return self._provider
55
+
56
+ @property
57
+ def model(self) -> str:
58
+ return self._model
59
+
60
+ def embed_texts(self, texts: Sequence[str]) -> EmbeddingsResult:
61
+ items = [str(t or "") for t in texts]
62
+ embeddings = self._mgr.embed_batch(items)
63
+ dim = int(self._mgr.get_dimension() or 0)
64
+ return EmbeddingsResult(
65
+ provider=self._provider,
66
+ model=self._model,
67
+ embeddings=embeddings,
68
+ dimension=dim,
69
+ )
@@ -60,11 +60,12 @@ def create_local_runtime(
60
60
  run_store: Optional[RunStore] = None,
61
61
  ledger_store: Optional[LedgerStore] = None,
62
62
  tool_executor: Optional[ToolExecutor] = None,
63
- tool_timeout_s: float = DEFAULT_TOOL_TIMEOUT_S,
63
+ tool_timeout_s: Optional[float] = None,
64
64
  context: Optional[Any] = None,
65
65
  effect_policy: Optional[Any] = None,
66
66
  config: Optional[RuntimeConfig] = None,
67
67
  artifact_store: Optional[ArtifactStore] = None,
68
+ extra_effect_handlers: Optional[Dict[Any, Any]] = None,
68
69
  ) -> Runtime:
69
70
  """Create a runtime with local LLM execution via AbstractCore.
70
71
 
@@ -92,23 +93,39 @@ def create_local_runtime(
92
93
  if artifact_store is None:
93
94
  artifact_store = InMemoryArtifactStore()
94
95
 
95
- # Runtime authority: default LLM timeout for orchestrated workflows.
96
+ # Runtime authority: choose default timeouts for orchestrated workflows.
96
97
  #
97
- # We set this here (in the runtime layer) rather than relying on AbstractCore global config,
98
- # so workflow behavior is consistent and controlled by the orchestrator.
98
+ # Note: local providers may ignore timeouts (e.g. MLX) and should warn explicitly when doing so.
99
+ # We still pass a timeout through the runtime for future-proofing and consistent orchestration
100
+ # policy across providers.
101
+ default_llm_timeout_s: float = DEFAULT_LLM_TIMEOUT_S
102
+ default_tool_timeout_s: float = DEFAULT_TOOL_TIMEOUT_S
103
+ try:
104
+ from abstractcore.config.manager import get_config_manager # type: ignore
105
+
106
+ cfg_mgr = get_config_manager()
107
+ default_llm_timeout_s = float(cfg_mgr.get_default_timeout())
108
+ default_tool_timeout_s = float(cfg_mgr.get_tool_timeout())
109
+ except Exception:
110
+ pass
111
+
112
+ resolved_tool_timeout_s = float(tool_timeout_s) if tool_timeout_s is not None else float(default_tool_timeout_s)
113
+
99
114
  effective_llm_kwargs: Dict[str, Any] = dict(llm_kwargs or {})
100
- effective_llm_kwargs.setdefault("timeout", DEFAULT_LLM_TIMEOUT_S)
115
+ effective_llm_kwargs.setdefault("timeout", float(default_llm_timeout_s))
101
116
 
102
117
  llm_client = MultiLocalAbstractCoreLLMClient(provider=provider, model=model, llm_kwargs=effective_llm_kwargs)
103
- tools = tool_executor or AbstractCoreToolExecutor(timeout_s=tool_timeout_s)
118
+ tools = tool_executor or AbstractCoreToolExecutor(timeout_s=resolved_tool_timeout_s)
104
119
  # Orchestrator policy: enforce tool execution timeout at the runtime layer.
105
120
  try:
106
121
  setter = getattr(tools, "set_timeout_s", None)
107
122
  if callable(setter):
108
- setter(tool_timeout_s)
123
+ setter(resolved_tool_timeout_s)
109
124
  except Exception:
110
125
  pass
111
- handlers = build_effect_handlers(llm=llm_client, tools=tools)
126
+ handlers = build_effect_handlers(llm=llm_client, tools=tools, artifact_store=artifact_store, run_store=run_store)
127
+ if extra_effect_handlers:
128
+ handlers.update(dict(extra_effect_handlers))
112
129
 
113
130
  # Query model capabilities and merge into config
114
131
  capabilities = llm_client.get_model_capabilities()
@@ -130,7 +147,7 @@ def create_local_runtime(
130
147
  max_output_tokens=config.max_output_tokens if config.max_output_tokens is not None else -1,
131
148
  )
132
149
 
133
- return Runtime(
150
+ rt = Runtime(
134
151
  run_store=run_store,
135
152
  ledger_store=ledger_store,
136
153
  effect_handlers=handlers,
@@ -140,6 +157,13 @@ def create_local_runtime(
140
157
  artifact_store=artifact_store,
141
158
  chat_summarizer=summarizer,
142
159
  )
160
+ # Best-effort: expose the underlying LLM client for host-side control planes (e.g. gateway cache ops).
161
+ # This stays an internal attribute to avoid hard API commitments on Runtime itself.
162
+ try: # pragma: no cover
163
+ setattr(rt, "_abstractcore_llm_client", llm_client)
164
+ except Exception:
165
+ pass
166
+ return rt
143
167
 
144
168
 
145
169
  def create_remote_runtime(
@@ -147,7 +171,7 @@ def create_remote_runtime(
147
171
  server_base_url: str,
148
172
  model: str,
149
173
  headers: Optional[Dict[str, str]] = None,
150
- timeout_s: float = DEFAULT_LLM_TIMEOUT_S,
174
+ timeout_s: Optional[float] = None,
151
175
  run_store: Optional[RunStore] = None,
152
176
  ledger_store: Optional[LedgerStore] = None,
153
177
  tool_executor: Optional[ToolExecutor] = None,
@@ -161,14 +185,23 @@ def create_remote_runtime(
161
185
  if artifact_store is None:
162
186
  artifact_store = InMemoryArtifactStore()
163
187
 
188
+ resolved_timeout_s = float(timeout_s) if timeout_s is not None else float(DEFAULT_LLM_TIMEOUT_S)
189
+ if timeout_s is None:
190
+ try:
191
+ from abstractcore.config.manager import get_config_manager # type: ignore
192
+
193
+ resolved_timeout_s = float(get_config_manager().get_default_timeout())
194
+ except Exception:
195
+ pass
196
+
164
197
  llm_client = RemoteAbstractCoreLLMClient(
165
198
  server_base_url=server_base_url,
166
199
  model=model,
167
200
  headers=headers,
168
- timeout_s=timeout_s,
201
+ timeout_s=resolved_timeout_s,
169
202
  )
170
203
  tools = tool_executor or PassthroughToolExecutor()
171
- handlers = build_effect_handlers(llm=llm_client, tools=tools)
204
+ handlers = build_effect_handlers(llm=llm_client, tools=tools, artifact_store=artifact_store, run_store=run_store)
172
205
 
173
206
  return Runtime(
174
207
  run_store=run_store,
@@ -184,8 +217,8 @@ def create_hybrid_runtime(
184
217
  server_base_url: str,
185
218
  model: str,
186
219
  headers: Optional[Dict[str, str]] = None,
187
- timeout_s: float = DEFAULT_LLM_TIMEOUT_S,
188
- tool_timeout_s: float = DEFAULT_TOOL_TIMEOUT_S,
220
+ timeout_s: Optional[float] = None,
221
+ tool_timeout_s: Optional[float] = None,
189
222
  run_store: Optional[RunStore] = None,
190
223
  ledger_store: Optional[LedgerStore] = None,
191
224
  context: Optional[Any] = None,
@@ -200,20 +233,35 @@ def create_hybrid_runtime(
200
233
  if artifact_store is None:
201
234
  artifact_store = InMemoryArtifactStore()
202
235
 
236
+ default_llm_timeout_s = float(DEFAULT_LLM_TIMEOUT_S)
237
+ default_tool_timeout_s = float(DEFAULT_TOOL_TIMEOUT_S)
238
+ if timeout_s is None or tool_timeout_s is None:
239
+ try:
240
+ from abstractcore.config.manager import get_config_manager # type: ignore
241
+
242
+ cfg_mgr = get_config_manager()
243
+ default_llm_timeout_s = float(cfg_mgr.get_default_timeout())
244
+ default_tool_timeout_s = float(cfg_mgr.get_tool_timeout())
245
+ except Exception:
246
+ pass
247
+
248
+ resolved_timeout_s = float(timeout_s) if timeout_s is not None else float(default_llm_timeout_s)
249
+ resolved_tool_timeout_s = float(tool_timeout_s) if tool_timeout_s is not None else float(default_tool_timeout_s)
250
+
203
251
  llm_client = RemoteAbstractCoreLLMClient(
204
252
  server_base_url=server_base_url,
205
253
  model=model,
206
254
  headers=headers,
207
- timeout_s=timeout_s,
255
+ timeout_s=resolved_timeout_s,
208
256
  )
209
- tools = AbstractCoreToolExecutor(timeout_s=tool_timeout_s)
257
+ tools = AbstractCoreToolExecutor(timeout_s=resolved_tool_timeout_s)
210
258
  try:
211
259
  setter = getattr(tools, "set_timeout_s", None)
212
260
  if callable(setter):
213
- setter(tool_timeout_s)
261
+ setter(resolved_tool_timeout_s)
214
262
  except Exception:
215
263
  pass
216
- handlers = build_effect_handlers(llm=llm_client, tools=tools)
264
+ handlers = build_effect_handlers(llm=llm_client, tools=tools, artifact_store=artifact_store, run_store=run_store)
217
265
 
218
266
  return Runtime(
219
267
  run_store=run_store,
@@ -232,7 +280,7 @@ def create_local_file_runtime(
232
280
  llm_kwargs: Optional[Dict[str, Any]] = None,
233
281
  context: Optional[Any] = None,
234
282
  config: Optional[RuntimeConfig] = None,
235
- tool_timeout_s: float = DEFAULT_TOOL_TIMEOUT_S,
283
+ tool_timeout_s: Optional[float] = None,
236
284
  ) -> Runtime:
237
285
  run_store, ledger_store = _default_file_stores(base_dir=base_dir)
238
286
  artifact_store = FileArtifactStore(base_dir)
@@ -255,7 +303,7 @@ def create_remote_file_runtime(
255
303
  server_base_url: str,
256
304
  model: str,
257
305
  headers: Optional[Dict[str, str]] = None,
258
- timeout_s: float = DEFAULT_LLM_TIMEOUT_S,
306
+ timeout_s: Optional[float] = None,
259
307
  context: Optional[Any] = None,
260
308
  ) -> Runtime:
261
309
  run_store, ledger_store = _default_file_stores(base_dir=base_dir)