agent-runtime-core 0.7.0__tar.gz → 0.7.1__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 (75) hide show
  1. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/PKG-INFO +202 -1
  2. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/README.md +195 -0
  3. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/__init__.py +108 -1
  4. agent_runtime_core-0.7.1/agent_runtime_core/agentic_loop.py +254 -0
  5. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/config.py +54 -4
  6. agent_runtime_core-0.7.1/agent_runtime_core/config_schema.py +307 -0
  7. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/interfaces.py +106 -0
  8. agent_runtime_core-0.7.1/agent_runtime_core/json_runtime.py +509 -0
  9. agent_runtime_core-0.7.1/agent_runtime_core/llm/__init__.py +156 -0
  10. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/llm/anthropic.py +133 -12
  11. agent_runtime_core-0.7.1/agent_runtime_core/llm/models_config.py +180 -0
  12. agent_runtime_core-0.7.1/agent_runtime_core/memory/__init__.py +70 -0
  13. agent_runtime_core-0.7.1/agent_runtime_core/memory/manager.py +554 -0
  14. agent_runtime_core-0.7.1/agent_runtime_core/memory/mixin.py +294 -0
  15. agent_runtime_core-0.7.1/agent_runtime_core/multi_agent.py +569 -0
  16. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/persistence/__init__.py +2 -0
  17. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/persistence/file.py +277 -0
  18. agent_runtime_core-0.7.1/agent_runtime_core/rag/__init__.py +65 -0
  19. agent_runtime_core-0.7.1/agent_runtime_core/rag/chunking.py +224 -0
  20. agent_runtime_core-0.7.1/agent_runtime_core/rag/indexer.py +253 -0
  21. agent_runtime_core-0.7.1/agent_runtime_core/rag/retriever.py +261 -0
  22. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/runner.py +193 -15
  23. agent_runtime_core-0.7.1/agent_runtime_core/tool_calling_agent.py +214 -0
  24. agent_runtime_core-0.7.1/agent_runtime_core/tools.py +179 -0
  25. agent_runtime_core-0.7.1/agent_runtime_core/vectorstore/__init__.py +193 -0
  26. agent_runtime_core-0.7.1/agent_runtime_core/vectorstore/base.py +138 -0
  27. agent_runtime_core-0.7.1/agent_runtime_core/vectorstore/embeddings.py +242 -0
  28. agent_runtime_core-0.7.1/agent_runtime_core/vectorstore/sqlite_vec.py +328 -0
  29. agent_runtime_core-0.7.1/agent_runtime_core/vectorstore/vertex.py +295 -0
  30. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/pyproject.toml +6 -1
  31. agent_runtime_core-0.7.1/tests/test_memory.py +503 -0
  32. agent_runtime_core-0.7.1/tests/test_multi_agent.py +465 -0
  33. agent_runtime_core-0.7.1/tests/test_rag.py +235 -0
  34. agent_runtime_core-0.7.1/tests/test_tools.py +275 -0
  35. agent_runtime_core-0.7.1/tests/test_vectorstore.py +242 -0
  36. agent_runtime_core-0.7.0/agent_runtime_core/llm/__init__.py +0 -83
  37. agent_runtime_core-0.7.0/agent_runtime_core/tool_calling_agent.py +0 -256
  38. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/.gitignore +0 -0
  39. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/LICENSE +0 -0
  40. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/contexts.py +0 -0
  41. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/events/__init__.py +0 -0
  42. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/events/base.py +0 -0
  43. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/events/memory.py +0 -0
  44. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/events/redis.py +0 -0
  45. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/events/sqlite.py +0 -0
  46. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/llm/litellm_client.py +0 -0
  47. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/llm/openai.py +0 -0
  48. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/persistence/base.py +0 -0
  49. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/persistence/manager.py +0 -0
  50. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/queue/__init__.py +0 -0
  51. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/queue/base.py +0 -0
  52. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/queue/memory.py +0 -0
  53. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/queue/redis.py +0 -0
  54. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/queue/sqlite.py +0 -0
  55. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/registry.py +0 -0
  56. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/state/__init__.py +0 -0
  57. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/state/base.py +0 -0
  58. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/state/memory.py +0 -0
  59. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/state/redis.py +0 -0
  60. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/state/sqlite.py +0 -0
  61. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/steps.py +0 -0
  62. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/testing.py +0 -0
  63. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/tracing/__init__.py +0 -0
  64. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/tracing/langfuse.py +0 -0
  65. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/agent_runtime_core/tracing/noop.py +0 -0
  66. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/tests/__init__.py +0 -0
  67. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/tests/test_contexts.py +0 -0
  68. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/tests/test_events.py +0 -0
  69. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/tests/test_imports.py +0 -0
  70. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/tests/test_persistence.py +0 -0
  71. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/tests/test_queue.py +0 -0
  72. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/tests/test_state.py +0 -0
  73. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/tests/test_steps.py +0 -0
  74. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/tests/test_testing.py +0 -0
  75. {agent_runtime_core-0.7.0 → agent_runtime_core-0.7.1}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-runtime-core
