soe-ai 0.1.3__tar.gz → 0.1.4__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 (154) hide show
  1. {soe_ai-0.1.3 → soe_ai-0.1.4}/PKG-INFO +2 -2
  2. {soe_ai-0.1.3 → soe_ai-0.1.4}/pyproject.toml +2 -2
  3. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/broker.py +14 -32
  4. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/builtin_tools/__init__.py +12 -0
  5. soe_ai-0.1.4/soe/builtin_tools/soe_get_context_schema.py +56 -0
  6. soe_ai-0.1.4/soe/builtin_tools/soe_get_identities.py +63 -0
  7. soe_ai-0.1.4/soe/builtin_tools/soe_inject_context_schema_field.py +80 -0
  8. soe_ai-0.1.4/soe/builtin_tools/soe_inject_identity.py +64 -0
  9. soe_ai-0.1.4/soe/builtin_tools/soe_remove_context_schema_field.py +61 -0
  10. soe_ai-0.1.4/soe/builtin_tools/soe_remove_identity.py +61 -0
  11. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/builtin_tools/soe_update_context.py +5 -2
  12. soe_ai-0.1.4/soe/docs/builtins/context_schema.md +158 -0
  13. soe_ai-0.1.4/soe/docs/builtins/identity.md +139 -0
  14. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/guide_01_tool.md +52 -0
  15. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/guide_02_llm.md +5 -5
  16. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/guide_11_builtins.md +11 -3
  17. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/index.md +3 -1
  18. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/primitives/node_reference.md +1 -0
  19. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/primitives/signals.md +10 -9
  20. soe_ai-0.1.4/soe/docs_index.py +2 -0
  21. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/init.py +7 -1
  22. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/lib/inheritance.py +42 -1
  23. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/agent/factory.py +1 -1
  24. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/agent/stages/response.py +3 -3
  25. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/agent/types.py +1 -1
  26. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/lib/response_builder.py +12 -10
  27. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/lib/signal_emission.py +6 -10
  28. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/llm/factory.py +3 -3
  29. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/tool/state.py +21 -1
  30. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/tool/validation/config.py +15 -0
  31. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/validation/__init__.py +7 -1
  32. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/validation/config.py +22 -0
  33. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe_ai.egg-info/PKG-INFO +2 -2
  34. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe_ai.egg-info/SOURCES.txt +10 -1
  35. soe_ai-0.1.4/tests/test_setup_orchestration.py +146 -0
  36. soe_ai-0.1.3/soe/docs_index.py +0 -2
  37. {soe_ai-0.1.3 → soe_ai-0.1.4}/LICENSE +0 -0
  38. {soe_ai-0.1.3 → soe_ai-0.1.4}/README.md +0 -0
  39. {soe_ai-0.1.3 → soe_ai-0.1.4}/setup.cfg +0 -0
  40. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/__init__.py +0 -0
  41. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/builtin_tools/soe_add_signal.py +0 -0
  42. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/builtin_tools/soe_call_tool.py +0 -0
  43. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/builtin_tools/soe_copy_context.py +0 -0
  44. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/builtin_tools/soe_explore_docs.py +0 -0
  45. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/builtin_tools/soe_get_available_tools.py +0 -0
  46. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/builtin_tools/soe_get_context.py +0 -0
  47. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/builtin_tools/soe_get_workflows.py +0 -0
  48. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/builtin_tools/soe_inject_node.py +0 -0
  49. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/builtin_tools/soe_inject_workflow.py +0 -0
  50. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/builtin_tools/soe_list_contexts.py +0 -0
  51. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/builtin_tools/soe_remove_node.py +0 -0
  52. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/builtin_tools/soe_remove_workflow.py +0 -0
  53. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/_config.yml +0 -0
  54. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/advanced_patterns/guide_fanout_and_aggregations.md +0 -0
  55. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/advanced_patterns/guide_inheritance.md +0 -0
  56. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/advanced_patterns/hybrid_intelligence.md +0 -0
  57. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/advanced_patterns/index.md +0 -0
  58. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/advanced_patterns/operational.md +0 -0
  59. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/advanced_patterns/self_evolving_workflows.md +0 -0
  60. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/advanced_patterns/swarm_intelligence.md +0 -0
  61. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/builtins/context.md +0 -0
  62. /soe_ai-0.1.3/soe/docs/builtins/explore_docs.md → /soe_ai-0.1.4/soe/docs/builtins/soe_explore_docs.md +0 -0
  63. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/builtins/tools.md +0 -0
  64. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/builtins/workflows.md +0 -0
  65. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/guide_00_getting_started.md +0 -0
  66. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/guide_03_router.md +0 -0
  67. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/guide_04_patterns.md +0 -0
  68. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/guide_05_agent.md +0 -0
  69. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/guide_06_schema.md +0 -0
  70. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/guide_07_identity.md +0 -0
  71. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/guide_08_child.md +0 -0
  72. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/guide_09_ecosystem.md +0 -0
  73. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/guide_10_infrastructure.md +0 -0
  74. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/primitives/backends.md +0 -0
  75. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/primitives/context.md +0 -0
  76. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/docs/primitives/primitives.md +0 -0
  77. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/lib/__init__.py +0 -0
  78. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/lib/child_context.py +0 -0
  79. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/lib/context_fields.py +0 -0
  80. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/lib/jinja_render.py +0 -0
  81. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/lib/operational.py +0 -0
  82. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/lib/parent_sync.py +0 -0
  83. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/lib/register_event.py +0 -0
  84. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/lib/schema_validation.py +0 -0
  85. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/lib/yaml_parser.py +0 -0
  86. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/local_backends/__init__.py +0 -0
  87. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/local_backends/factory.py +0 -0
  88. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/local_backends/in_memory/context.py +0 -0
  89. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/local_backends/in_memory/conversation_history.py +0 -0
  90. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/local_backends/in_memory/identity.py +0 -0
  91. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/local_backends/in_memory/schema.py +0 -0
  92. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/local_backends/in_memory/telemetry.py +0 -0
  93. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/local_backends/in_memory/workflow.py +0 -0
  94. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/local_backends/storage/context.py +0 -0
  95. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/local_backends/storage/conversation_history.py +0 -0
  96. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/local_backends/storage/identity.py +0 -0
  97. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/local_backends/storage/schema.py +0 -0
  98. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/local_backends/storage/telemetry.py +0 -0
  99. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/local_backends/storage/workflow.py +0 -0
  100. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/__init__.py +0 -0
  101. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/agent/__init__.py +0 -0
  102. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/agent/lib/loop_handlers.py +0 -0
  103. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/agent/lib/loop_state.py +0 -0
  104. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/agent/lib/prompts.py +0 -0
  105. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/agent/lib/tools.py +0 -0
  106. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/agent/stages/__init__.py +0 -0
  107. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/agent/stages/parameter.py +0 -0
  108. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/agent/stages/router.py +0 -0
  109. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/agent/state.py +0 -0
  110. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/agent/validation/__init__.py +0 -0
  111. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/agent/validation/config.py +0 -0
  112. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/agent/validation/operational.py +0 -0
  113. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/child/__init__.py +0 -0
  114. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/child/factory.py +0 -0
  115. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/child/state.py +0 -0
  116. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/child/validation/__init__.py +0 -0
  117. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/child/validation/config.py +0 -0
  118. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/child/validation/operational.py +0 -0
  119. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/lib/conditions.py +0 -0
  120. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/lib/context.py +0 -0
  121. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/lib/conversation_history.py +0 -0
  122. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/lib/identity.py +0 -0
  123. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/lib/llm_resolver.py +0 -0
  124. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/lib/output.py +0 -0
  125. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/lib/signals.py +0 -0
  126. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/lib/tools.py +0 -0
  127. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/llm/__init__.py +0 -0
  128. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/llm/state.py +0 -0
  129. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/llm/types.py +0 -0
  130. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/llm/validation/__init__.py +0 -0
  131. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/llm/validation/config.py +0 -0
  132. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/llm/validation/operational.py +0 -0
  133. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/router/__init__.py +0 -0
  134. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/router/factory.py +0 -0
  135. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/router/state.py +0 -0
  136. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/router/validation/__init__.py +0 -0
  137. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/router/validation/config.py +0 -0
  138. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/router/validation/operational.py +0 -0
  139. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/tool/factory.py +0 -0
  140. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/tool/lib/__init__.py +0 -0
  141. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/tool/lib/conditions.py +0 -0
  142. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/tool/lib/failure.py +0 -0
  143. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/tool/lib/parameters.py +0 -0
  144. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/tool/types.py +0 -0
  145. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/tool/validation/__init__.py +0 -0
  146. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/nodes/tool/validation/operational.py +0 -0
  147. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/types.py +0 -0
  148. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/validation/jinja.py +0 -0
  149. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe/validation/operational.py +0 -0
  150. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe_ai.egg-info/dependency_links.txt +0 -0
  151. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe_ai.egg-info/requires.txt +0 -0
  152. {soe_ai-0.1.3 → soe_ai-0.1.4}/soe_ai.egg-info/top_level.txt +0 -0
  153. {soe_ai-0.1.3 → soe_ai-0.1.4}/tests/test_local_storage_backends.py +0 -0
  154. {soe_ai-0.1.3 → soe_ai-0.1.4}/tests/test_validation_errors.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: soe-ai
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: Signal-driven Orchestration Engine - Agent orchestration with event-driven workflow engine
5
5
  Author-email: Pedro Garcia <pgarcia14180@gmail.com>
