1
- from google .adk .agents .invocation_context import InvocationContext
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
2
15
from google .adk .agents .llm_agent import Agent
3
16
from google .adk .agents .readonly_context import ReadonlyContext
4
17
from google .adk .sessions .session import Session
@@ -17,7 +30,7 @@ async def load_artifact(self, app_name, user_id, session_id, filename):
17
30
if filename in self .artifacts :
18
31
return self .artifacts [filename ]
19
32
else :
20
- raise KeyError ( f"Artifact ' { filename } ' not found." )
33
+ return None
21
34
22
35
23
36
async def _create_test_readonly_context (
@@ -114,7 +127,7 @@ async def test_inject_session_state_with_missing_artifact_raises_key_error():
114
127
artifact_service = mock_artifact_service
115
128
)
116
129
117
- with pytest .raises (KeyError , match = "Artifact ' missing_file' not found." ):
130
+ with pytest .raises (KeyError , match = "Artifact missing_file not found." ):
118
131
await instructions_utils .inject_session_state (
119
132
instruction_template , invocation_context
120
133
)
@@ -200,7 +213,7 @@ async def test_inject_session_state_with_empty_artifact_name_raises_key_error():
200
213
artifact_service = mock_artifact_service
201
214
)
202
215
203
- with pytest .raises (KeyError , match = "Artifact '' not found." ):
216
+ with pytest .raises (KeyError , match = "Artifact not found." ):
204
217
await instructions_utils .inject_session_state (
205
218
instruction_template , invocation_context
206
219
)
@@ -214,3 +227,43 @@ async def test_inject_session_state_artifact_service_not_initialized_raises_valu
214
227
await instructions_utils .inject_session_state (
215
228
instruction_template , invocation_context
216
229
)
230
+
231
+
232
+ @pytest .mark .asyncio
233
+ async def test_inject_session_state_with_optional_missing_artifact_returns_empty ():
234
+ instruction_template = "Optional artifact: {artifact.missing_file?}"
235
+ mock_artifact_service = MockArtifactService (
236
+ {"my_file" : "This is my artifact content." }
237
+ )
238
+ invocation_context = await _create_test_readonly_context (
239
+ artifact_service = mock_artifact_service
240
+ )
241
+
242
+ populated_instruction = await instructions_utils .inject_session_state (
243
+ instruction_template , invocation_context
244
+ )
245
+ assert populated_instruction == "Optional artifact: "
246
+
247
+
248
+ @pytest .mark .asyncio
249
+ async def test_inject_session_state_with_none_state_value_returns_empty ():
250
+ instruction_template = "Value: {test_key}"
251
+ invocation_context = await _create_test_readonly_context (
252
+ state = {"test_key" : None }
253
+ )
254
+
255
+ populated_instruction = await instructions_utils .inject_session_state (
256
+ instruction_template , invocation_context
257
+ )
258
+ assert populated_instruction == "Value: "
259
+
260
+
261
+ @pytest .mark .asyncio
262
+ async def test_inject_session_state_with_optional_missing_state_returns_empty ():
263
+ instruction_template = "Optional value: {missing_key?}"
264
+ invocation_context = await _create_test_readonly_context ()
265
+
266
+ populated_instruction = await instructions_utils .inject_session_state (
267
+ instruction_template , invocation_context
268
+ )
269
+ assert populated_instruction == "Optional value: "
0 commit comments