Spaces:
Running
Running
Henri Bonamy
commited on
Commit
·
916a4b8
1
Parent(s):
1297e91
prompt changes, more robust hf token sending, banner
Browse files- agent/main.py +14 -2
- agent/prompts/system_prompt.yaml +6 -3
- agent/tools/jobs_tool.py +8 -6
- agent/tools/plan_tool.py +3 -3
agent/main.py
CHANGED
|
@@ -71,7 +71,7 @@ async def event_listener(
|
|
| 71 |
|
| 72 |
# Display event
|
| 73 |
if event.event_type == "ready":
|
| 74 |
-
print(format_success("Agent ready"))
|
| 75 |
ready_event.set()
|
| 76 |
elif event.event_type == "assistant_message":
|
| 77 |
content = event.data.get("content", "") if event.data else ""
|
|
@@ -196,9 +196,21 @@ async def main():
|
|
| 196 |
# Clear screen
|
| 197 |
os.system('clear' if os.name != 'nt' else 'cls')
|
| 198 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 199 |
print(format_separator())
|
| 200 |
-
print(f"{Colors.YELLOW}{
|
| 201 |
print("Type your messages below. Type 'exit', 'quit', or '/quit' to end.\n")
|
|
|
|
| 202 |
|
| 203 |
# Create queues for communication
|
| 204 |
submission_queue = asyncio.Queue()
|
|
|
|
| 71 |
|
| 72 |
# Display event
|
| 73 |
if event.event_type == "ready":
|
| 74 |
+
print(format_success("\U0001F917 Agent ready"))
|
| 75 |
ready_event.set()
|
| 76 |
elif event.event_type == "assistant_message":
|
| 77 |
content = event.data.get("content", "") if event.data else ""
|
|
|
|
| 196 |
# Clear screen
|
| 197 |
os.system('clear' if os.name != 'nt' else 'cls')
|
| 198 |
|
| 199 |
+
|
| 200 |
+
banner = r"""
|
| 201 |
+
_ _ _ _____ _ _
|
| 202 |
+
| | | |_ _ __ _ __ _(_)_ __ __ _ | ___|_ _ ___ ___ / \ __ _ ___ _ __ | |_
|
| 203 |
+
| |_| | | | |/ _` |/ _` | | '_ \ / _` | | |_ / _` |/ __/ _ \ / _ \ / _` |/ _ \ '_ \| __|
|
| 204 |
+
| _ | |_| | (_| | (_| | | | | | (_| | | _| (_| | (_| __/ / ___ \ (_| | __/ | | | |_
|
| 205 |
+
|_| |_|\__,_|\__, |\__, |_|_| |_|\__, | |_| \__,_|\___\___| /_/ \_\__, |\___|_| |_|\__|
|
| 206 |
+
|___/ |___/ |___/ |___/
|
| 207 |
+
"""
|
| 208 |
+
|
| 209 |
+
|
| 210 |
print(format_separator())
|
| 211 |
+
print(f"{Colors.YELLOW} {banner}{Colors.RESET}")
|
| 212 |
print("Type your messages below. Type 'exit', 'quit', or '/quit' to end.\n")
|
| 213 |
+
print(format_separator())
|
| 214 |
|
| 215 |
# Create queues for communication
|
| 216 |
submission_queue = asyncio.Queue()
|
agent/prompts/system_prompt.yaml
CHANGED
|
@@ -11,7 +11,7 @@ system_prompt: |
|
|
| 11 |
# Autonomy / Subordinate trade-off.
|
| 12 |
|
| 13 |
Your main goal is to achieve what the user asked. For this:
|
| 14 |
-
1. Take action, follow-up, launch jobs. Ask for as little action from the user as possible.
|
| 15 |
|
| 16 |
However !! :
|
| 17 |
1. Don't surprise the user with costly, irreversible, or strange actions without asking.
|
|
@@ -85,13 +85,16 @@ system_prompt: |
|
|
| 85 |
# Conventions
|
| 86 |
|
| 87 |
- Always search Hugging Face Hub for existing resources before suggesting custom implementations
|
|
|
|
|
|
|
|
|
|
| 88 |
- When referencing models, datasets, or papers, include direct links from search results
|
| 89 |
- Never assume a library is available - check documentation first
|
| 90 |
- Before processing any dataset: inspect its actual structure first using the mcp__hf-mcp-server__hub_repo_details tool. Never assume column names: verify them beforehand.
|
| 91 |
- Follow ML best practices: proper train/val/test splits, reproducibility, evaluation metrics
|
| 92 |
- Unless absolutely necessary, don't ask user for action. This does not apply to follow-up questions you have.
|
| 93 |
-
- For training tasks, consider compute requirements and
|
| 94 |
-
- Never expose or log API keys, tokens, or secrets
|
| 95 |
|
| 96 |
# Communication Style
|
| 97 |
|
|
|
|
| 11 |
# Autonomy / Subordinate trade-off.
|
| 12 |
|
| 13 |
Your main goal is to achieve what the user asked. For this:
|
| 14 |
+
1. Take action, follow-up, launch jobs. Ask for as little action from the user as possible. Do not ask them to do things you could do via a script.
|
| 15 |
|
| 16 |
However !! :
|
| 17 |
1. Don't surprise the user with costly, irreversible, or strange actions without asking.
|
|
|
|
| 85 |
# Conventions
|
| 86 |
|
| 87 |
- Always search Hugging Face Hub for existing resources before suggesting custom implementations
|
| 88 |
+
- Keep in mind that a space is a repo, so you can create a space directly by uploading files that way. Repos should also be used to store files permanently : post-execution, files from jobs are not available.
|
| 89 |
+
- To run jobs, you must always pass the whole content of the file to execute. No files are available on server. Your local files and distant files are entirely seperate scopes.
|
| 90 |
+
- To access, create, or modify private Hub assets (spaces, private models, datasets, collections), pass `secrets: {% raw %}{{ "HF_TOKEN": "$HF_TOKEN" }}{% endraw %}` along with the jobs parameters. This is important. Without it, you will encounter authentification issues. Do not assume the user is connected on the jobs' server.
|
| 91 |
- When referencing models, datasets, or papers, include direct links from search results
|
| 92 |
- Never assume a library is available - check documentation first
|
| 93 |
- Before processing any dataset: inspect its actual structure first using the mcp__hf-mcp-server__hub_repo_details tool. Never assume column names: verify them beforehand.
|
| 94 |
- Follow ML best practices: proper train/val/test splits, reproducibility, evaluation metrics
|
| 95 |
- Unless absolutely necessary, don't ask user for action. This does not apply to follow-up questions you have.
|
| 96 |
+
- For training tasks, consider compute requirements and choose appropriate hardware.
|
| 97 |
+
- Never expose or log API keys, tokens, or secrets. Do not assume keys or secrets are available. Only Hugging Face private resources are available.
|
| 98 |
|
| 99 |
# Communication Style
|
| 100 |
|
agent/tools/jobs_tool.py
CHANGED
|
@@ -66,20 +66,21 @@ UV_DEFAULT_IMAGE = "ghcr.io/astral-sh/uv:python3.12-bookworm"
|
|
| 66 |
|
| 67 |
def _substitute_hf_token(params: Dict[str, Any] | None) -> Dict[str, Any] | None:
|
| 68 |
"""
|
| 69 |
-
Substitute
|
| 70 |
|
| 71 |
Args:
|
| 72 |
-
params: Dictionary that may contain "
|
| 73 |
|
| 74 |
Returns:
|
| 75 |
-
Dictionary with
|
| 76 |
"""
|
|
|
|
| 77 |
if params is None:
|
| 78 |
return None
|
| 79 |
|
| 80 |
result = {}
|
| 81 |
for key, value in params.items():
|
| 82 |
-
if
|
| 83 |
result[key] = os.environ.get("HF_TOKEN", "")
|
| 84 |
else:
|
| 85 |
result[key] = value
|
|
@@ -354,7 +355,8 @@ Call this tool with:
|
|
| 354 |
"operation": "uv",
|
| 355 |
"args": {{
|
| 356 |
"script": "import random\\nprint(42 + random.randint(1, 5))",
|
| 357 |
-
"dependencies"
|
|
|
|
| 358 |
}}
|
| 359 |
}}
|
| 360 |
```
|
|
@@ -384,7 +386,7 @@ Call this tool with:
|
|
| 384 |
|
| 385 |
- Jobs default to non-detached mode (stream logs until completion). Set `detach: true` to return immediately.
|
| 386 |
- Prefer array commands to avoid shell parsing surprises
|
| 387 |
-
- To access private Hub assets (spaces, private models, datasets, collections), pass `secrets: {{ "HF_TOKEN": "$HF_TOKEN" }}
|
| 388 |
- Before calling a job, think about dependencies (they must be specified), which hardware flavor to run on (choose simplest for task), and whether to include secrets.
|
| 389 |
"""
|
| 390 |
return {"formatted": usage_text, "totalResults": 1, "resultsShared": 1}
|
|
|
|
| 66 |
|
| 67 |
def _substitute_hf_token(params: Dict[str, Any] | None) -> Dict[str, Any] | None:
|
| 68 |
"""
|
| 69 |
+
Substitute HF_TOKEN key with actual token value from environment.
|
| 70 |
|
| 71 |
Args:
|
| 72 |
+
params: Dictionary that may contain "HF_TOKEN" as a key
|
| 73 |
|
| 74 |
Returns:
|
| 75 |
+
Dictionary with HF_TOKEN value substituted from environment
|
| 76 |
"""
|
| 77 |
+
print("DEBUG !! : ", params)
|
| 78 |
if params is None:
|
| 79 |
return None
|
| 80 |
|
| 81 |
result = {}
|
| 82 |
for key, value in params.items():
|
| 83 |
+
if key == "HF_TOKEN":
|
| 84 |
result[key] = os.environ.get("HF_TOKEN", "")
|
| 85 |
else:
|
| 86 |
result[key] = value
|
|
|
|
| 355 |
"operation": "uv",
|
| 356 |
"args": {{
|
| 357 |
"script": "import random\\nprint(42 + random.randint(1, 5))",
|
| 358 |
+
"dependencies": ["torch", "huggingface_hub"],
|
| 359 |
+
"secrets": {{"HF_TOKEN": "$HF_TOKEN"}}
|
| 360 |
}}
|
| 361 |
}}
|
| 362 |
```
|
|
|
|
| 386 |
|
| 387 |
- Jobs default to non-detached mode (stream logs until completion). Set `detach: true` to return immediately.
|
| 388 |
- Prefer array commands to avoid shell parsing surprises
|
| 389 |
+
- To access, create, or modify private Hub assets (spaces, private models, datasets, collections), pass `secrets: {{ "HF_TOKEN": "$HF_TOKEN" }}`. This is important. Without it, you will encounter authentification issues. Do not assume the user is connected on the jobs' server.
|
| 390 |
- Before calling a job, think about dependencies (they must be specified), which hardware flavor to run on (choose simplest for task), and whether to include secrets.
|
| 391 |
"""
|
| 392 |
return {"formatted": usage_text, "totalResults": 1, "resultsShared": 1}
|
agent/tools/plan_tool.py
CHANGED
|
@@ -33,7 +33,7 @@ class PlanTool:
|
|
| 33 |
for todo in todos:
|
| 34 |
if not isinstance(todo, dict):
|
| 35 |
return {
|
| 36 |
-
"formatted": "Error: Each todo must be an object",
|
| 37 |
"isError": True,
|
| 38 |
}
|
| 39 |
|
|
@@ -41,7 +41,7 @@ class PlanTool:
|
|
| 41 |
for field in required_fields:
|
| 42 |
if field not in todo:
|
| 43 |
return {
|
| 44 |
-
"formatted": f"Error: Todo missing required field '{field}'",
|
| 45 |
"isError": True,
|
| 46 |
}
|
| 47 |
|
|
@@ -49,7 +49,7 @@ class PlanTool:
|
|
| 49 |
valid_statuses = ["pending", "in_progress", "completed"]
|
| 50 |
if todo["status"] not in valid_statuses:
|
| 51 |
return {
|
| 52 |
-
"formatted": f"Error: Invalid status '{todo['status']}'. Must be one of: {', '.join(valid_statuses)}",
|
| 53 |
"isError": True,
|
| 54 |
}
|
| 55 |
|
|
|
|
| 33 |
for todo in todos:
|
| 34 |
if not isinstance(todo, dict):
|
| 35 |
return {
|
| 36 |
+
"formatted": "Error: Each todo must be an object. Re call the tool with correct format (mandatory).",
|
| 37 |
"isError": True,
|
| 38 |
}
|
| 39 |
|
|
|
|
| 41 |
for field in required_fields:
|
| 42 |
if field not in todo:
|
| 43 |
return {
|
| 44 |
+
"formatted": f"Error: Todo missing required field '{field}'. Re call the tool with correct format (mandatory).",
|
| 45 |
"isError": True,
|
| 46 |
}
|
| 47 |
|
|
|
|
| 49 |
valid_statuses = ["pending", "in_progress", "completed"]
|
| 50 |
if todo["status"] not in valid_statuses:
|
| 51 |
return {
|
| 52 |
+
"formatted": f"Error: Invalid status '{todo['status']}'. Must be one of: {', '.join(valid_statuses)}. Re call the tool with correct format (mandatory).",
|
| 53 |
"isError": True,
|
| 54 |
}
|
| 55 |
|