3
- Version: 0.7.0
3
+ Version: 0.7.1
4
4
  Summary: Framework-agnostic Python library for executing AI agents with consistent patterns
5
5
  Project-URL: Homepage, https://github.com/makemore/agent-runtime-core
6
6
  Project-URL: Repository, https://github.com/makemore/agent-runtime-core
@@ -19,10 +19,12 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
19
  Requires-Python: >=3.11
20
20
  Provides-Extra: all
21
21
  Requires-Dist: anthropic>=0.18.0; extra == 'all'
22
+ Requires-Dist: google-cloud-aiplatform>=1.38.0; extra == 'all'
22
23
  Requires-Dist: langfuse>=2.0.0; extra == 'all'
23
24
  Requires-Dist: litellm>=1.0.0; extra == 'all'
24
25
  Requires-Dist: openai>=1.0.0; extra == 'all'
25
26
  Requires-Dist: redis>=5.0.0; extra == 'all'
27
+ Requires-Dist: sqlite-vec>=0.1.0; extra == 'all'
26
28
  Provides-Extra: anthropic
27
29
  Requires-Dist: anthropic>=0.18.0; extra == 'anthropic'
28
30
  Provides-Extra: dev
@@ -39,6 +41,10 @@ Provides-Extra: openai
39
41
  Requires-Dist: openai>=1.0.0; extra == 'openai'
40
42
  Provides-Extra: redis
41
43
  Requires-Dist: redis>=5.0.0; extra == 'redis'
44
+ Provides-Extra: sqlite-vec
45
+ Requires-Dist: sqlite-vec>=0.1.0; extra == 'sqlite-vec'
46
+ Provides-Extra: vertex
47
+ Requires-Dist: google-cloud-aiplatform>=1.38.0; extra == 'vertex'
42
48
  Description-Content-Type: text/markdown
43
49
 
44
50
  # agent-runtime-core
@@ -53,6 +59,7 @@ A lightweight, framework-agnostic Python library for building AI agent systems.
53
59
 
54
60
  | Version | Date | Changes |
55
61
  |---------|------|---------|
62
+ | **0.7.1** | 2026-01-24 | RAG module, vector stores (sqlite-vec, Vertex AI), memory system, multi-agent support, agentic loop, JSON runtime |
56
63
  | **0.6.0** | 2025-01-23 | Enhanced registry with factory functions and class registration |
57
64
  | **0.5.2** | 2025-01-14 | Add ToolCallingAgent base class, execute_with_events helper |
58
65
  | **0.5.1** | 2025-01-13 | Bug fixes and improvements |
@@ -820,6 +827,200 @@ The executor emits events for observability:
820
827
  - `EventType.STEP_SKIPPED` - Step skipped (already completed)
821
828
  - `EventType.PROGRESS_UPDATE` - Progress percentage update
822
829
 
