@aws/agentcore 0.12.2 → 0.13.1

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 (61) hide show
  1. package/README.md +26 -10
  2. package/dist/agent-inspector/index.css +1 -1
  3. package/dist/agent-inspector/index.js +86 -81
  4. package/dist/assets/__tests__/__snapshots__/assets.snapshot.test.ts.snap +125 -17
  5. package/dist/assets/cdk/test/cdk.test.ts +1 -0
  6. package/dist/assets/python/http/langchain_langgraph/base/main.py +52 -8
  7. package/dist/assets/python/http/strands/base/main.py +71 -8
  8. package/dist/cli/index.mjs +972 -610
  9. package/dist/lib/packaging/build-args.js +2 -2
  10. package/dist/lib/packaging/build-args.js.map +1 -1
  11. package/dist/lib/packaging/helpers.d.ts.map +1 -1
  12. package/dist/lib/packaging/helpers.js +10 -6
  13. package/dist/lib/packaging/helpers.js.map +1 -1
  14. package/dist/lib/schemas/io/config-io.d.ts.map +1 -1
  15. package/dist/lib/schemas/io/config-io.js +9 -1
  16. package/dist/lib/schemas/io/config-io.js.map +1 -1
  17. package/dist/lib/schemas/io/global-config.d.ts +33 -0
  18. package/dist/lib/schemas/io/global-config.d.ts.map +1 -0
  19. package/dist/lib/schemas/io/global-config.js +89 -0
  20. package/dist/lib/schemas/io/global-config.js.map +1 -0
  21. package/dist/lib/schemas/io/index.d.ts +0 -1
  22. package/dist/lib/schemas/io/index.d.ts.map +1 -1
  23. package/dist/lib/schemas/io/index.js +1 -3
  24. package/dist/lib/schemas/io/index.js.map +1 -1
  25. package/dist/schema/schemas/agentcore-project.d.ts +81 -0
  26. package/dist/schema/schemas/agentcore-project.d.ts.map +1 -1
  27. package/dist/schema/schemas/agentcore-project.js +87 -1
  28. package/dist/schema/schemas/agentcore-project.js.map +1 -1
  29. package/dist/schema/schemas/deployed-state.d.ts +113 -0
  30. package/dist/schema/schemas/deployed-state.d.ts.map +1 -1
  31. package/dist/schema/schemas/deployed-state.js +40 -1
  32. package/dist/schema/schemas/deployed-state.js.map +1 -1
  33. package/dist/schema/schemas/mcp.js +1 -1
  34. package/dist/schema/schemas/mcp.js.map +1 -1
  35. package/dist/schema/schemas/primitives/ab-test.d.ts +141 -0
  36. package/dist/schema/schemas/primitives/ab-test.d.ts.map +1 -0
  37. package/dist/schema/schemas/primitives/ab-test.js +97 -0
  38. package/dist/schema/schemas/primitives/ab-test.js.map +1 -0
  39. package/dist/schema/schemas/primitives/config-bundle.d.ts +31 -0
  40. package/dist/schema/schemas/primitives/config-bundle.d.ts.map +1 -0
  41. package/dist/schema/schemas/primitives/config-bundle.js +38 -0
  42. package/dist/schema/schemas/primitives/config-bundle.js.map +1 -0
  43. package/dist/schema/schemas/primitives/http-gateway.d.ts +21 -0
  44. package/dist/schema/schemas/primitives/http-gateway.d.ts.map +1 -0
  45. package/dist/schema/schemas/primitives/http-gateway.js +34 -0
  46. package/dist/schema/schemas/primitives/http-gateway.js.map +1 -0
  47. package/dist/schema/schemas/primitives/index.d.ts +4 -0
  48. package/dist/schema/schemas/primitives/index.d.ts.map +1 -1
  49. package/dist/schema/schemas/primitives/index.js +15 -1
  50. package/dist/schema/schemas/primitives/index.js.map +1 -1
  51. package/dist/schema/schemas/primitives/online-eval-config.d.ts +1 -0
  52. package/dist/schema/schemas/primitives/online-eval-config.d.ts.map +1 -1
  53. package/dist/schema/schemas/primitives/online-eval-config.js +2 -0
  54. package/dist/schema/schemas/primitives/online-eval-config.js.map +1 -1
  55. package/package.json +6 -4
  56. package/scripts/bundle.mjs +5 -2
  57. package/scripts/run-e2e-local.sh +112 -0
  58. package/dist/lib/schemas/io/cli-config.d.ts +0 -12
  59. package/dist/lib/schemas/io/cli-config.d.ts.map +0 -1
  60. package/dist/lib/schemas/io/cli-config.js +0 -35
  61. package/dist/lib/schemas/io/cli-config.js.map +0 -1
