Skip to content

Commit 2aafd15

Browse files
WauplinCopilot
andauthored
[tiny-agents] Handle env variables in tiny-agents (Python client) (#3129)
* [tiny-agents] forward local env variables * Approximately follow VSCode convention * Update src/huggingface_hub/inference/_mcp/cli.py Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Copilot <[email protected]>
1 parent f956f80 commit 2aafd15

File tree

1 file changed

+58
-2
lines changed
  • src/huggingface_hub/inference/_mcp

1 file changed

+58
-2
lines changed

src/huggingface_hub/inference/_mcp/cli.py

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import asyncio
2+
import os
23
import signal
34
import traceback
45
from typing import Any, Dict, List, Optional
@@ -39,6 +40,7 @@ async def run_agent(
3940

4041
config, prompt = _load_agent_config(agent_path)
4142

43+
inputs: List[Dict[str, Any]] = config.get("inputs", [])
4244
servers: List[Dict[str, Any]] = config.get("servers", [])
4345

4446
abort_event = asyncio.Event()
@@ -68,6 +70,60 @@ def _sigint_handler() -> None:
6870
# Windows (or any loop that doesn't support it) : fall back to sync
6971
signal.signal(signal.SIGINT, lambda *_: _sigint_handler())
7072

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
71127
async with Agent(
72128
provider=config.get("provider"),
73129
model=config.get("model"),
@@ -85,7 +141,7 @@ def _sigint_handler() -> None:
85141

86142
# Check if we should exit
87143
if exit_event.is_set():
88-
break
144+
return
89145

90146
try:
91147
user_input = await _async_prompt(exit_event=exit_event)
@@ -105,7 +161,7 @@ def _sigint_handler() -> None:
105161
if abort_event.is_set() and not first_sigint:
106162
break
107163
if exit_event.is_set():
108-
break
164+
return
109165

110166
if hasattr(chunk, "choices"):
111167
delta = chunk.choices[0].delta

0 commit comments

Comments
 (0)