830
+ ## Multi-Agent Systems
831
+
832
+ The `multi_agent` module provides the "agent-as-tool" pattern, allowing agents to invoke other agents as tools. This enables router/dispatcher patterns, hierarchical agent systems, and specialist delegation.
833
+
834
+ ### Core Concepts
835
+
836
+ **Invocation Modes:**
837
+ - `DELEGATE`: Sub-agent runs and returns result to parent (parent continues). Good for "get me an answer".
838
+ - `HANDOFF`: Control transfers completely to sub-agent (parent exits). Good for "transfer this customer to billing".
839
+
840
+ **Context Modes:**
841
+ - `FULL`: Complete conversation history passed to sub-agent (default)
842
+ - `SUMMARY`: Summarized context + current message (more efficient)
843
+ - `MESSAGE_ONLY`: Only the invocation message (clean isolation)
844
+
845
+ ### Creating Agent Tools
846
+
847
+ Wrap any agent as a tool that can be called by other agents:
848
+
849
+ ```python
850
+ from agent_runtime_core.multi_agent import (
851
+ AgentTool,
852
+ InvocationMode,
853
+ ContextMode,
854
+ invoke_agent,
855
+ register_agent_tools,
856
+ )
857
+
858
+ # Define specialist agents
859
+ class BillingAgent(AgentRuntime):
860
+ @property
861
+ def key(self) -> str:
862
+ return "billing-specialist"
863
+
864
+ async def run(self, ctx: RunContext) -> RunResult:
865
+ # Handle billing questions, refunds, payments
866
+ ...
867
+
868
+ class TechSupportAgent(AgentRuntime):
869
+ @property
870
+ def key(self) -> str:
871
+ return "tech-support"
872
+
873
+ async def run(self, ctx: RunContext) -> RunResult:
874
+ # Handle technical issues
875
+ ...
876
+
877
+ # Wrap agents as tools
878
+ billing_tool = AgentTool(
879
+ agent=BillingAgent(),
880
+ name="billing_specialist",
881
+ description="Handles billing questions, refunds, and payment issues. Use when customer has billing-related questions.",
882
+ invocation_mode=InvocationMode.DELEGATE,
883
+ context_mode=ContextMode.FULL,
884
+ )
885
+
886
+ tech_support_tool = AgentTool(
887
+ agent=TechSupportAgent(),
888
+ name="tech_support",
889
+ description="Handles technical issues and troubleshooting. Use for technical problems.",
890
+ invocation_mode=InvocationMode.HANDOFF, # Transfer control completely
891
+ )
892
+ ```
893
+
894
+ ### Router Agent Pattern
895
+
896
+ Create a router agent that delegates to specialists:
897
+
898
+ ```python
899
+ class RouterAgent(AgentRuntime):
900
+ """Routes customer requests to appropriate specialist agents."""
901
+
902
+ def __init__(self):
903
+ self.agent_tools = [billing_tool, tech_support_tool]
904
+
905
+ @property
906
+ def key(self) -> str:
907
+ return "customer-router"
908
+
909
+ async def run(self, ctx: RunContext) -> RunResult:
910
+ from agent_runtime_core.llm import get_llm_client
911
+ llm = get_llm_client()
912
+
913
+ # Create tool registry with agent-tools
914
+ tools = ToolRegistry()
915
+ messages = list(ctx.input_messages)
916
+
917
+ # Register agent-tools as callable tools
918
+ register_agent_tools(
919
+ registry=tools,
920
+ agent_tools=self.agent_tools,
921
+ get_conversation_history=lambda: messages,
922
+ parent_ctx=ctx,
923
+ )
924
+
925
+ # Add system prompt for routing
926
+ system_message = {
927
+ "role": "system",
928
+ "content": """You are a customer service router. Analyze the customer's
929
+ request and delegate to the appropriate specialist:
930
+ - billing_specialist: For billing, payments, refunds
931
+ - tech_support: For technical issues (this will transfer the customer)
932
+
933
+ If you can answer directly, do so. Otherwise, use the appropriate tool."""
934
+ }
935
+
936
+ while True:
937
+ response = await llm.generate(
938
+ [system_message] + messages,
939
+ tools=tools.to_openai_format(),
940
+ )
941
+
942
+ messages.append(response.message)
943
+
944
+ if not response.tool_calls:
945
+ # No tool call - respond directly
946
+ await ctx.emit(EventType.ASSISTANT_MESSAGE, {
947
+ "content": response.content,
948
+ })
949
+ break
950
+
951
+ # Execute tool calls (which may invoke sub-agents)
952
+ for tool_call in response.tool_calls:
953
+ result = await tools.execute_with_events(tool_call, ctx)
954
+
955
+ # Check for handoff
956
+ if isinstance(result, dict) and result.get("handoff"):
957
+ # Sub-agent took over - we're done
958
+ return RunResult(
959
+ final_output=result.get("final_output", {}),
960
+ final_messages=messages,
961
+ )
962
+
963
+ # Add result to conversation
964
+ messages.append({
965
+ "role": "tool",
966
+ "tool_call_id": tool_call.id,
967
+ "content": str(result.get("response", result)),
968
+ })
969
+
970
+ return RunResult(
971
+ final_output={"response": response.content},
972
+ final_messages=messages,
973
+ )
974
+ ```
975
+
976
+ ### Direct Invocation
977
+
978
+ You can also invoke agents directly without the tool pattern:
979
+
980
+ ```python
981
+ from agent_runtime_core.multi_agent import invoke_agent
982
+
983
+ # Invoke a sub-agent directly
984
+ result = await invoke_agent(
985
+ agent_tool=billing_tool,
986
+ message="Customer wants a refund for order #123",
987
+ parent_ctx=ctx,
988
+ conversation_history=messages,
989
+ additional_context="Customer has been waiting 2 weeks",
990
+ )
991
+
992
+ if result.handoff:
993
+ # Sub-agent took over
994
+ return RunResult(final_output=result.run_result.final_output)
995
+ else:
996
+ # Use the response
997
+ print(result.response)
998
+ ```
999
+
1000
+ ### Events
1001
+
1002
+ Multi-agent invocations emit events for observability:
1003
+
1004
+ - `sub_agent.start` - Sub-agent invocation started
1005
+ - `sub_agent.end` - Sub-agent invocation completed
1006
+ - `tool.call` with `is_agent_tool: true` - Agent-tool was called
1007
+ - `tool.result` with `is_agent_tool: true` - Agent-tool returned
1008
+
1009
+ ### AgentTool Options
1010
+
1011
+ ```python
1012
+ AgentTool(
1013
+ agent=my_agent, # Required: The agent to wrap
1014
+ name="specialist", # Required: Tool name
1015
+ description="When to use this agent", # Required: Shown to parent LLM
1016
+ invocation_mode=InvocationMode.DELEGATE, # DELEGATE or HANDOFF
1017
+ context_mode=ContextMode.FULL, # FULL, SUMMARY, or MESSAGE_ONLY
1018
+ max_turns=10, # Optional: Limit sub-agent turns
1019
+ input_schema={...}, # Optional: Custom input schema
1020
+ metadata={"category": "billing"}, # Optional: Additional metadata
1021
+ )
1022
+ ```
1023
+
823
1024
  ## API Reference
