@@ -100,6 +100,136 @@ func TestWithInvocationRunOptions(t *testing.T) {
100100 assert .Equal (t , "value1" , inv .RunOptions .RuntimeState ["key1" ])
101101}
102102
103+ func TestGetRuntimeStateValue (t * testing.T ) {
104+ t .Run ("key not found" , func (t * testing.T ) {
105+ opts := & RunOptions {
106+ RuntimeState : map [string ]any {},
107+ }
108+ val , ok := GetRuntimeStateValue [string ](opts , "nonexistent" )
109+ assert .False (t , ok )
110+ assert .Equal (t , "" , val )
111+ })
112+
113+ t .Run ("nil RunOptions" , func (t * testing.T ) {
114+ var opts * RunOptions
115+ val , ok := GetRuntimeStateValue [string ](opts , "key" )
116+ assert .False (t , ok )
117+ assert .Equal (t , "" , val )
118+ })
119+
120+ t .Run ("nil RuntimeState" , func (t * testing.T ) {
121+ opts := & RunOptions {}
122+ val , ok := GetRuntimeStateValue [string ](opts , "key" )
123+ assert .False (t , ok )
124+ assert .Equal (t , "" , val )
125+ })
126+
127+ t .Run ("matching type" , func (t * testing.T ) {
128+ opts := & RunOptions {
129+ RuntimeState : map [string ]any {
130+ "user_id" : "12345" ,
131+ "room_id" : 678 ,
132+ "config" : true ,
133+ "score" : 3.14 ,
134+ },
135+ }
136+
137+ // Test string.
138+ userID , ok := GetRuntimeStateValue [string ](opts , "user_id" )
139+ assert .True (t , ok )
140+ assert .Equal (t , "12345" , userID )
141+
142+ // Test int.
143+ roomID , ok := GetRuntimeStateValue [int ](opts , "room_id" )
144+ assert .True (t , ok )
145+ assert .Equal (t , 678 , roomID )
146+
147+ // Test bool.
148+ config , ok := GetRuntimeStateValue [bool ](opts , "config" )
149+ assert .True (t , ok )
150+ assert .Equal (t , true , config )
151+
152+ // Test float64.
153+ score , ok := GetRuntimeStateValue [float64 ](opts , "score" )
154+ assert .True (t , ok )
155+ assert .Equal (t , 3.14 , score )
156+ })
157+
158+ t .Run ("type mismatch" , func (t * testing.T ) {
159+ opts := & RunOptions {
160+ RuntimeState : map [string ]any {
161+ "value" : "hello" ,
162+ },
163+ }
164+
165+ // Try to get as int when it's actually string.
166+ intVal , ok := GetRuntimeStateValue [int ](opts , "value" )
167+ assert .False (t , ok )
168+ assert .Equal (t , 0 , intVal )
169+
170+ // Try to get as string when it's actually int.
171+ opts .RuntimeState ["number" ] = 42
172+ strVal , ok := GetRuntimeStateValue [string ](opts , "number" )
173+ assert .False (t , ok )
174+ assert .Equal (t , "" , strVal )
175+ })
176+
177+ t .Run ("slice type" , func (t * testing.T ) {
178+ opts := & RunOptions {
179+ RuntimeState : map [string ]any {
180+ "tags" : []string {"tag1" , "tag2" , "tag3" },
181+ },
182+ }
183+
184+ tags , ok := GetRuntimeStateValue [[]string ](opts , "tags" )
185+ assert .True (t , ok )
186+ assert .Equal (t , []string {"tag1" , "tag2" , "tag3" }, tags )
187+ })
188+
189+ t .Run ("map type" , func (t * testing.T ) {
190+ opts := & RunOptions {
191+ RuntimeState : map [string ]any {
192+ "metadata" : map [string ]string {
193+ "key1" : "value1" ,
194+ "key2" : "value2" ,
195+ },
196+ },
197+ }
198+
199+ metadata , ok := GetRuntimeStateValue [map [string ]string ](opts , "metadata" )
200+ assert .True (t , ok )
201+ assert .Equal (t , "value1" , metadata ["key1" ])
202+ assert .Equal (t , "value2" , metadata ["key2" ])
203+ })
204+
205+ t .Run ("complex struct type" , func (t * testing.T ) {
206+ type UserContext struct {
207+ UserID string
208+ RoomID int
209+ Metadata map [string ]string
210+ }
211+
212+ ctx := UserContext {
213+ UserID : "user-123" ,
214+ RoomID : 456 ,
215+ Metadata : map [string ]string {
216+ "key1" : "value1" ,
217+ },
218+ }
219+ opts := & RunOptions {
220+ RuntimeState : map [string ]any {
221+ "user_context" : ctx ,
222+ },
223+ }
224+
225+ retrieved , ok := GetRuntimeStateValue [UserContext ](opts , "user_context" )
226+ require .True (t , ok )
227+ assert .Equal (t , ctx .UserID , retrieved .UserID )
228+ assert .Equal (t , ctx .RoomID , retrieved .RoomID )
229+ assert .Equal (t , ctx .Metadata , retrieved .Metadata )
230+ })
231+ }
232+
103233func TestWithInvocationTransferInfo (t * testing.T ) {
104234 transferInfo := & TransferInfo {
105235 TargetAgentName : "target-agent" ,
0 commit comments