Compare commits

..

3 Commits

Author SHA1 Message Date
Songbird
574e0cbce7 Support flexible A2A agent registration and fix redirects
- Accept direct .json URLs (e.g., http://host/.well-known/agent-card.json)
- Accept base agent URLs (e.g., http://host/a2a/sentinel)
- Extract canonical URL from agent card response
- Try both agent-card.json and agent.json for compatibility
- Follow HTTP redirects for POST requests (fixes 307 redirects)
- Remove trailing slash from POST endpoint to avoid redirect loops

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 23:02:11 +01:00
Ectario
f6cdb1ae2e fix(docs): fixing workflow docs (#29) 2025-10-27 12:37:04 +01:00
tduhamel42
731927667d fix/ Change default llm_secret_detection to gpt-5-mini 2025-10-22 10:17:41 +02:00
7 changed files with 49 additions and 26 deletions

View File

@@ -26,27 +26,50 @@ class RemoteAgentConnection:
"""Initialize connection to a remote agent"""
self.url = url.rstrip('/')
self.agent_card = None
self.client = httpx.AsyncClient(timeout=120.0)
self.client = httpx.AsyncClient(timeout=120.0, follow_redirects=True)
self.context_id = None
async def get_agent_card(self) -> Optional[Dict[str, Any]]:
"""Get the agent card from the remote agent"""
try:
# Try new path first (A2A 0.3.0+)
response = await self.client.get(f"{self.url}/.well-known/agent-card.json")
response.raise_for_status()
self.agent_card = response.json()
return self.agent_card
except Exception:
# Try old path for compatibility
# If URL already points to a .json file, fetch it directly
if self.url.endswith('.json'):
try:
response = await self.client.get(f"{self.url}/.well-known/agent.json")
response = await self.client.get(self.url)
response.raise_for_status()
self.agent_card = response.json()
# Use canonical URL from agent card if provided
if isinstance(self.agent_card, dict) and "url" in self.agent_card:
self.url = self.agent_card["url"].rstrip('/')
return self.agent_card
except Exception as e:
print(f"Failed to get agent card from {self.url}: {e}")
return None
# Try both agent-card.json (A2A 0.3.0+) and agent.json (legacy)
well_known_paths = [
"/.well-known/agent-card.json",
"/.well-known/agent.json",
]
for path in well_known_paths:
try:
response = await self.client.get(f"{self.url}{path}")
response.raise_for_status()
self.agent_card = response.json()
# Use canonical URL from agent card if provided
if isinstance(self.agent_card, dict) and "url" in self.agent_card:
self.url = self.agent_card["url"].rstrip('/')
return self.agent_card
except Exception:
continue
print(f"Failed to get agent card from {self.url}")
print("Tip: If agent is at /a2a/something, use full URL: /register http://host:port/a2a/something")
return None
async def send_message(self, message: str | Dict[str, Any] | List[Dict[str, Any]]) -> str:
"""Send a message to the remote agent using A2A protocol"""
@@ -93,7 +116,7 @@ class RemoteAgentConnection:
payload["params"]["contextId"] = self.context_id
# Send to root endpoint per A2A protocol
response = await self.client.post(f"{self.url}/", json=payload)
response = await self.client.post(self.url, json=payload)
response.raise_for_status()
result = response.json()

View File

@@ -17,22 +17,22 @@ parameters:
agent_url:
type: string
default: "http://fuzzforge-task-agent:8000/a2a/litellm_agent"
llm_model:
type: string
default: "gpt-4o-mini"
default: "gpt-5-mini"
llm_provider:
type: string
default: "openai"
max_files:
type: integer
default: 20
default_parameters:
agent_url: "http://fuzzforge-task-agent:8000/a2a/litellm_agent"
llm_model: "gpt-4o-mini"
llm_model: "gpt-5-mini"
llm_provider: "openai"
max_files: 20

View File

@@ -78,7 +78,7 @@ fuzzforge workflows list
fuzzforge workflows info security_assessment
# Submit a workflow for analysis
fuzzforge workflow security_assessment /path/to/your/code
fuzzforge workflow run security_assessment /path/to/your/code
# View findings when complete
@@ -150,24 +150,24 @@ fuzzforge workflows parameters security_assessment --no-interactive
### Workflow Execution
#### `fuzzforge workflow <workflow> <target-path>`
#### `fuzzforge workflow run <workflow> <target-path>`
Execute a security testing workflow with **automatic file upload**.
```bash
# Basic execution - CLI automatically detects local files and uploads them
fuzzforge workflow security_assessment /path/to/code
fuzzforge workflow run security_assessment /path/to/code
# With parameters
fuzzforge workflow security_assessment /path/to/binary \
fuzzforge workflow run security_assessment /path/to/binary \
--param timeout=3600 \
--param iterations=10000
# With parameter file
fuzzforge workflow security_assessment /path/to/code \
fuzzforge workflow run security_assessment /path/to/code \
--param-file my-params.json
# Wait for completion
fuzzforge workflow security_assessment /path/to/code --wait
fuzzforge workflow run security_assessment /path/to/code --wait
```
**Automatic File Upload Behavior:**

View File

@@ -141,7 +141,7 @@ FuzzForge security testing project.
fuzzforge workflows
# Submit a workflow for analysis
fuzzforge workflow <workflow-name> /path/to/target
fuzzforge workflow run <workflow-name> /path/to/target
# View findings
fuzzforge finding <run-id>

View File

@@ -438,7 +438,7 @@ def execute_workflow(
# Suggest --live for fuzzing workflows
if not live and not wait and "fuzzing" in workflow.lower():
console.print(f"💡 Next time try: [bold cyan]fuzzforge workflow {workflow} {target_path} --live[/bold cyan] for real-time monitoring", style="dim")
console.print(f"💡 Next time try: [bold cyan]fuzzforge workflow run {workflow} {target_path} --live[/bold cyan] for real-time monitoring", style="dim")
# Start live monitoring if requested
if live:

View File

@@ -251,7 +251,7 @@ def workflow_main():
Execute workflows and manage workflow executions
Examples:
fuzzforge workflow security_assessment ./target # Execute workflow
fuzzforge workflow run security_assessment ./target # Execute workflow
fuzzforge workflow status # Check latest status
fuzzforge workflow history # Show execution history
"""

View File

@@ -9,7 +9,7 @@ FuzzForge security testing project.
fuzzforge workflows
# Submit a workflow for analysis
fuzzforge workflow <workflow-name> /path/to/target
fuzzforge workflow run <workflow-name> /path/to/target
# View findings
fuzzforge finding <run-id>