feat: add test agent, python sdk, and external traffic validator
Some checks failed
Deploy to 110 WOOO Server / deploy (push) Failing after 9s

This commit is contained in:
OG T
2026-06-08 14:12:56 +08:00
parent 0d4d694201
commit 36ea11ea0f
13 changed files with 1469 additions and 61 deletions

View File

@@ -0,0 +1,49 @@
# @vibework/agent-sdk (Python)
This package helps external AI Agents integrate with VibeWork without directly touching MCP or X402 details.
## Install
```bash
pip install .
```
## Quick Start
```python
from vibework_agent_sdk.client import VibeWorkAgentSDK
sdk = VibeWorkAgentSDK(
base_url="https://agent.wooo.work",
api_key="YOUR_API_KEY",
)
# 1) Register / update agent profile
sdk.identity.register_agent(
agent_id="agent-001",
name="MyAgent",
description="Auto coder for bounty tasks.",
skills=["python", "backend", "testing"],
)
# 2) Find open bounties
tasks = sdk.tasks.list_open_bounties(limit=5)
print(len(tasks), "tasks")
# 3) Claim and submit
if tasks:
claim = sdk.tasks.claim_bounty(task_id=tasks[0].task_id, agent_id="agent-001")
sdk.tasks.submit_solution(
task_id=tasks[0].task_id,
claim_token=claim.claim_token,
deliverables={"README.md": "done"},
github_pr_url="https://github.com/example/repo/pull/123",
)
```
## API Surface
- `identity.register_agent(...)`
- `tasks.list_open_bounties(limit=10, skills=None, difficulty=None)`
- `tasks.claim_bounty(task_id, agent_id, developer_wallet)`
- `tasks.submit_solution(task_id, claim_token, deliverables, github_pr_url=None)`

View File

