feat: Enhance login page UI with delayed redirect instead of transparent 307
Some checks failed
Deploy to 110 WOOO Server / deploy (push) Failing after 8s
Some checks failed
Deploy to 110 WOOO Server / deploy (push) Failing after 8s
This commit is contained in:
@@ -1,10 +1,22 @@
|
||||
from .client import VibeWorkAgentSDK, VibeWorkApiError
|
||||
from .models import (
|
||||
AgentCard,
|
||||
ClaimTaskResponse,
|
||||
ClaimTaskRequest,
|
||||
ClaimTaskResponse,
|
||||
SubmitSolutionRequest,
|
||||
SubmitSolutionResponse,
|
||||
ListOpenTasksMcpResponse,
|
||||
CreateSubTaskRequest,
|
||||
CreateSubTaskResponse,
|
||||
RequestPeerReviewRequest,
|
||||
RequestPeerReviewResponse,
|
||||
BroadcastHelpSignalRequest,
|
||||
BroadcastHelpSignalResponse,
|
||||
QueryAgentMemoryRequest,
|
||||
QueryAgentMemoryResponse,
|
||||
RentApiResourceRequest,
|
||||
RentApiResourceResponse,
|
||||
A2AResourceType,
|
||||
TaskBounty,
|
||||
)
|
||||
|
||||
@@ -17,4 +29,16 @@ __all__ = [
|
||||
"SubmitSolutionRequest",
|
||||
"SubmitSolutionResponse",
|
||||
"TaskBounty",
|
||||
"ListOpenTasksMcpResponse",
|
||||
"CreateSubTaskRequest",
|
||||
"CreateSubTaskResponse",
|
||||
"RequestPeerReviewRequest",
|
||||
"RequestPeerReviewResponse",
|
||||
"BroadcastHelpSignalRequest",
|
||||
"BroadcastHelpSignalResponse",
|
||||
"QueryAgentMemoryRequest",
|
||||
"QueryAgentMemoryResponse",
|
||||
"RentApiResourceRequest",
|
||||
"RentApiResourceResponse",
|
||||
"A2AResourceType",
|
||||
]
|
||||
|
||||
@@ -12,6 +12,17 @@ from .models import (
|
||||
ClaimTaskResponse,
|
||||
SubmitSolutionRequest,
|
||||
SubmitSolutionResponse,
|
||||
ListOpenTasksMcpResponse,
|
||||
CreateSubTaskRequest,
|
||||
CreateSubTaskResponse,
|
||||
RequestPeerReviewRequest,
|
||||
RequestPeerReviewResponse,
|
||||
BroadcastHelpSignalRequest,
|
||||
BroadcastHelpSignalResponse,
|
||||
QueryAgentMemoryRequest,
|
||||
QueryAgentMemoryResponse,
|
||||
RentApiResourceRequest,
|
||||
RentApiResourceResponse,
|
||||
TaskBounty,
|
||||
)
|
||||
|
||||
@@ -81,6 +92,49 @@ class TasksModule:
|
||||
response = self.client._request("post", "/api/mcp/submit_solution", payload=payload.model_dump())
|
||||
return SubmitSolutionResponse.model_validate(response)
|
||||
|
||||
def list_open_bounties_via_mcp(
|
||||
self,
|
||||
limit: int = 5,
|
||||
skills: Optional[List[str]] = None,
|
||||
difficulty: Optional[str] = None,
|
||||
) -> ListOpenTasksMcpResponse:
|
||||
payload = {
|
||||
"skills": skills or [],
|
||||
"limit": min(max(limit, 1), 20),
|
||||
}
|
||||
if difficulty:
|
||||
payload["difficulty"] = difficulty
|
||||
response = self.client._request("post", "/api/mcp/list_open_tasks", payload=payload)
|
||||
return ListOpenTasksMcpResponse.model_validate(response)
|
||||
|
||||
|
||||
@dataclass
|
||||
class A2AModule:
|
||||
client: "VibeWorkAgentSDK"
|
||||
|
||||
def list_open_bounties(self, limit: int = 8) -> ListOpenTasksMcpResponse:
|
||||
return self.client.tasks.list_open_bounties_via_mcp(limit=limit)
|
||||
|
||||
def create_sub_task(self, request: CreateSubTaskRequest) -> CreateSubTaskResponse:
|
||||
response = self.client._request("post", "/api/mcp/create_sub_task", payload=request.model_dump())
|
||||
return CreateSubTaskResponse.model_validate(response)
|
||||
|
||||
def request_peer_review(self, request: RequestPeerReviewRequest) -> RequestPeerReviewResponse:
|
||||
response = self.client._request("post", "/api/mcp/request_peer_review", payload=request.model_dump())
|
||||
return RequestPeerReviewResponse.model_validate(response)
|
||||
|
||||
def broadcast_help_signal(self, request: BroadcastHelpSignalRequest) -> BroadcastHelpSignalResponse:
|
||||
response = self.client._request("post", "/api/mcp/broadcast_help_signal", payload=request.model_dump())
|
||||
return BroadcastHelpSignalResponse.model_validate(response)
|
||||
|
||||
def query_agent_memory(self, request: QueryAgentMemoryRequest) -> QueryAgentMemoryResponse:
|
||||
response = self.client._request("post", "/api/mcp/query_agent_memory", payload=request.model_dump())
|
||||
return QueryAgentMemoryResponse.model_validate(response)
|
||||
|
||||
def rent_api_resource(self, request: RentApiResourceRequest) -> RentApiResourceResponse:
|
||||
response = self.client._request("post", "/api/mcp/rent_api_resource", payload=request.model_dump())
|
||||
return RentApiResourceResponse.model_validate(response)
|
||||
|
||||
|
||||
class VibeWorkAgentSDK:
|
||||
def __init__(self, base_url: str = "https://agent.wooo.work", api_key: str | None = None):
|
||||
@@ -93,6 +147,7 @@ class VibeWorkAgentSDK:
|
||||
|
||||
self.identity = IdentityModule(self)
|
||||
self.tasks = TasksModule(self)
|
||||
self.a2a = A2AModule(self)
|
||||
|
||||
def _request(
|
||||
self,
|
||||
|
||||
@@ -64,3 +64,95 @@ class SubmitSolutionResponse(BaseModel):
|
||||
submission_id: str
|
||||
status: Literal["VERIFYING"]
|
||||
estimated_judge_complete_at: Optional[str] = None
|
||||
|
||||
|
||||
ValidationMode = Literal["VITEST_UNIT", "PLAYWRIGHT_E2E", "AST_PARSING", "VISUAL_REGRESSION"]
|
||||
A2AResourceType = Literal["GPT_4O", "CLAUDE_3_5_SONNET", "EMBEDDINGS"]
|
||||
|
||||
|
||||
class AcceptanceRule(BaseModel):
|
||||
assertion: str
|
||||
expected: object
|
||||
description: Optional[str] = None
|
||||
|
||||
|
||||
class AcceptanceCriteria(BaseModel):
|
||||
validation_mode: ValidationMode
|
||||
test_file_content: str
|
||||
rules: Optional[List[AcceptanceRule]] = None
|
||||
|
||||
|
||||
class ListOpenTasksMcpResponse(BaseModel):
|
||||
tasks: List[TaskBounty] = Field(default_factory=list)
|
||||
total_open: int
|
||||
stockout_warning: bool
|
||||
|
||||
|
||||
class CreateSubTaskRequest(BaseModel):
|
||||
parent_task_id: str
|
||||
claim_token: str
|
||||
title: str
|
||||
description: str
|
||||
reward_amount: int
|
||||
acceptance_criteria: AcceptanceCriteria
|
||||
|
||||
|
||||
class CreateSubTaskResponse(BaseModel):
|
||||
sub_task_id: str
|
||||
status: Literal["DRAFT", "OPEN"]
|
||||
|
||||
|
||||
class RequestPeerReviewRequest(BaseModel):
|
||||
parent_task_id: str
|
||||
claim_token: str
|
||||
code_snippet: str
|
||||
review_instructions: str
|
||||
|
||||
|
||||
class RequestPeerReviewResponse(BaseModel):
|
||||
review_task_id: str
|
||||
status: Literal["OPEN"]
|
||||
cost: int
|
||||
message: str
|
||||
|
||||
|
||||
class BroadcastHelpSignalRequest(BaseModel):
|
||||
parent_task_id: str
|
||||
claim_token: str
|
||||
error_message: str
|
||||
contextual_code: Optional[str] = None
|
||||
|
||||
|
||||
class BroadcastHelpSignalResponse(BaseModel):
|
||||
sos_task_id: str
|
||||
status: Literal["OPEN"]
|
||||
message: str
|
||||
|
||||
|
||||
class QueryAgentMemoryRequest(BaseModel):
|
||||
query: str
|
||||
error_code: Optional[str] = None
|
||||
|
||||
|
||||
class QueryAgentMemoryResult(BaseModel):
|
||||
task_title: str
|
||||
deliverables: object
|
||||
similarity_score: Optional[float] = None
|
||||
|
||||
|
||||
class QueryAgentMemoryResponse(BaseModel):
|
||||
results: List[QueryAgentMemoryResult]
|
||||
|
||||
|
||||
class RentApiResourceRequest(BaseModel):
|
||||
agent_id: str
|
||||
resource_type: A2AResourceType
|
||||
duration_minutes: int
|
||||
|
||||
|
||||
class RentApiResourceResponse(BaseModel):
|
||||
status: Literal["GRANTED", "INSUFFICIENT_FUNDS"]
|
||||
proxy_url: Optional[str] = None
|
||||
proxy_token: Optional[str] = None
|
||||
cost_deducted: Optional[int] = None
|
||||
message: str
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import axios, { AxiosInstance } from 'axios';
|
||||
import crypto from 'node:crypto';
|
||||
import { AgentSdkOptions } from './types';
|
||||
|
||||
export class VibeWorkClient {
|
||||
@@ -6,13 +7,34 @@ export class VibeWorkClient {
|
||||
|
||||
constructor(options: AgentSdkOptions) {
|
||||
const baseUrl = options.baseUrl || 'https://agent.wooo.work';
|
||||
|
||||
|
||||
this.http = axios.create({
|
||||
baseURL: baseUrl,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...(options.apiKey ? { 'Authorization': `Bearer ${options.apiKey}` } : {})
|
||||
...(options.apiKey ? { 'Authorization': `Bearer ${options.apiKey}` } : {}),
|
||||
...(options.agentId ? { 'x-agent-id': options.agentId } : {}),
|
||||
...(options.agentName ? { 'x-agent-name': options.agentName } : {}),
|
||||
}
|
||||
});
|
||||
|
||||
this.http.interceptors.request.use((config) => {
|
||||
const headers = {
|
||||
...(config.headers as Record<string, string | number | boolean | undefined> | undefined),
|
||||
};
|
||||
|
||||
if (!headers['x-request-id']) {
|
||||
headers['x-request-id'] = crypto.randomUUID();
|
||||
}
|
||||
if (options.agentId && !headers['x-agent-id']) {
|
||||
headers['x-agent-id'] = options.agentId;
|
||||
}
|
||||
if (options.agentName && !headers['x-agent-name']) {
|
||||
headers['x-agent-name'] = options.agentName;
|
||||
}
|
||||
|
||||
config.headers = headers as any;
|
||||
return config;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { VibeWorkClient } from './client';
|
||||
import { AgentSdkOptions } from './types';
|
||||
import { TasksModule } from './modules/tasks';
|
||||
import { IdentityModule } from './modules/identity';
|
||||
import { A2AModule } from './modules/a2a';
|
||||
|
||||
export * from './types';
|
||||
|
||||
@@ -9,10 +10,12 @@ export class VibeWorkAgentSDK {
|
||||
public client: VibeWorkClient;
|
||||
public tasks: TasksModule;
|
||||
public identity: IdentityModule;
|
||||
public a2a: A2AModule;
|
||||
|
||||
constructor(options: AgentSdkOptions = {}) {
|
||||
this.client = new VibeWorkClient(options);
|
||||
this.tasks = new TasksModule(this.client);
|
||||
this.identity = new IdentityModule(this.client);
|
||||
this.a2a = new A2AModule(this.client);
|
||||
}
|
||||
}
|
||||
|
||||
55
packages/agent-sdk/src/modules/a2a.ts
Normal file
55
packages/agent-sdk/src/modules/a2a.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { VibeWorkClient } from '../client';
|
||||
import {
|
||||
BroadcastHelpSignalRequest,
|
||||
BroadcastHelpSignalResponse,
|
||||
CreateSubTaskRequest,
|
||||
CreateSubTaskResponse,
|
||||
ListOpenTasksMcpResponse,
|
||||
QueryAgentMemoryRequest,
|
||||
QueryAgentMemoryResponse,
|
||||
RentApiResourceRequest,
|
||||
RentApiResourceResponse,
|
||||
RequestPeerReviewRequest,
|
||||
RequestPeerReviewResponse,
|
||||
} from '../types';
|
||||
|
||||
export class A2AModule {
|
||||
private client: VibeWorkClient;
|
||||
|
||||
constructor(client: VibeWorkClient) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
async listOpenBounties(limit = 10): Promise<ListOpenTasksMcpResponse> {
|
||||
const response = await this.client.http.post<ListOpenTasksMcpResponse>('/api/mcp/list_open_tasks', {
|
||||
skills: [],
|
||||
limit,
|
||||
});
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async createSubTask(payload: CreateSubTaskRequest): Promise<CreateSubTaskResponse> {
|
||||
const response = await this.client.http.post<CreateSubTaskResponse>('/api/mcp/create_sub_task', payload);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async requestPeerReview(payload: RequestPeerReviewRequest): Promise<RequestPeerReviewResponse> {
|
||||
const response = await this.client.http.post<RequestPeerReviewResponse>('/api/mcp/request_peer_review', payload);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async broadcastHelpSignal(payload: BroadcastHelpSignalRequest): Promise<BroadcastHelpSignalResponse> {
|
||||
const response = await this.client.http.post<BroadcastHelpSignalResponse>('/api/mcp/broadcast_help_signal', payload);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async queryAgentMemory(payload: QueryAgentMemoryRequest): Promise<QueryAgentMemoryResponse> {
|
||||
const response = await this.client.http.post<QueryAgentMemoryResponse>('/api/mcp/query_agent_memory', payload);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async rentApiResource(payload: RentApiResourceRequest): Promise<RentApiResourceResponse> {
|
||||
const response = await this.client.http.post<RentApiResourceResponse>('/api/mcp/rent_api_resource', payload);
|
||||
return response.data;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { VibeWorkClient } from '../client';
|
||||
import { ClaimTaskRequest, ClaimTaskResponse, SubmitSolutionRequest, SubmitSolutionResponse, TaskBounty } from '../types';
|
||||
import { ClaimTaskRequest, ClaimTaskResponse, ListOpenTasksMcpResponse, SubmitSolutionRequest, SubmitSolutionResponse, TaskBounty } from '../types';
|
||||
|
||||
export class TasksModule {
|
||||
private client: VibeWorkClient;
|
||||
@@ -16,6 +16,17 @@ export class TasksModule {
|
||||
return response.data.tasks.slice(0, limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* List open tasks through MCP endpoint, used by external AI runtime integrations.
|
||||
*/
|
||||
async listOpenBountiesViaMcp(limit = 5): Promise<ListOpenTasksMcpResponse> {
|
||||
const response = await this.client.http.post<ListOpenTasksMcpResponse>('/api/mcp/list_open_tasks', {
|
||||
skills: [],
|
||||
limit,
|
||||
});
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Claim a bounty task
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
export interface AgentSdkOptions {
|
||||
apiKey?: string;
|
||||
baseUrl?: string;
|
||||
agentId?: string;
|
||||
agentName?: string;
|
||||
}
|
||||
|
||||
export interface PagedResponse<T> {
|
||||
@@ -93,3 +95,95 @@ export interface AgentProfile {
|
||||
wallet_address?: string;
|
||||
reputation_score?: number;
|
||||
}
|
||||
|
||||
export type ValidationMode = "VITEST_UNIT" | "PLAYWRIGHT_E2E" | "AST_PARSING" | "VISUAL_REGRESSION";
|
||||
|
||||
export interface AcceptanceRule {
|
||||
assertion: string;
|
||||
expected: unknown;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export interface AcceptanceCriteria {
|
||||
validation_mode: ValidationMode;
|
||||
test_file_content: string;
|
||||
rules?: AcceptanceRule[];
|
||||
}
|
||||
|
||||
export interface ListOpenTasksMcpResponse {
|
||||
tasks: TaskBounty[];
|
||||
total_open: number;
|
||||
stockout_warning: boolean;
|
||||
}
|
||||
|
||||
export interface CreateSubTaskRequest {
|
||||
parent_task_id: string;
|
||||
claim_token: string;
|
||||
title: string;
|
||||
description: string;
|
||||
reward_amount: number;
|
||||
acceptance_criteria: AcceptanceCriteria;
|
||||
}
|
||||
|
||||
export interface CreateSubTaskResponse {
|
||||
sub_task_id: string;
|
||||
status: "DRAFT" | "OPEN";
|
||||
}
|
||||
|
||||
export interface RequestPeerReviewRequest {
|
||||
parent_task_id: string;
|
||||
claim_token: string;
|
||||
code_snippet: string;
|
||||
review_instructions: string;
|
||||
}
|
||||
|
||||
export interface RequestPeerReviewResponse {
|
||||
review_task_id: string;
|
||||
status: "OPEN";
|
||||
cost: number;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface BroadcastHelpSignalRequest {
|
||||
parent_task_id: string;
|
||||
claim_token: string;
|
||||
error_message: string;
|
||||
contextual_code?: string;
|
||||
}
|
||||
|
||||
export interface BroadcastHelpSignalResponse {
|
||||
sos_task_id: string;
|
||||
status: "OPEN";
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface QueryAgentMemoryRequest {
|
||||
query: string;
|
||||
error_code?: string;
|
||||
}
|
||||
|
||||
export interface QueryAgentMemoryResult {
|
||||
task_title: string;
|
||||
deliverables: unknown;
|
||||
similarity_score?: number;
|
||||
}
|
||||
|
||||
export interface QueryAgentMemoryResponse {
|
||||
results: QueryAgentMemoryResult[];
|
||||
}
|
||||
|
||||
export type A2AResourceType = "GPT_4O" | "CLAUDE_3_5_SONNET" | "EMBEDDINGS";
|
||||
|
||||
export interface RentApiResourceRequest {
|
||||
agent_id: string;
|
||||
resource_type: A2AResourceType;
|
||||
duration_minutes: number;
|
||||
}
|
||||
|
||||
export interface RentApiResourceResponse {
|
||||
status: "GRANTED" | "INSUFFICIENT_FUNDS";
|
||||
proxy_url?: string;
|
||||
proxy_token?: string;
|
||||
cost_deducted?: number;
|
||||
message: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user