1
1
import asyncio
2
+ import os
2
3
import signal
3
4
import traceback
4
5
from typing import Any , Dict , List , Optional
@@ -39,6 +40,7 @@ async def run_agent(
39
40
40
41
config , prompt = _load_agent_config (agent_path )
41
42
43
+ inputs : List [Dict [str , Any ]] = config .get ("inputs" , [])
42
44
servers : List [Dict [str , Any ]] = config .get ("servers" , [])
43
45
44
46
abort_event = asyncio .Event ()
@@ -68,6 +70,60 @@ def _sigint_handler() -> None:
68
70
# Windows (or any loop that doesn't support it) : fall back to sync
69
71
signal .signal (signal .SIGINT , lambda * _ : _sigint_handler ())
70
72
73
+ # Handle inputs (i.e. env variables injection)
74
+ if len (inputs ) > 0 :
75
+ print (
76
+ "[bold blue]Some initial inputs are required by the agent. "
77
+ "Please provide a value or leave empty to load from env.[/bold blue]"
78
+ )
79
+ for input_item in inputs :
80
+ input_id = input_item ["id" ]
81
+ description = input_item ["description" ]
82
+ env_special_value = "${input:" + input_id + "}" # Special value to indicate env variable injection
83
+
84
+ # Check env variables that will use this input
85
+ input_vars = list (
86
+ {
87
+ key
88
+ for server in servers
89
+ for key , value in server .get ("config" , {}).get ("env" , {}).items ()
90
+ if value == env_special_value
91
+ }
92
+ )
93
+
94
+ if not input_vars :
95
+ print (f"[yellow]Input { input_id } defined in config but not used by any server.[/yellow]" )
96
+ continue
97
+
98
+ # Prompt user for input
99
+ print (
100
+ f"[blue] • { input_id } [/blue]: { description } . (default: load from { ', ' .join (input_vars )} )." ,
101
+ end = " " ,
102
+ )
103
+ user_input = (await _async_prompt (exit_event = exit_event )).strip ()
104
+ if exit_event .is_set ():
105
+ return
106
+
107
+ # Inject user input (or env variable) into servers' env
108
+ for server in servers :
109
+ env = server .get ("config" , {}).get ("env" , {})
110
+ for key , value in env .items ():
111
+ if value == env_special_value :
112
+ if user_input :
113
+ env [key ] = user_input
114
+ else :
115
+ value_from_env = os .getenv (key , "" )
116
+ env [key ] = value_from_env
117
+ if value_from_env :
118
+ print (f"[green]Value successfully loaded from '{ key } '[/green]" )
119
+ else :
120
+ print (
121
+ f"[yellow]No value found for '{ key } ' in environment variables. Continuing.[/yellow]"
122
+ )
123
+
124
+ print ()
125
+
126
+ # Main agent loop
71
127
async with Agent (
72
128
provider = config .get ("provider" ),
73
129
model = config .get ("model" ),
@@ -85,7 +141,7 @@ def _sigint_handler() -> None:
85
141
86
142
# Check if we should exit
87
143
if exit_event .is_set ():
88
- break
144
+ return
89
145
90
146
try :
91
147
user_input = await _async_prompt (exit_event = exit_event )
@@ -105,7 +161,7 @@ def _sigint_handler() -> None:
105
161
if abort_event .is_set () and not first_sigint :
106
162
break
107
163
if exit_event .is_set ():
108
- break
164
+ return
109
165
110
166
if hasattr (chunk , "choices" ):
111
167
delta = chunk .choices [0 ].delta
0 commit comments