Spaces:
Running
Running
feat: add delete_env action + collision auto-detection
Browse files- Add [ACTION: delete_env:KEY] to delete env vars that collide with secrets
- action_get_env() now detects and flags variable/secret name collisions
- System prompt teaches agents to use delete_env for CONFIG_ERROR fixes
- This is the correct fix: OPENAI_API_KEY exists as both Variable and Secret
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- scripts/conversation-loop.py +31 -5
scripts/conversation-loop.py
CHANGED
|
@@ -236,15 +236,27 @@ def action_restart():
|
|
| 236 |
return f"Restart failed: {e}"
|
| 237 |
|
| 238 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 239 |
def action_get_env():
|
| 240 |
-
"""List environment variables and secrets on the child's Space."""
|
| 241 |
try:
|
| 242 |
lines = [f"{CHILD_NAME}'s environment:"]
|
|
|
|
|
|
|
| 243 |
vars_dict = hf_api.get_space_variables(CHILD_SPACE_ID)
|
| 244 |
if vars_dict:
|
| 245 |
lines.append(" Variables:")
|
| 246 |
for k, v in vars_dict.items():
|
| 247 |
lines.append(f" {k} = {v.value}")
|
|
|
|
| 248 |
info = hf_api.space_info(CHILD_SPACE_ID)
|
| 249 |
if hasattr(info, 'runtime') and info.runtime and hasattr(info.runtime, 'secrets'):
|
| 250 |
secrets = info.runtime.secrets
|
|
@@ -252,6 +264,13 @@ def action_get_env():
|
|
| 252 |
lines.append(" Secrets (values hidden):")
|
| 253 |
for s in secrets:
|
| 254 |
lines.append(f" {s} = ****")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 255 |
return "\n".join(lines)
|
| 256 |
except Exception as e:
|
| 257 |
return f"Error: {e}"
|
|
@@ -634,6 +653,13 @@ def parse_and_execute_turn(raw_text, ctx):
|
|
| 634 |
result = action_restart()
|
| 635 |
results.append({"action": "restart", "result": result})
|
| 636 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 637 |
# 4. Handle [ACTION: send_bubble:...] (parent-child communication)
|
| 638 |
bubble_match = re.search(r'\[ACTION:\s*send_bubble:([^\]]+)\]', raw_text)
|
| 639 |
if bubble_match:
|
|
@@ -680,10 +706,9 @@ You do NOT read files or write code yourself. You analyze the situation and give
|
|
| 680 |
IMPORTANT KNOWLEDGE — HuggingFace Spaces CONFIG_ERROR:
|
| 681 |
- "Collision on variables and secrets names" means a HF Space has an ENVIRONMENT VARIABLE and a SECRET with the SAME NAME.
|
| 682 |
- This is NOT about duplicate JSON keys. It's about the HF Space settings page.
|
| 683 |
-
- Fix: use [ACTION:
|
| 684 |
-
- The env vars and secrets are shown in the
|
| 685 |
-
-
|
| 686 |
-
- Actually, this may require manual intervention via HF API. Discuss what you find.
|
| 687 |
|
| 688 |
AVAILABLE ACTIONS:
|
| 689 |
[TASK]
|
|
@@ -692,6 +717,7 @@ AVAILABLE ACTIONS:
|
|
| 692 |
[/TASK]
|
| 693 |
|
| 694 |
[ACTION: restart] — Restart {CHILD_NAME}'s Space
|
|
|
|
| 695 |
[ACTION: send_bubble:MESSAGE] — Send a message to {CHILD_NAME}
|
| 696 |
[ACTION: create_child] — Create {CHILD_NAME} (if not born)
|
| 697 |
|
|
|
|
| 236 |
return f"Restart failed: {e}"
|
| 237 |
|
| 238 |
|
| 239 |
+
def action_delete_env(key):
|
| 240 |
+
"""Delete an environment variable from the child's Space (fixes CONFIG_ERROR collisions)."""
|
| 241 |
+
try:
|
| 242 |
+
hf_api.delete_space_variable(CHILD_SPACE_ID, key)
|
| 243 |
+
return f"Deleted variable {key} from {CHILD_NAME}'s Space. Use [ACTION: restart] to apply."
|
| 244 |
+
except Exception as e:
|
| 245 |
+
return f"Error deleting variable {key}: {e}"
|
| 246 |
+
|
| 247 |
+
|
| 248 |
def action_get_env():
|
| 249 |
+
"""List environment variables and secrets on the child's Space, flag collisions."""
|
| 250 |
try:
|
| 251 |
lines = [f"{CHILD_NAME}'s environment:"]
|
| 252 |
+
var_names = set()
|
| 253 |
+
secret_names = set()
|
| 254 |
vars_dict = hf_api.get_space_variables(CHILD_SPACE_ID)
|
| 255 |
if vars_dict:
|
| 256 |
lines.append(" Variables:")
|
| 257 |
for k, v in vars_dict.items():
|
| 258 |
lines.append(f" {k} = {v.value}")
|
| 259 |
+
var_names.add(k)
|
| 260 |
info = hf_api.space_info(CHILD_SPACE_ID)
|
| 261 |
if hasattr(info, 'runtime') and info.runtime and hasattr(info.runtime, 'secrets'):
|
| 262 |
secrets = info.runtime.secrets
|
|
|
|
| 264 |
lines.append(" Secrets (values hidden):")
|
| 265 |
for s in secrets:
|
| 266 |
lines.append(f" {s} = ****")
|
| 267 |
+
secret_names.add(s)
|
| 268 |
+
# Detect collisions (cause of CONFIG_ERROR)
|
| 269 |
+
collisions = var_names & secret_names
|
| 270 |
+
if collisions:
|
| 271 |
+
lines.append(f"\n ⚠️ COLLISION DETECTED: {', '.join(collisions)}")
|
| 272 |
+
lines.append(f" These names exist as BOTH Variables AND Secrets!")
|
| 273 |
+
lines.append(f" Fix: [ACTION: delete_env:{list(collisions)[0]}] then [ACTION: restart]")
|
| 274 |
return "\n".join(lines)
|
| 275 |
except Exception as e:
|
| 276 |
return f"Error: {e}"
|
|
|
|
| 653 |
result = action_restart()
|
| 654 |
results.append({"action": "restart", "result": result})
|
| 655 |
|
| 656 |
+
# 3b. Handle [ACTION: delete_env:KEY] (fix CONFIG_ERROR collisions)
|
| 657 |
+
del_env_match = re.search(r'\[ACTION:\s*delete_env:([^\]]+)\]', raw_text)
|
| 658 |
+
if del_env_match:
|
| 659 |
+
key = del_env_match.group(1).strip()
|
| 660 |
+
result = action_delete_env(key)
|
| 661 |
+
results.append({"action": f"delete_env:{key}", "result": result})
|
| 662 |
+
|
| 663 |
# 4. Handle [ACTION: send_bubble:...] (parent-child communication)
|
| 664 |
bubble_match = re.search(r'\[ACTION:\s*send_bubble:([^\]]+)\]', raw_text)
|
| 665 |
if bubble_match:
|
|
|
|
| 706 |
IMPORTANT KNOWLEDGE — HuggingFace Spaces CONFIG_ERROR:
|
| 707 |
- "Collision on variables and secrets names" means a HF Space has an ENVIRONMENT VARIABLE and a SECRET with the SAME NAME.
|
| 708 |
- This is NOT about duplicate JSON keys. It's about the HF Space settings page.
|
| 709 |
+
- Fix: use [ACTION: delete_env:COLLIDING_KEY] to remove the duplicate variable, then [ACTION: restart].
|
| 710 |
+
- The env vars and secrets are shown in the auto-gathered context. Look for ⚠️ COLLISION DETECTED.
|
| 711 |
+
- Example: if OPENAI_API_KEY appears in both Variables and Secrets → [ACTION: delete_env:OPENAI_API_KEY] then [ACTION: restart]
|
|
|
|
| 712 |
|
| 713 |
AVAILABLE ACTIONS:
|
| 714 |
[TASK]
|
|
|
|
| 717 |
[/TASK]
|
| 718 |
|
| 719 |
[ACTION: restart] — Restart {CHILD_NAME}'s Space
|
| 720 |
+
[ACTION: delete_env:KEY] — Delete an environment variable (fixes CONFIG_ERROR collisions!)
|
| 721 |
[ACTION: send_bubble:MESSAGE] — Send a message to {CHILD_NAME}
|
| 722 |
[ACTION: create_child] — Create {CHILD_NAME} (if not born)
|
| 723 |
|