6
6
  License-Expression: MIT
@@ -9,7 +9,7 @@ Project-URL: Documentation, https://github.com/pgarcia14180/soe/tree/master/docs
9
9
  Project-URL: Repository, https://github.com/pgarcia14180/soe
10
10
  Project-URL: Issues, https://github.com/pgarcia14180/soe/issues
11
11
  Keywords: orchestration,agent,workflow,automation
12
- Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Development Status :: 4 - Beta
13
13
  Classifier: Intended Audience :: Developers
14
14
  Classifier: Programming Language :: Python :: 3
15
15
  Classifier: Programming Language :: Python :: 3.8
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "soe-ai"
7
- version = "0.1.3"
7
+ version = "0.1.4"
8
8
  description = "Signal-driven Orchestration Engine - Agent orchestration with event-driven workflow engine"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -14,7 +14,7 @@ authors = [
14
14
  ]
15
15
  keywords = ["orchestration", "agent", "workflow", "automation"]
16
16
  classifiers = [
17
- "Development Status :: 3 - Alpha",
17
+ "Development Status :: 4 - Beta",
18
18
  "Intended Audience :: Developers",
19
19
  "Programming Language :: Python :: 3",
20
20
  "Programming Language :: Python :: 3.8",
@@ -4,15 +4,18 @@ from .types import Backends, BroadcastSignalsCaller, NodeCaller, EventTypes, Wor
4
4
  from .lib.register_event import register_event
5
5
  from .lib.yaml_parser import parse_yaml
6
6
  from .lib.operational import add_operational_state
7
- from .lib.context_fields import set_field
8
7
  from .lib.parent_sync import get_signals_for_parent
9
8
  from .lib.inheritance import (
10
9
  inherit_config,
11
- inherit_context,
12
10
  extract_and_save_config_sections,
11
+ prepare_initial_context,
12
+ )
13
+ from .validation import (
14
+ validate_config,
15
+ validate_operational,
16
+ validate_orchestrate_params,
17
+ validate_initial_workflow,
13
18
  )
14
- from .validation import validate_config, validate_operational, validate_orchestrate_params
15
- from .types import WorkflowValidationError
16
19
 
17
20
 
18
21
  def orchestrate(
@@ -70,17 +73,15 @@ def orchestrate(
70
73
 
71
74
  id = str(uuid4())
72
75
 
76
+ parsed_registry = {}
73
77
  if inherit_config_from_id:
74
78
  register_event(
75
79
  backends, id, EventTypes.CONFIG_INHERITANCE_START,
76
80
  {"source_execution_id": inherit_config_from_id}
77
81
  )
78
82
  parsed_registry = inherit_config(inherit_config_from_id, id, backends)
79
- if config:
80
- validate_config(config)
81
- parsed_config = parse_yaml(config)
82
- parsed_registry = extract_and_save_config_sections(parsed_config, id, backends)
83
- else:
83
+
84
+ if config:
84
85
  validate_config(config)
85
86
  parsed_config = parse_yaml(config)
86
87
  parsed_registry = extract_and_save_config_sections(parsed_config, id, backends)
@@ -92,32 +93,13 @@ def orchestrate(
92
93
 
93
94
  backends.workflow.save_workflows_registry(id, parsed_registry)
94
95
 
95
- if initial_workflow_name not in parsed_registry:
96
- available = list(parsed_registry.keys())
97
- raise WorkflowValidationError(
98
- f"Workflow '{initial_workflow_name}' not found in config. "
99
- f"Available workflows: {available}"
100
- )
96
+ validate_initial_workflow(initial_workflow_name, parsed_registry)
101
97
 
102
98
  backends.workflow.save_current_workflow_name(id, initial_workflow_name)
103
99
 
104
- if inherit_context_from_id:
105
- register_event(
106
- backends, id, EventTypes.CONTEXT_INHERITANCE_START,
107
- )
108
- context = inherit_context(inherit_context_from_id, backends)
109
- if initial_context:
110
- register_event(
111
- backends, id, EventTypes.CONTEXT_MERGE,
112
- {"fields": list(initial_context.keys())}
113
- )
114
- for field, value in initial_context.items():
115
- set_field(context, field, value)
116
- else:
117
- context = {
118
- k: [v] if not k.startswith("__") else v
119
- for k, v in initial_context.items()
120
- }
100
+ context = prepare_initial_context(
101
+ id, initial_context, backends, inherit_context_from_id
102
+ )
121
103
 
122
104
  context = add_operational_state(id, context)
123
105
  backends.context.save_context(id, context)
@@ -15,6 +15,12 @@ from .soe_copy_context import create_soe_copy_context_tool
15
15
  from .soe_list_contexts import create_soe_list_contexts_tool
16
16
  from .soe_add_signal import create_soe_add_signal_tool
17
17
  from .soe_call_tool import create_soe_call_tool_tool
18
+ from .soe_get_identities import create_soe_get_identities_tool
19
+ from .soe_inject_identity import create_soe_inject_identity_tool
20
+ from .soe_remove_identity import create_soe_remove_identity_tool
21
+ from .soe_get_context_schema import create_soe_get_context_schema_tool
22
+ from .soe_inject_context_schema_field import create_soe_inject_context_schema_field_tool
23
+ from .soe_remove_context_schema_field import create_soe_remove_context_schema_field_tool
18
24
 
19
25
  # Registry of all available built-in tools
20
26
  BUILTIN_TOOLS = {
@@ -31,6 +37,12 @@ BUILTIN_TOOLS = {
31
37
  "soe_list_contexts": create_soe_list_contexts_tool,
32
38
  "soe_add_signal": create_soe_add_signal_tool,
33
39
  "soe_call_tool": create_soe_call_tool_tool,
40
+ "soe_get_identities": create_soe_get_identities_tool,
41
+ "soe_inject_identity": create_soe_inject_identity_tool,
42
+ "soe_remove_identity": create_soe_remove_identity_tool,
43
+ "soe_get_context_schema": create_soe_get_context_schema_tool,
44
+ "soe_inject_context_schema_field": create_soe_inject_context_schema_field_tool,
45
+ "soe_remove_context_schema_field": create_soe_remove_context_schema_field_tool,
34
46
  }
35
47
 
36
48
 
@@ -0,0 +1,56 @@
1
+ """Built-in context schema retrieval tool."""
2
+
3
+ from typing import Dict, Any, Callable, Optional
4
+
5
+
6
+ def create_soe_get_context_schema_tool(
7
+ execution_id: str,
8
+ backends,
9
+ tools_registry: dict = None,
10
+ ) -> Callable:
11
+ """
12
+ Factory function to create soe_get_context_schema tool.
13
+
14
+ Args:
15
+ execution_id: ID to access context schema data via backends
16
+ backends: Backend services to fetch context schema
17
+ tools_registry: Optional registry of available tools (unused by this tool)
18
+
19
+ Returns:
20
+ Configured soe_get_context_schema function
21
+ """
22
+
23
+ def soe_get_context_schema(
24
+ field_name: Optional[str] = None,
25
+ ) -> Dict[str, Any]:
26
+ """
27
+ Get context schema information from the current execution.
28
+
29
+ Args:
30
+ field_name: If provided, get only this specific field's definition.
31
+ If None, returns the full schema.
32
+
33
+ Returns:
34
+ If field_name provided: {"field_name": "...", "definition": {...}}
35
+ Otherwise: Full schema dict of field_name -> field_definition
36
+ """
37
+ schema = backends.context_schema.get_context_schema(execution_id)
38
+
39
+ if schema is None:
40
+ schema = {}
41
+
42
+ if field_name:
43
+ if field_name in schema:
44
+ return {
45
+ "field_name": field_name,
46
+ "definition": schema[field_name],
47
+ }
48
+ else:
49
+ return {
50
+ "error": f"Field '{field_name}' not found in context schema",
51
+ "available": list(schema.keys()),
52
+ }
53
+
54
+ return schema
55
+
56
+ return soe_get_context_schema
@@ -0,0 +1,63 @@
1
+ """Built-in identity retrieval tool."""
2
+
3
+ from typing import Dict, Any, Callable, Optional
4
+
5
+
6
+ def create_soe_get_identities_tool(
7
+ execution_id: str,
8
+ backends,
9
+ tools_registry: dict = None,
10
+ ) -> Callable:
11
+ """
12
+ Factory function to create soe_get_identities tool.
13
+
14
+ Args:
15
+ execution_id: ID to access identity data via backends
16
+ backends: Backend services to fetch identities
17
+ tools_registry: Optional registry of available tools (unused by this tool)
18
+
19
+ Returns:
20
+ Configured soe_get_identities function
21
+ """
22
+
23
+ def soe_get_identities(
24
+ identity_name: Optional[str] = None,
25
+ list_only: bool = False,
26
+ ) -> Dict[str, Any]:
27
+ """
28
+ Get identity information from the current execution.
29
+
30
+ Args:
31
+ identity_name: If provided, get only this specific identity's system prompt.
32
+ If None, returns info about all identities.
33
+ list_only: If True, only return identity names (not full system prompts).
34
+ Default is False.
35
+
36
+ Returns:
37
+ If list_only=True: {"identity_names": ["assistant", "expert", ...]}
38
+ If identity_name provided: {"identity_name": "...", "system_prompt": "..."}
39
+ Otherwise: Full dict of identity_name -> system_prompt
40
+ """
41
+ identities = backends.identity.get_identities(execution_id)
42
+
43
+ if identities is None:
44
+ identities = {}
45
+
46
+ if list_only:
47
+ return {"identity_names": list(identities.keys())}
48
+
49
+ if identity_name:
50
+ if identity_name in identities:
51
+ return {
52
+ "identity_name": identity_name,
53
+ "system_prompt": identities[identity_name],
54
+ }
55
+ else:
56
+ return {
57
+ "error": f"Identity '{identity_name}' not found",
58
+ "available": list(identities.keys()),
59
+ }
60
+
61
+ return identities
62
+
63
+ return soe_get_identities
@@ -0,0 +1,80 @@
1
+ """Built-in context schema field injection tool."""
2
+
3
+ import json
4
+ from typing import Dict, Any, Callable
5
+ from ..types import EventTypes
6
+ from ..lib.register_event import register_event
7
+ from ..lib.yaml_parser import parse_yaml
8
+
9
+
10
+ def create_soe_inject_context_schema_field_tool(
11
+ execution_id: str,
12
+ backends,
13
+ tools_registry: dict = None,
14
+ ) -> Callable:
15
+ """
16
+ Factory function to create soe_inject_context_schema_field tool.
17
+
18
+ Args:
19
+ execution_id: ID to access context schema data via backends
20
+ backends: Backend services to fetch/update context schema
21
+ tools_registry: Optional registry of available tools (unused by this tool)
22
+
23
+ Returns:
24
+ Configured soe_inject_context_schema_field function
25
+ """
26
+
27
+ def soe_inject_context_schema_field(
28
+ field_name: str,
29
+ field_definition: str,
30
+ ) -> Dict[str, Any]:
31
+ """
32
+ Add or update a field in the context schema.
33
+
34
+ Args:
35
+ field_name: Name of the field to add/update
36
+ field_definition: JSON or YAML string with field definition
37
+ (e.g., {"type": "string", "description": "..."})
38
+
39
+ Returns:
40
+ Success confirmation with field info and action taken
41
+ """
42
+ parsed_definition = None
43
+
44
+ try:
45
+ parsed_definition = json.loads(field_definition)
46
+ except json.JSONDecodeError:
47
+ parsed_definition = parse_yaml(field_definition)
48
+
49
+ if not isinstance(parsed_definition, dict):
50
+ raise ValueError("Field definition must be a dictionary/object")
51
+
52
+ schema = backends.context_schema.get_context_schema(execution_id)
53
+
54
+ if schema is None:
55
+ schema = {}
56
+
57
+ action = "updated" if field_name in schema else "created"
58
+
59
+ schema[field_name] = parsed_definition
60
+ backends.context_schema.save_context_schema(execution_id, schema)
61
+
62
+ register_event(
63
+ backends,
64
+ execution_id,
65
+ EventTypes.NODE_EXECUTION,
66
+ {
67
+ "tool": "soe_inject_context_schema_field",
68
+ "field_name": field_name,
69
+ "action": action,
70
+ },
71
+ )
72
+
73
+ return {
74
+ "success": True,
75
+ "field_name": field_name,
76
+ "action": action,
77
+ "message": f"Successfully {action} field '{field_name}' in context schema",
78
+ }
79
+
80
+ return soe_inject_context_schema_field
@@ -0,0 +1,64 @@
1
+ """Built-in identity injection tool."""
2
+
3
+ from typing import Dict, Any, Callable
4
+ from ..types import EventTypes
5
+ from ..lib.register_event import register_event
6
+
7
+
8
+ def create_soe_inject_identity_tool(
9
+ execution_id: str,
10
+ backends,
11
+ tools_registry: dict = None,
12
+ ) -> Callable:
13
+ """
14
+ Factory function to create soe_inject_identity tool.
15
+
16
+ Args:
17
+ execution_id: ID to access identity data via backends
18
+ backends: Backend services to fetch/update identities
19
+ tools_registry: Optional registry of available tools (unused by this tool)
20
+
21
+ Returns:
22
+ Configured soe_inject_identity function that can add/update identities
23
+ """
24
+
25
+ def soe_inject_identity(identity_name: str, system_prompt: str) -> Dict[str, Any]:
26
+ """
27
+ Add or update an identity definition.
28
+
29
+ Args:
30
+ identity_name: Name/key for the identity
31
+ system_prompt: The system prompt text for this identity
32
+
33
+ Returns:
34
+ Success confirmation with identity info and action taken
35
+ """
36
+ identities = backends.identity.get_identities(execution_id)
37
+
38
+ if identities is None:
39
+ identities = {}
40
+
41
+ action = "updated" if identity_name in identities else "created"
42
+
43
+ identities[identity_name] = system_prompt
44
+ backends.identity.save_identities(execution_id, identities)
45
+
46
+ register_event(
47
+ backends,
48
+ execution_id,
49
+ EventTypes.NODE_EXECUTION,
50
+ {
51
+ "tool": "soe_inject_identity",
52
+ "identity_name": identity_name,
53
+ "action": action,
54
+ },
55
+ )
56
+
57
+ return {
58
+ "success": True,
59
+ "identity_name": identity_name,
60
+ "action": action,
61
+ "message": f"Successfully {action} identity '{identity_name}'",
62
+ }
63
+
64
+ return soe_inject_identity
@@ -0,0 +1,61 @@
1
+ """Built-in context schema field removal tool."""
2
+
3
+ from typing import Dict, Any, Callable
4
+ from ..types import EventTypes
5
+ from ..lib.register_event import register_event
6
+
7
+
8
+ def create_soe_remove_context_schema_field_tool(
9
+ execution_id: str,
10
+ backends,
11
+ tools_registry: dict = None,
12
+ ) -> Callable:
13
+ """
14
+ Factory function to create soe_remove_context_schema_field tool.
15
+
16
+ Args:
17
+ execution_id: ID to access context schema data via backends
18
+ backends: Backend services to fetch/update context schema
19
+ tools_registry: Optional registry of available tools (unused by this tool)
20
+
21
+ Returns:
22
+ Configured soe_remove_context_schema_field function
23
+ """
24
+
25
+ def soe_remove_context_schema_field(field_name: str) -> Dict[str, Any]:
26
+ """
27
+ Remove a field from the context schema.
28
+
29
+ Args:
30
+ field_name: Name of the field to remove
31
+
32
+ Returns:
33
+ Success confirmation with removed field info
34
+ """
35
+ schema = backends.context_schema.get_context_schema(execution_id)
36
+
37
+ if schema is None or field_name not in schema:
38
+ raise ValueError(
39
+ f"Field '{field_name}' not found in context schema"
40
+ )
41
+
42
+ del schema[field_name]
43
+ backends.context_schema.save_context_schema(execution_id, schema)
44
+
45
+ register_event(
46
+ backends,
47
+ execution_id,
48
+ EventTypes.NODE_EXECUTION,
49
+ {
50
+ "tool": "soe_remove_context_schema_field",
51
+ "field_name": field_name,
52
+ },
53
+ )
54
+
55
+ return {
56
+ "removed": True,
57
+ "field_name": field_name,
58
+ "message": f"Successfully removed field '{field_name}' from context schema",
59
+ }
60
+
61
+ return soe_remove_context_schema_field
@@ -0,0 +1,61 @@
1
+ """Built-in identity removal tool."""
2
+
3
+ from typing import Dict, Any, Callable
4
+ from ..types import EventTypes
5
+ from ..lib.register_event import register_event
6
+
7
+
8
+ def create_soe_remove_identity_tool(
9
+ execution_id: str,
10
+ backends,
11
+ tools_registry: dict = None,
12
+ ) -> Callable:
13
+ """
14
+ Factory function to create soe_remove_identity tool.
15
+
16
+ Args:
17
+ execution_id: ID to access identity data via backends
18
+ backends: Backend services to fetch/update identities
19
+ tools_registry: Optional registry of available tools (unused by this tool)
20
+
21
+ Returns:
22
+ Configured soe_remove_identity function that can remove identities
23
+ """
24
+
25
+ def soe_remove_identity(identity_name: str) -> Dict[str, Any]:
26
+ """
27
+ Remove an identity definition.
28
+
29
+ Args:
30
+ identity_name: Name of the identity to remove
31
+
32
+ Returns:
33
+ Success confirmation with removed identity info
34
+ """
35
+ identities = backends.identity.get_identities(execution_id)
36
+
37
+ if identities is None or identity_name not in identities:
38
+ raise ValueError(
39
+ f"Identity '{identity_name}' not found"
40
+ )
41
+
42
+ del identities[identity_name]
43
+ backends.identity.save_identities(execution_id, identities)
44
+
45
+ register_event(
46
+ backends,
47
+ execution_id,
48
+ EventTypes.NODE_EXECUTION,
49
+ {
50
+ "tool": "soe_remove_identity",
51
+ "identity_name": identity_name,
52
+ },
53
+ )
54
+
55
+ return {
56
+ "removed": True,
57
+ "identity_name": identity_name,
58
+ "message": f"Successfully removed identity '{identity_name}'",
59
+ }
60
+
61
+ return soe_remove_identity
@@ -5,6 +5,8 @@ Allows agents to write context fields dynamically.
5
5
 
6
6
  from typing import Any, Dict
7
7
 
8
+ from ..lib.context_fields import set_field
9
+
8
10
 
9
11
  def create_soe_update_context_tool(backends, execution_id: str, tools_registry=None):
10
12
  """
@@ -41,9 +43,10 @@ def create_soe_update_context_tool(backends, execution_id: str, tools_registry=N
41
43
  if not filtered_updates:
42
44
  return {"status": "no valid updates (operational fields cannot be updated)"}
43
45
 
44
- # Get current context and update
46
+ # Get current context and update using set_field for proper list wrapping
45
47
  context = backends.context.get_context(execution_id)
46
- context.update(filtered_updates)
48
+ for field, value in filtered_updates.items():
49
+ set_field(context, field, value)
47
50
  backends.context.save_context(execution_id, context)
48
51
 
49
52
  return {