824
1025
 
825
1026
  ### Configuration
@@ -10,6 +10,7 @@ A lightweight, framework-agnostic Python library for building AI agent systems.
10
10
 
11
11
  | Version | Date | Changes |
12
12
  |---------|------|---------|
13
+ | **0.7.1** | 2026-01-24 | RAG module, vector stores (sqlite-vec, Vertex AI), memory system, multi-agent support, agentic loop, JSON runtime |
13
14
  | **0.6.0** | 2025-01-23 | Enhanced registry with factory functions and class registration |
14
15
  | **0.5.2** | 2025-01-14 | Add ToolCallingAgent base class, execute_with_events helper |
15
16
  | **0.5.1** | 2025-01-13 | Bug fixes and improvements |
@@ -777,6 +778,200 @@ The executor emits events for observability:
777
778
  - `EventType.STEP_SKIPPED` - Step skipped (already completed)
778
779
  - `EventType.PROGRESS_UPDATE` - Progress percentage update
779
780
 
781
+ ## Multi-Agent Systems
782
+
783
+ The `multi_agent` module provides the "agent-as-tool" pattern, allowing agents to invoke other agents as tools. This enables router/dispatcher patterns, hierarchical agent systems, and specialist delegation.
784
+
785
+ ### Core Concepts
786
+
787
+ **Invocation Modes:**
788
+ - `DELEGATE`: Sub-agent runs and returns result to parent (parent continues). Good for "get me an answer".
789
+ - `HANDOFF`: Control transfers completely to sub-agent (parent exits). Good for "transfer this customer to billing".
790
+
791
+ **Context Modes:**
792
+ - `FULL`: Complete conversation history passed to sub-agent (default)
793
+ - `SUMMARY`: Summarized context + current message (more efficient)
794
+ - `MESSAGE_ONLY`: Only the invocation message (clean isolation)
795
+
796
+ ### Creating Agent Tools
797
+
798
+ Wrap any agent as a tool that can be called by other agents:
799
+
800
+ ```python
801
+ from agent_runtime_core.multi_agent import (
802
+ AgentTool,
803
+ InvocationMode,
804
+ ContextMode,
805
+ invoke_agent,
806
+ register_agent_tools,
807
+ )
808
+
809
+ # Define specialist agents
810
+ class BillingAgent(AgentRuntime):
811
+ @property
812
+ def key(self) -> str:
813
+ return "billing-specialist"
814
+
815
+ async def run(self, ctx: RunContext) -> RunResult:
816
+ # Handle billing questions, refunds, payments
817
+ ...
818
+
819
+ class TechSupportAgent(AgentRuntime):
820
+ @property
821
+ def key(self) -> str:
822
+ return "tech-support"
823
+
824
+ async def run(self, ctx: RunContext) -> RunResult:
825
+ # Handle technical issues
826
+ ...
827
+
828
+ # Wrap agents as tools
829
+ billing_tool = AgentTool(
830
+ agent=BillingAgent(),
831
+ name="billing_specialist",
832
+ description="Handles billing questions, refunds, and payment issues. Use when customer has billing-related questions.",
833
+ invocation_mode=InvocationMode.DELEGATE,
834
+ context_mode=ContextMode.FULL,
835
+ )
836
+
837
+ tech_support_tool = AgentTool(
838
+ agent=TechSupportAgent(),
839
+ name="tech_support",
840
+ description="Handles technical issues and troubleshooting. Use for technical problems.",
841
+ invocation_mode=InvocationMode.HANDOFF, # Transfer control completely
842
+ )
843
+ ```
844
+
845
+ ### Router Agent Pattern
846
+
847
+ Create a router agent that delegates to specialists:
848
+
849
+ ```python
850
+ class RouterAgent(AgentRuntime):
851
+ """Routes customer requests to appropriate specialist agents."""
852
+
853
+ def __init__(self):
854
+ self.agent_tools = [billing_tool, tech_support_tool]
855
+
856
+ @property
857
+ def key(self) -> str:
858
+ return "customer-router"
859
+
860
+ async def run(self, ctx: RunContext) -> RunResult:
861
+ from agent_runtime_core.llm import get_llm_client
862
+ llm = get_llm_client()
863
+
864
+ # Create tool registry with agent-tools
865
+ tools = ToolRegistry()
866
+ messages = list(ctx.input_messages)
867
+
868
+ # Register agent-tools as callable tools
869
+ register_agent_tools(
870
+ registry=tools,
871
+ agent_tools=self.agent_tools,
872
+ get_conversation_history=lambda: messages,
873
+ parent_ctx=ctx,
874
+ )
875
+
876
+ # Add system prompt for routing
877
+ system_message = {
878
+ "role": "system",
879
+ "content": """You are a customer service router. Analyze the customer's
880
+ request and delegate to the appropriate specialist:
881
+ - billing_specialist: For billing, payments, refunds
882
+ - tech_support: For technical issues (this will transfer the customer)
883
+
884
+ If you can answer directly, do so. Otherwise, use the appropriate tool."""
885
+ }
886
+
887
+ while True:
888
+ response = await llm.generate(
889
+ [system_message] + messages,
890
+ tools=tools.to_openai_format(),
891
+ )
892
+
893
+ messages.append(response.message)
894
+
895
+ if not response.tool_calls:
896
+ # No tool call - respond directly
897
+ await ctx.emit(EventType.ASSISTANT_MESSAGE, {
898
+ "content": response.content,
899
+ })
900
+ break
901
+
902
+ # Execute tool calls (which may invoke sub-agents)
903
+ for tool_call in response.tool_calls:
904
+ result = await tools.execute_with_events(tool_call, ctx)
905
+
906
+ # Check for handoff
907
+ if isinstance(result, dict) and result.get("handoff"):
908
+ # Sub-agent took over - we're done
909
+ return RunResult(
910
+ final_output=result.get("final_output", {}),
911
+ final_messages=messages,
912
+ )
913
+
914
+ # Add result to conversation
915
+ messages.append({
916
+ "role": "tool",
917
+ "tool_call_id": tool_call.id,
918
+ "content": str(result.get("response", result)),
919
+ })
920
+
921
+ return RunResult(
922
+ final_output={"response": response.content},
923
+ final_messages=messages,
924
+ )
925
+ ```
926
+
927
+ ### Direct Invocation
928
+
929
+ You can also invoke agents directly without the tool pattern:
930
+
931
+ ```python
932
+ from agent_runtime_core.multi_agent import invoke_agent
933
+
934
+ # Invoke a sub-agent directly
935
+ result = await invoke_agent(
936
+ agent_tool=billing_tool,
937
+ message="Customer wants a refund for order #123",
938
+ parent_ctx=ctx,
939
+ conversation_history=messages,
940
+ additional_context="Customer has been waiting 2 weeks",
941
+ )
942
+
943
+ if result.handoff:
944
+ # Sub-agent took over
945
+ return RunResult(final_output=result.run_result.final_output)
946
+ else:
947
+ # Use the response
948
+ print(result.response)
949
+ ```
950
+
951
+ ### Events
952
+
953
+ Multi-agent invocations emit events for observability:
954
+
955
+ - `sub_agent.start` - Sub-agent invocation started
956
+ - `sub_agent.end` - Sub-agent invocation completed
957
+ - `tool.call` with `is_agent_tool: true` - Agent-tool was called
958
+ - `tool.result` with `is_agent_tool: true` - Agent-tool returned
959
+
960
+ ### AgentTool Options
961
+
962
+ ```python
963
+ AgentTool(
964
+ agent=my_agent, # Required: The agent to wrap
965
+ name="specialist", # Required: Tool name
966
+ description="When to use this agent", # Required: Shown to parent LLM
967
+ invocation_mode=InvocationMode.DELEGATE, # DELEGATE or HANDOFF
968
+ context_mode=ContextMode.FULL, # FULL, SUMMARY, or MESSAGE_ONLY
969
+ max_turns=10, # Optional: Limit sub-agent turns
970
+ input_schema={...}, # Optional: Custom input schema
971
+ metadata={"category": "billing"}, # Optional: Additional metadata
972
+ )
973
+ ```
974
+
780
975
  ## API Reference
