tao-shen Claude Opus 4.6 commited on
Commit
ddef022
·
1 Parent(s): f3f1288

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>

Files changed (1) hide show
  1. 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: restart] after identifying which env var names collide with secret names.
684
- - The env vars and secrets are shown in the context below. Look for names that appear in BOTH the Variables and Secrets lists.
685
- - To fix: the colliding variable or secret needs to be removed. Claude Code cannot do this — use the discussion to identify the collision, then tell your partner.
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