@@ -382,6 +382,7 @@ test('AgentCoreStack synthesizes with empty spec', () => {
382
382
  credentials: [],
383
383
  evaluators: [],
384
384
  onlineEvalConfigs: [],
385
+ configBundles: [],
385
386
  policyEngines: [],
386
387
  agentCoreGateways: [],
387
388
  mcpRuntimeTools: [],
@@ -3700,9 +3701,15 @@ Thumbs.db
3700
3701
 
3701
3702
  exports[`Assets Directory Snapshots > Python framework assets > python/python/http/langchain_langgraph/base/main.py should match snapshot 1`] = `
3702
3703
  "import os
3703
- from langchain_core.messages import HumanMessage
3704
+ from typing import Any
3705
+
3706
+ from langchain_core.messages import HumanMessage{{#if hasConfigBundle}}, SystemMessage{{/if}}
3704
3707
  from langgraph.prebuilt import create_react_agent
3705
3708
  from langchain.tools import tool
3709
+ {{#if hasConfigBundle}}
3710
+ from langchain_core.callbacks import BaseCallbackHandler
3711
+ from bedrock_agentcore.runtime.context import BedrockAgentCoreContext
3712
+ {{/if}}
3706
3713
  from opentelemetry.instrumentation.langchain import LangchainInstrumentor
3707
3714
  from bedrock_agentcore.runtime import BedrockAgentCoreApp
3708
3715
  from model.load import load_model
@@ -3726,6 +3733,14 @@ def get_or_create_model():
3726
3733
  return _llm
3727
3734
 
3728
3735
 
3736
+ DEFAULT_SYSTEM_PROMPT = """
3737
+ You are a helpful assistant. Use tools when appropriate.
3738
+ {{#if sessionStorageMountPath}}
3739
+ You have persistent storage at {{sessionStorageMountPath}}. Use file tools to read and write files. Data persists across sessions.
3740
+ {{/if}}
3741
+ """
3742
+
3743
+
3729
3744
  # Define a simple function tool
3730
3745
  @tool
3731
3746
  def add_numbers(a: int, b: int) -> int:
@@ -3789,13 +3804,28 @@ def list_files(directory: str = "") -> str:
3789
3804
  tools.extend([file_read, file_write, list_files])
3790
3805
  {{/if}}
3791
3806
 
3792
- SYSTEM_PROMPT = """
3793
- You are a helpful assistant. Use tools when appropriate.
3794
- {{#if sessionStorageMountPath}}
3795
- You have persistent storage at {{sessionStorageMountPath}}. Use file tools to read and write files. Data persists across sessions.
3796
- {{/if}}
3797
- """
3807
+ {{#if hasConfigBundle}}
3798
3808
 
3809
+ class ConfigBundleCallback(BaseCallbackHandler):
3810
+ """Injects config bundle values into LangGraph agent at runtime.
3811
+
3812
+ BedrockAgentCoreContext.get_config_bundle() fetches the component configuration
3813
+ for the current runtime ARN from the config bundle service. The SDK caches the
3814
+ result and refreshes on bundle version changes.
3815
+ """
3816
+
3817
+ def on_chain_start(self, serialized: dict, inputs: dict, **kwargs: Any) -> None:
3818
+ config = BedrockAgentCoreContext.get_config_bundle()
3819
+ prompt = config.get("systemPrompt", DEFAULT_SYSTEM_PROMPT)
3820
+
3821
+ messages = inputs.get("messages", [])
3822
+ if messages and isinstance(messages[0], SystemMessage):
3823
+ messages[0] = SystemMessage(content=prompt)
3824
+ else:
3825
+ messages.insert(0, SystemMessage(content=prompt))
3826
+ inputs["messages"] = messages
3827
+
3828
+ {{/if}}
3799
3829
 
3800
3830
  @app.entrypoint
3801
3831
  async def invoke(payload, context):
@@ -3814,7 +3844,21 @@ async def invoke(payload, context):
3814
3844
  mcp_tools = await mcp_client.get_tools()
3815
3845
 
3816
3846
  # Define the agent using create_react_agent
3817
- graph = create_react_agent(get_or_create_model(), tools=mcp_tools + tools, prompt=SYSTEM_PROMPT)
3847
+ {{#if hasConfigBundle}}
3848
+ graph = create_react_agent(get_or_create_model(), tools=mcp_tools + tools, prompt=DEFAULT_SYSTEM_PROMPT)
3849
+ callback = ConfigBundleCallback()
3850
+
3851
+ # Process the user prompt
3852
+ prompt = payload.get("prompt", "What can you help me with?")
3853
+ log.info(f"Agent input: {prompt}")
3854
+
3855
+ # Run the agent with config bundle callback
3856
+ result = await graph.ainvoke(
3857
+ {"messages": [HumanMessage(content=prompt)]},
3858
+ config={"callbacks": [callback]},
3859
+ )
3860
+ {{else}}
3861
+ graph = create_react_agent(get_or_create_model(), tools=mcp_tools + tools, prompt=DEFAULT_SYSTEM_PROMPT)
3818
3862
 
3819
3863
  # Process the user prompt
3820
3864
  prompt = payload.get("prompt", "What can you help me with?")
@@ -3822,6 +3866,7 @@ async def invoke(payload, context):
3822
3866
 
3823
3867
  # Run the agent
3824
3868
  result = await graph.ainvoke({"messages": [HumanMessage(content=prompt)]})
3869
+ {{/if}}
3825
3870
 
3826
3871
  # Return result
3827
3872
  output = result["messages"][-1].content
@@ -4596,7 +4641,13 @@ Thumbs.db"
4596
4641
  `;
4597
4642
 
4598
4643
  exports[`Assets Directory Snapshots > Python framework assets > python/python/http/strands/base/main.py should match snapshot 1`] = `
4599
- "from strands import Agent, tool
4644
+ "from typing import Any
4645
+
4646
+ from strands import Agent, tool
4647
+ {{#if hasConfigBundle}}
4648
+ from strands.hooks import HookProvider, HookRegistry, BeforeInvocationEvent, BeforeToolCallEvent
4649
+ from bedrock_agentcore.runtime.context import BedrockAgentCoreContext
4650
+ {{/if}}
4600
4651
  from bedrock_agentcore.runtime import BedrockAgentCoreApp
4601
4652
  from model.load import load_model
4602
4653
  {{#if hasGateway}}
@@ -4621,11 +4672,26 @@ mcp_clients = get_all_gateway_mcp_clients()
4621
4672
  mcp_clients = [get_streamable_http_mcp_client()]
4622
4673
  {{/if}}
4623
4674
 
4675
+ DEFAULT_SYSTEM_PROMPT = """
4676
+ You are a helpful assistant. Use tools when appropriate.
4677
+ {{#if sessionStorageMountPath}}
4678
+ You have persistent storage at {{sessionStorageMountPath}}. Use file tools to read and write files. Data persists across sessions.
4679
+ {{/if}}
4680
+ """
4681
+
4682
+ {{#if hasConfigBundle}}
4683
+ DEFAULT_TOOL_DESC = "Return the sum of two numbers"
4684
+ {{/if}}
4685
+
4624
4686
  # Define a collection of tools used by the model
4625
4687
  tools = []
4626
4688
 
4627
4689
  # Define a simple function tool
4690
+ {{#if hasConfigBundle}}
4691
+ @tool(description=DEFAULT_TOOL_DESC)
4692
+ {{else}}
4628
4693
  @tool
4694
+ {{/if}}
4629
4695
  def add_numbers(a: int, b: int) -> int:
4630
4696
  """Return the sum of two numbers"""
4631
4697
  return a+b
@@ -4689,12 +4755,39 @@ for mcp_client in mcp_clients:
4689
4755
  if mcp_client:
4690
4756
  tools.append(mcp_client)
4691
4757
 
4692
- SYSTEM_PROMPT = """
4693
- You are a helpful assistant. Use tools when appropriate.
4694
- {{#if sessionStorageMountPath}}
4695
- You have persistent storage at {{sessionStorageMountPath}}. Use file tools to read and write files. Data persists across sessions.
4758
+ {{#if hasConfigBundle}}
4759
+
4760
+ class ConfigBundleHook(HookProvider):
4761
+ """Injects config bundle values (system prompt, tool descriptions) before each invocation.
4762
+
4763
+ BedrockAgentCoreContext.get_config_bundle() fetches the component configuration
4764
+ for the current runtime ARN from the config bundle service. The SDK caches the
4765
+ result and refreshes on bundle version changes.
4766
+ """
4767
+
4768
+ def register_hooks(self, registry: HookRegistry, **kwargs: Any) -> None:
4769
+ registry.add_callback(BeforeInvocationEvent, self._inject_system_prompt)
4770
+ registry.add_callback(BeforeToolCallEvent, self._override_tool_desc)
4771
+
4772
+ def _inject_system_prompt(self, event: BeforeInvocationEvent) -> None:
4773
+ config = BedrockAgentCoreContext.get_config_bundle()
4774
+ prompt = config.get("systemPrompt", DEFAULT_SYSTEM_PROMPT)
4775
+
4776
+ if prompt != event.agent.system_prompt:
4777
+ event.agent.system_prompt = prompt
4778
+
4779
+ def _override_tool_desc(self, event: BeforeToolCallEvent) -> None:
4780
+ config = BedrockAgentCoreContext.get_config_bundle()
4781
+ tool_descs = config.get("toolDescriptions", {})
4782
+
4783
+ tool_name = event.tool_use["name"]
4784
+ override = tool_descs.get(tool_name)
4785
+ if override and event.selected_tool:
4786
+ spec = event.selected_tool.tool_spec
4787
+ if spec and "description" in spec:
4788
+ spec["description"] = override
4789
+
4696
4790
  {{/if}}
4697
- """
4698
4791
 
4699
4792
  {{#if hasMemory}}
4700
4793
  def agent_factory():
@@ -4706,13 +4799,23 @@ def agent_factory():
4706
4799
  cache[key] = Agent(
4707
4800
  model=load_model(),
4708
4801
  session_manager=get_memory_session_manager(session_id, user_id),
4709
- system_prompt=SYSTEM_PROMPT,
4710
- tools=tools
4802
+ system_prompt=DEFAULT_SYSTEM_PROMPT,
4803
+ tools=tools{{#if hasConfigBundle}},
4804
+ hooks=[ConfigBundleHook()]{{/if}}
4711
4805
  )
4712
4806
  return cache[key]
4713
4807
  return get_or_create_agent
4714
4808
  get_or_create_agent = agent_factory()
4715
4809
  {{else}}
4810
+ {{#if hasConfigBundle}}
4811
+ def create_agent():
4812
+ return Agent(
4813
+ model=load_model(),
4814
+ system_prompt=DEFAULT_SYSTEM_PROMPT,
4815
+ tools=tools,
4816
+ hooks=[ConfigBundleHook()],
4817
+ )
4818
+ {{else}}
4716
4819
  _agent = None
4717
4820
 
4718
4821
  def get_or_create_agent():
@@ -4720,11 +4823,12 @@ def get_or_create_agent():
4720
4823
  if _agent is None:
4721
4824
  _agent = Agent(
4722
4825
  model=load_model(),
4723
- system_prompt=SYSTEM_PROMPT,
4826
+ system_prompt=DEFAULT_SYSTEM_PROMPT,
4724
4827
  tools=tools
4725
4828
  )
4726
4829
  return _agent
4727
4830
  {{/if}}
4831
+ {{/if}}
4728
4832
 
4729
4833
 
4730
4834
  @app.entrypoint
@@ -4735,8 +4839,12 @@ async def invoke(payload, context):
4735
4839
  session_id = getattr(context, 'session_id', 'default-session')
4736
4840
  user_id = getattr(context, 'user_id', 'default-user')
4737
4841
  agent = get_or_create_agent(session_id, user_id)
4842
+ {{else}}
4843
+ {{#if hasConfigBundle}}
4844
+ agent = create_agent()
4738
4845
  {{else}}
4739
4846
  agent = get_or_create_agent()
4847
+ {{/if}}
4740
4848
  {{/if}}
4741
4849
 
4742
4850
  # Execute and format response
@@ -14,6 +14,7 @@ test('AgentCoreStack synthesizes with empty spec', () => {
14
14
  credentials: [],
15
15
  evaluators: [],
16
16
  onlineEvalConfigs: [],
17
+ configBundles: [],
17
18
  policyEngines: [],
18
19
  agentCoreGateways: [],
19
20
  mcpRuntimeTools: [],
@@ -1,7 +1,13 @@
1
1
  import os
2
- from langchain_core.messages import HumanMessage
2
+ from typing import Any
3
+
4
+ from langchain_core.messages import HumanMessage{{#if hasConfigBundle}}, SystemMessage{{/if}}
3
5
  from langgraph.prebuilt import create_react_agent
4
6
  from langchain.tools import tool
7
+ {{#if hasConfigBundle}}
8
+ from langchain_core.callbacks import BaseCallbackHandler
9
+ from bedrock_agentcore.runtime.context import BedrockAgentCoreContext
10
+ {{/if}}
5
11
  from opentelemetry.instrumentation.langchain import LangchainInstrumentor
6
12
  from bedrock_agentcore.runtime import BedrockAgentCoreApp
7
13
  from model.load import load_model
@@ -25,6 +31,14 @@ def get_or_create_model():
25
31
  return _llm
26
32
 
27
33
 
34
+ DEFAULT_SYSTEM_PROMPT = """
35
+ You are a helpful assistant. Use tools when appropriate.
36
+ {{#if sessionStorageMountPath}}
37
+ You have persistent storage at {{sessionStorageMountPath}}. Use file tools to read and write files. Data persists across sessions.
38
+ {{/if}}
39
+ """
40
+
41
+
28
42
  # Define a simple function tool
29
43
  @tool
30
44
  def add_numbers(a: int, b: int) -> int:
@@ -88,13 +102,28 @@ def list_files(directory: str = "") -> str:
88
102
  tools.extend([file_read, file_write, list_files])
89
103
  {{/if}}
90
104
 
91
- SYSTEM_PROMPT = """
92
- You are a helpful assistant. Use tools when appropriate.
93
- {{#if sessionStorageMountPath}}
94
- You have persistent storage at {{sessionStorageMountPath}}. Use file tools to read and write files. Data persists across sessions.
95
- {{/if}}
96
- """
105
+ {{#if hasConfigBundle}}
106
+
107
+ class ConfigBundleCallback(BaseCallbackHandler):
108
+ """Injects config bundle values into LangGraph agent at runtime.
109
+
110
+ BedrockAgentCoreContext.get_config_bundle() fetches the component configuration
111
+ for the current runtime ARN from the config bundle service. The SDK caches the
112
+ result and refreshes on bundle version changes.
113
+ """
114
+
115
+ def on_chain_start(self, serialized: dict, inputs: dict, **kwargs: Any) -> None:
116
+ config = BedrockAgentCoreContext.get_config_bundle()
117
+ prompt = config.get("systemPrompt", DEFAULT_SYSTEM_PROMPT)
97
118
 
119
+ messages = inputs.get("messages", [])
120
+ if messages and isinstance(messages[0], SystemMessage):
121
+ messages[0] = SystemMessage(content=prompt)
122
+ else:
123
+ messages.insert(0, SystemMessage(content=prompt))
124
+ inputs["messages"] = messages
125
+
126
+ {{/if}}
98
127
 
99
128
  @app.entrypoint
100
129
  async def invoke(payload, context):
@@ -113,7 +142,21 @@ async def invoke(payload, context):
113
142
  mcp_tools = await mcp_client.get_tools()
114
143
 
115
144
  # Define the agent using create_react_agent
116
- graph = create_react_agent(get_or_create_model(), tools=mcp_tools + tools, prompt=SYSTEM_PROMPT)
145
+ {{#if hasConfigBundle}}
146
+ graph = create_react_agent(get_or_create_model(), tools=mcp_tools + tools, prompt=DEFAULT_SYSTEM_PROMPT)
147
+ callback = ConfigBundleCallback()
148
+
149
+ # Process the user prompt
150
+ prompt = payload.get("prompt", "What can you help me with?")
151
+ log.info(f"Agent input: {prompt}")
152
+
153
+ # Run the agent with config bundle callback
154
+ result = await graph.ainvoke(
155
+ {"messages": [HumanMessage(content=prompt)]},
156
+ config={"callbacks": [callback]},
157
+ )
158
+ {{else}}
159
+ graph = create_react_agent(get_or_create_model(), tools=mcp_tools + tools, prompt=DEFAULT_SYSTEM_PROMPT)
117
160
 
118
161
  # Process the user prompt
119
162
  prompt = payload.get("prompt", "What can you help me with?")
@@ -121,6 +164,7 @@ async def invoke(payload, context):
121
164
 
122
165
  # Run the agent
123
166
  result = await graph.ainvoke({"messages": [HumanMessage(content=prompt)]})
167
+ {{/if}}
124
168
 
125
169
  # Return result
126
170
  output = result["messages"][-1].content
@@ -1,4 +1,10 @@
1
+ from typing import Any
2
+
1
3
  from strands import Agent, tool
4
+ {{#if hasConfigBundle}}
5
+ from strands.hooks import HookProvider, HookRegistry, BeforeInvocationEvent, BeforeToolCallEvent
6
+ from bedrock_agentcore.runtime.context import BedrockAgentCoreContext
7
+ {{/if}}
2
8
  from bedrock_agentcore.runtime import BedrockAgentCoreApp
3
9
  from model.load import load_model
4
10
  {{#if hasGateway}}
@@ -23,11 +29,26 @@ mcp_clients = get_all_gateway_mcp_clients()
23
29
  mcp_clients = [get_streamable_http_mcp_client()]
24
30
  {{/if}}
25
31
 
32
+ DEFAULT_SYSTEM_PROMPT = """
33
+ You are a helpful assistant. Use tools when appropriate.
34
+ {{#if sessionStorageMountPath}}
35
+ You have persistent storage at {{sessionStorageMountPath}}. Use file tools to read and write files. Data persists across sessions.
36
+ {{/if}}
37
+ """
38
+
39
+ {{#if hasConfigBundle}}
40
+ DEFAULT_TOOL_DESC = "Return the sum of two numbers"
41
+ {{/if}}
42
+
26
43
  # Define a collection of tools used by the model
27
44
  tools = []
28
45
 
29
46
  # Define a simple function tool
47
+ {{#if hasConfigBundle}}
48
+ @tool(description=DEFAULT_TOOL_DESC)
49
+ {{else}}
30
50
  @tool
51
+ {{/if}}
31
52
  def add_numbers(a: int, b: int) -> int:
32
53
  """Return the sum of two numbers"""
33
54
  return a+b
@@ -91,12 +112,39 @@ for mcp_client in mcp_clients:
91
112
  if mcp_client:
92
113
  tools.append(mcp_client)
93
114
 
94
- SYSTEM_PROMPT = """
95
- You are a helpful assistant. Use tools when appropriate.
96
- {{#if sessionStorageMountPath}}
97
- You have persistent storage at {{sessionStorageMountPath}}. Use file tools to read and write files. Data persists across sessions.
115
+ {{#if hasConfigBundle}}
116
+
117
+ class ConfigBundleHook(HookProvider):
118
+ """Injects config bundle values (system prompt, tool descriptions) before each invocation.
119
+
120
+ BedrockAgentCoreContext.get_config_bundle() fetches the component configuration
121
+ for the current runtime ARN from the config bundle service. The SDK caches the
122
+ result and refreshes on bundle version changes.
123
+ """
124
+
125
+ def register_hooks(self, registry: HookRegistry, **kwargs: Any) -> None:
126
+ registry.add_callback(BeforeInvocationEvent, self._inject_system_prompt)
127
+ registry.add_callback(BeforeToolCallEvent, self._override_tool_desc)
128
+
129
+ def _inject_system_prompt(self, event: BeforeInvocationEvent) -> None:
130
+ config = BedrockAgentCoreContext.get_config_bundle()
131
+ prompt = config.get("systemPrompt", DEFAULT_SYSTEM_PROMPT)
132
+
133
+ if prompt != event.agent.system_prompt:
134
+ event.agent.system_prompt = prompt
135
+
136
+ def _override_tool_desc(self, event: BeforeToolCallEvent) -> None:
137
+ config = BedrockAgentCoreContext.get_config_bundle()
138
+ tool_descs = config.get("toolDescriptions", {})
139
+
140
+ tool_name = event.tool_use["name"]
141
+ override = tool_descs.get(tool_name)
142
+ if override and event.selected_tool:
143
+ spec = event.selected_tool.tool_spec
144
+ if spec and "description" in spec:
145
+ spec["description"] = override
146
+
98
147
  {{/if}}
99
- """
100
148
 
101
149
  {{#if hasMemory}}
102
150
  def agent_factory():
@@ -108,13 +156,23 @@ def agent_factory():
108
156
  cache[key] = Agent(
109
157
  model=load_model(),
110
158
  session_manager=get_memory_session_manager(session_id, user_id),
111
- system_prompt=SYSTEM_PROMPT,
112
- tools=tools
159
+ system_prompt=DEFAULT_SYSTEM_PROMPT,
160
+ tools=tools{{#if hasConfigBundle}},
161
+ hooks=[ConfigBundleHook()]{{/if}}
113
162
  )
114
163
  return cache[key]
115
164
  return get_or_create_agent
116
165
  get_or_create_agent = agent_factory()
117
166
  {{else}}
167
+ {{#if hasConfigBundle}}
168
+ def create_agent():
169
+ return Agent(
170
+ model=load_model(),
171
+ system_prompt=DEFAULT_SYSTEM_PROMPT,
172
+ tools=tools,
173
+ hooks=[ConfigBundleHook()],
174
+ )
175
+ {{else}}
118
176
  _agent = None
119
177
 
120
178
  def get_or_create_agent():
@@ -122,11 +180,12 @@ def get_or_create_agent():
122
180
  if _agent is None:
123
181
  _agent = Agent(
124
182
  model=load_model(),
125
- system_prompt=SYSTEM_PROMPT,
183
+ system_prompt=DEFAULT_SYSTEM_PROMPT,
126
184
  tools=tools
127
185
  )
128
186
  return _agent
129
187
  {{/if}}
188
+ {{/if}}
130
189
 
131
190
 
132
191
  @app.entrypoint
@@ -137,8 +196,12 @@ async def invoke(payload, context):
137
196
  session_id = getattr(context, 'session_id', 'default-session')
138
197
  user_id = getattr(context, 'user_id', 'default-user')
139
198
  agent = get_or_create_agent(session_id, user_id)
199
+ {{else}}
200
+ {{#if hasConfigBundle}}
201
+ agent = create_agent()
140
202
  {{else}}
141
203
  agent = get_or_create_agent()
204
+ {{/if}}
142
205
  {{/if}}
143
206
 
144
207
  # Execute and format response