781
976
 
782
977
  ### Configuration
@@ -40,10 +40,12 @@ __version__ = "0.7.0"
40
40
  from agent_runtime_core.interfaces import (
41
41
  AgentRuntime,
42
42
  EventType,
43
+ EventVisibility,
43
44
  ErrorInfo,
44
45
  LLMClient,
45
46
  LLMResponse,
46
47
  LLMStreamChunk,
48
+ LLMToolCall,
47
49
  Message,
48
50
  RunContext,
49
51
  RunResult,
@@ -57,6 +59,12 @@ from agent_runtime_core.interfaces import (
57
59
  # Tool Calling Agent base class
58
60
  from agent_runtime_core.tool_calling_agent import ToolCallingAgent
59
61
 
62
+ # Agentic loop helper
63
+ from agent_runtime_core.agentic_loop import (
64
+ run_agentic_loop,
65
+ AgenticLoopResult,
66
+ )
67
+
60
68
  # Configuration
61
69
  from agent_runtime_core.config import (
62
70
  RuntimeConfig,
@@ -128,6 +136,7 @@ from agent_runtime_core.persistence import (
128
136
  FileConversationStore,
129
137
  FileTaskStore,
130
138
  FilePreferencesStore,
139
+ FileKnowledgeStore,
131
140
  # Manager
132
141
  PersistenceManager,
133
142
  PersistenceConfig,
@@ -135,6 +144,69 @@ from agent_runtime_core.persistence import (
135
144
  configure_persistence,
136
145
  )
137
146
 
147
+ # Agent configuration schema (portable JSON format)
148
+ from agent_runtime_core.config_schema import (
149
+ AgentConfig,
150
+ ToolConfig,
151
+ KnowledgeConfig,
152
+ SubAgentToolConfig,
153
+ )
154
+
155
+ # JSON-based runtime (loads from AgentConfig)
156
+ from agent_runtime_core.json_runtime import (
157
+ JsonAgentRuntime,
158
+ ConfiguredTool,
159
+ SubAgentTool,
160
+ resolve_function,
161
+ )
162
+
163
+ # Vector store (optional - requires additional dependencies)
164
+ # Import these directly from agent_runtime_core.vectorstore when needed:
165
+ # from agent_runtime_core.vectorstore import (
166
+ # VectorStore, VectorRecord, VectorSearchResult,
167
+ # EmbeddingClient, OpenAIEmbeddings, VertexAIEmbeddings,
168
+ # get_vector_store, get_embedding_client,
169
+ # )
170
+
171
+ # RAG (Retrieval Augmented Generation)
172
+ from agent_runtime_core.rag import (
173
+ chunk_text,
174
+ ChunkingConfig,
175
+ TextChunk,
176
+ )
177
+
178
+ # RAG services are imported lazily to avoid circular dependencies
179
+ # Import directly when needed:
180
+ # from agent_runtime_core.rag import KnowledgeIndexer, KnowledgeRetriever
181
+
182
+ # Tool schema builder utilities
183
+ from agent_runtime_core.tools import (
184
+ ToolSchema,
185
+ ToolSchemaBuilder,
186
+ ToolParameter,
187
+ schemas_to_openai_format,
188
+ )
189
+
190
+ # Multi-agent support (agent-as-tool pattern)
191
+ from agent_runtime_core.multi_agent import (
192
+ AgentTool,
193
+ AgentInvocationResult,
194
+ InvocationMode,
195
+ ContextMode,
196
+ SubAgentContext,
197
+ invoke_agent,
198
+ create_agent_tool_handler,
199
+ register_agent_tools,
200
+ build_sub_agent_messages,
201
+ )
202
+
203
+ # Cross-conversation memory
204
+ # Import directly when needed for full functionality:
205
+ # from agent_runtime_core.memory import (
206
+ # MemoryManager, MemoryConfig, MemoryEnabledAgent,
207
+ # ExtractedMemory, RecalledMemory, with_memory,
208
+ # )
209
+
138
210
  __all__ = [
139
211
  # Version
140
212
  "__version__",
@@ -143,6 +215,7 @@ __all__ = [
143
215
  "LLMClient",
144
216
  "LLMResponse",
145
217
  "LLMStreamChunk",
218
+ "LLMToolCall",
146
219
  "Message",
147
220
  "RunContext",
148
221
  "RunResult",
@@ -151,8 +224,12 @@ __all__ = [
151
224
  "ToolDefinition",
152
225
  "TraceSink",
153
226
  "EventType",
227
+ "EventVisibility",
154
228
  "ErrorInfo",
155
- "ToolCallingAgent",
229
+ # Tool calling
230
+ "ToolCallingAgent",
231
+ "run_agentic_loop",
232
+ "AgenticLoopResult",
156
233
  # Configuration
157
234
  "RuntimeConfig",
158
235
  "configure",
@@ -204,9 +281,39 @@ __all__ = [
204
281
  "FileConversationStore",
205
282
  "FileTaskStore",
206
283
  "FilePreferencesStore",
284
+ "FileKnowledgeStore",
207
285
  # Persistence - Manager
208
286
  "PersistenceManager",
209
287
  "PersistenceConfig",
210
288
  "get_persistence_manager",
211
289
  "configure_persistence",
290
+ # Agent configuration schema
291
+ "AgentConfig",
292
+ "ToolConfig",
293
+ "KnowledgeConfig",
294
+ "SubAgentToolConfig",
295
+ # JSON-based runtime
296
+ "JsonAgentRuntime",
297
+ "ConfiguredTool",
298
+ "SubAgentTool",
299
+ "resolve_function",
300
+ # RAG (Retrieval Augmented Generation)
301
+ "chunk_text",
302
+ "ChunkingConfig",
303
+ "TextChunk",
304
+ # Tool schema builder
305
+ "ToolSchema",
306
+ "ToolSchemaBuilder",
307
+ "ToolParameter",
308
+ "schemas_to_openai_format",
309
+ # Multi-agent support
310
+ "AgentTool",
311
+ "AgentInvocationResult",
312
+ "InvocationMode",
313
+ "ContextMode",
314
+ "SubAgentContext",
315
+ "invoke_agent",
316
+ "create_agent_tool_handler",
317
+ "register_agent_tools",
318
+ "build_sub_agent_messages",
212
319
  ]