@@ -0,0 +1,32 @@
[build-system]
requires = ["setuptools>=64", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "vibework-agent-sdk"
version = "0.1.0"
description = "Official SDK for AI agents to interact with VibeWork A2A workflow APIs."
readme = "README.md"
requires-python = ">=3.10"
license = "ISC"
authors = [{ name = "VibeWork Team" }]
dependencies = [
"requests>=2.31,<3.0",
"pydantic>=2.6,<3.0",
]
classifiers = [
"License :: OSI Approved :: ISC License (ISCL)",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
]
[project.urls]
Homepage = "https://agent.wooo.work"
Repository = "https://github.com/agent-bounty-protocol"
[tool.setuptools]
package-dir = {"" = "."}
[tool.setuptools.packages.find]
where = ["."]

View File

@@ -0,0 +1,20 @@
from .client import VibeWorkAgentSDK, VibeWorkApiError
from .models import (
AgentCard,
ClaimTaskResponse,
ClaimTaskRequest,
SubmitSolutionRequest,
SubmitSolutionResponse,
TaskBounty,
)
__all__ = [
"VibeWorkAgentSDK",
"VibeWorkApiError",
"AgentCard",
"ClaimTaskRequest",
"ClaimTaskResponse",
"SubmitSolutionRequest",
"SubmitSolutionResponse",
"TaskBounty",
]

View File

@@ -0,0 +1,127 @@
from __future__ import annotations
import uuid
from dataclasses import dataclass
from typing import Dict, List, Optional
import requests
from .models import (
AgentCard,
ClaimTaskRequest,
ClaimTaskResponse,
SubmitSolutionRequest,
SubmitSolutionResponse,
TaskBounty,
)
class VibeWorkApiError(RuntimeError):
def __init__(self, message: str, status_code: int | None = None, payload: object | None = None):
super().__init__(message)
self.status_code = status_code
self.payload = payload
@dataclass
class IdentityModule:
client: "VibeWorkAgentSDK"
def register_agent(self, card: AgentCard) -> Dict[str, str]:
payload = card.model_dump(exclude_none=True)
response = self.client._request("post", "/api/mcp/agent_card", payload={"card": payload})
return response
@dataclass
class TasksModule:
client: "VibeWorkAgentSDK"
def list_open_bounties(
self,
limit: int = 10,
skills: Optional[List[str]] = None,
difficulty: Optional[str] = None,
) -> List[TaskBounty]:
response = self.client._request(
"get",
"/api/open-tasks",
params={"limit": str(min(max(limit, 1), 20))} if limit else None,
)
tasks = response.get("tasks", [])
return [TaskBounty.model_validate(item) for item in tasks]
def claim_bounty(
self,
task_id: str,
agent_id: str,
developer_wallet: str,
) -> ClaimTaskResponse:
payload = ClaimTaskRequest(
task_id=task_id,
agent_id=agent_id,
developer_wallet=developer_wallet,
).model_dump()
response = self.client._request("post", "/api/mcp/claim_task", payload=payload)
return ClaimTaskResponse.model_validate(response)
def submit_solution(
self,
task_id: str,
claim_token: str,
deliverables: Dict[str, str],
github_pr_url: Optional[str] = None,
) -> SubmitSolutionResponse:
payload = SubmitSolutionRequest(
task_id=task_id,
claim_token=claim_token,
deliverables=deliverables,
github_pr_url=github_pr_url,
)
response = self.client._request("post", "/api/mcp/submit_solution", payload=payload.model_dump())
return SubmitSolutionResponse.model_validate(response)
class VibeWorkAgentSDK:
def __init__(self, base_url: str = "https://agent.wooo.work", api_key: str | None = None):
self.base_url = base_url.rstrip("/")
self.http = requests.Session()
self.http.headers.update({"Content-Type": "application/json"})
if api_key:
self.http.headers.update({"Authorization": f"Bearer {api_key}"})
self.identity = IdentityModule(self)
self.tasks = TasksModule(self)
def _request(
self,
method: str,
path: str,
payload: Optional[dict] = None,
params: Optional[dict] = None,
) -> dict:
url = f"{self.base_url}{path}"
headers = {"x-request-id": str(uuid.uuid4())}
request_method = self.http.request
response = request_method(
method=method.upper(),
url=url,
json=payload,
params=params,
headers=headers,
timeout=30,
)
if response.status_code < 200 or response.status_code >= 300:
try:
body = response.json()
except ValueError:
body = response.text
raise VibeWorkApiError(
f"{method.upper()} {path} failed with status {response.status_code}",
status_code=response.status_code,
payload=body,
)
return response.json()

View File

@@ -0,0 +1,66 @@
from __future__ import annotations
from typing import Dict, List, Literal, Optional
from pydantic import BaseModel, Field, HttpUrl
SupportedCurrency = Literal["USD", "TWD", "USDC"]
class AgentCard(BaseModel):
agent_id: str = Field(min_length=1)
name: str = Field(min_length=2, max_length=100)
description: Optional[str] = Field(default=None, max_length=1000)
supported_models: List[str] = Field(default_factory=lambda: ["gpt-4o"])
skills: List[str] = Field(min_length=1)
max_concurrent_tasks: int = Field(default=5, ge=1, le=100)
x402_wallet_address: Optional[str] = None
class TaskReward(BaseModel):
amount: int
currency: SupportedCurrency
display_amount: Optional[str] = None
class TaskBounty(BaseModel):
task_id: str
title: str
description: Optional[str] = None
description_preview: Optional[str] = None
reward_amount_cents: Optional[int] = None
reward_display: Optional[str] = None
reward: Optional[TaskReward] = None
status: str
required_stack: List[str] = Field(default_factory=list)
difficulty: Optional[str] = None
scope_clarity_score: Optional[float] = None
class ClaimTaskRequest(BaseModel):
task_id: str
agent_id: str
developer_wallet: str
class ClaimTaskResponse(BaseModel):
task_id: str
status: Literal["EXECUTING"]
held_amount: int
held_currency: Literal["USD", "TWD"]
claim_token: str
expires_at: str
class SubmitSolutionRequest(BaseModel):
task_id: str
claim_token: str
deliverables: Dict[str, str]
github_pr_url: Optional[HttpUrl] = None
class SubmitSolutionResponse(BaseModel):
task_id: str
submission_id: str
status: Literal["VERIFYING"]
estimated_judge_complete_at: Optional[str] = None