571 lines
22 KiB
TypeScript
571 lines
22 KiB
TypeScript
/**
|
||
* @agent-bounty/contracts — Zod Validation Schemas
|
||
*
|
||
* 唯一的驗證真實來源。
|
||
* MCP server、後端 API、前端表單都必須 import 這裡的 schema,
|
||
* 禁止在各自的程式庫中重新定義任何 VibeWork 資料結構。
|
||
*/
|
||
|
||
import { z } from "zod";
|
||
import {
|
||
TaskStatus,
|
||
TaskDifficulty,
|
||
ValidationMode,
|
||
JudgeOverallResult,
|
||
JudgeTestStatus,
|
||
JudgeErrorClassification,
|
||
SettlementPhase,
|
||
SettlementCaptureMode,
|
||
SupportedCurrency,
|
||
LeadStatus,
|
||
AttributionModel,
|
||
TaskErrorClassification,
|
||
MAX_TASK_RETRY_COUNT,
|
||
} from "../enums/index.js";
|
||
|
||
// ─────────────────────────────────────────────
|
||
// 通用基礎型別
|
||
// ─────────────────────────────────────────────
|
||
|
||
const UUIDSchema = z.string().uuid("無效的 UUID 格式");
|
||
const CUIDSchema = z.string().cuid("無效的 CUID 格式");
|
||
const PositiveIntSchema = z.number().int().positive();
|
||
const NonNegativeIntSchema = z.number().int().nonnegative();
|
||
|
||
/** 金額(以最小單位計,例如美分 / 台幣分) */
|
||
const MoneyAmountSchema = z
|
||
.number()
|
||
.int()
|
||
.nonnegative("金額不得為負數")
|
||
.max(1_000_000_00, "單筆金額超過上限($1,000,000)");
|
||
|
||
/** scope_clarity_score:AI 評估任務清晰度,Phase 1 要求 ≥ 0.90 */
|
||
const ScopeScoreSchema = z
|
||
.number()
|
||
.min(0)
|
||
.max(1)
|
||
.refine((v) => v >= 0.9, {
|
||
message: "scope_clarity_score 必須 ≥ 0.90 才能進入主任務池",
|
||
});
|
||
|
||
// ─────────────────────────────────────────────
|
||
// Task 驗收條件 Schema
|
||
// ─────────────────────────────────────────────
|
||
|
||
export const AcceptanceCriteriaSchema = z.object({
|
||
validation_mode: z.enum([
|
||
ValidationMode.VITEST_UNIT,
|
||
ValidationMode.PLAYWRIGHT_E2E,
|
||
ValidationMode.AST_PARSING,
|
||
ValidationMode.VISUAL_REGRESSION,
|
||
]),
|
||
/** 由平台提供的最小測試檔內容(string);Agent 不得修改此欄位 */
|
||
test_file_content: z.string().min(20, "測試檔內容不得為空"),
|
||
/** 關鍵斷言規則(可選,補充說明) */
|
||
rules: z
|
||
.array(
|
||
z.object({
|
||
assertion: z.string(),
|
||
expected: z.unknown(),
|
||
description: z.string().optional(),
|
||
})
|
||
)
|
||
.optional(),
|
||
});
|
||
|
||
// ─────────────────────────────────────────────
|
||
// Task Bounty 核心 Schema(Open Bounty Board)
|
||
// ─────────────────────────────────────────────
|
||
|
||
export const TaskBountySchema = z.object({
|
||
task_id: UUIDSchema,
|
||
title: z.string().min(5).max(120),
|
||
description: z.string().min(20).max(2000),
|
||
status: z.enum([
|
||
TaskStatus.DRAFT,
|
||
TaskStatus.OPEN,
|
||
TaskStatus.EXECUTING,
|
||
TaskStatus.VERIFYING,
|
||
TaskStatus.PENDING_REVIEW,
|
||
TaskStatus.COMPLETED,
|
||
TaskStatus.FAILED,
|
||
TaskStatus.FAILED_RETRYABLE,
|
||
TaskStatus.CANCELLED,
|
||
TaskStatus.DISPUTED,
|
||
TaskStatus.REFUND_PENDING,
|
||
TaskStatus.PAYOUT_READY,
|
||
TaskStatus.PAYOUT_SETTLED,
|
||
TaskStatus.ARCHIVED,
|
||
]),
|
||
difficulty: z.enum([
|
||
TaskDifficulty.HELLO_WORLD,
|
||
TaskDifficulty.COMPONENT,
|
||
TaskDifficulty.VIEW,
|
||
TaskDifficulty.EPIC,
|
||
]),
|
||
/** 最小可行要求 ≥ 0.90 才能進入公開任務池 */
|
||
scope_clarity_score: ScopeScoreSchema,
|
||
error_classification: z.enum([
|
||
TaskErrorClassification.RETRYABLE,
|
||
TaskErrorClassification.NON_RETRYABLE,
|
||
]),
|
||
reward: z.object({
|
||
/** 金額(整數,以最小貨幣單位計:USD cents / TWD 元) */
|
||
amount: MoneyAmountSchema,
|
||
currency: z.enum([
|
||
SupportedCurrency.USD,
|
||
SupportedCurrency.TWD,
|
||
SupportedCurrency.USDC,
|
||
]),
|
||
/** 顯示用格式化金額(例如 "NT$30" / "$1.00"),由後端產生 */
|
||
display_amount: z.string().optional(),
|
||
}),
|
||
acceptance_criteria: AcceptanceCriteriaSchema,
|
||
/** 要求使用的技術棧 */
|
||
required_stack: z.array(z.string()).min(1).default(["React", "Tailwind CSS"]),
|
||
/** 已重試次數 */
|
||
retry_count: NonNegativeIntSchema.max(MAX_TASK_RETRY_COUNT).default(0),
|
||
/** Auth-Hold 的 Stripe payment_intent_id */
|
||
stripe_payment_intent_id: z.string().optional(),
|
||
/** 任務到期時間(對應 Redis TTL) */
|
||
expires_at: z.string().datetime().optional(),
|
||
created_at: z.string().datetime(),
|
||
updated_at: z.string().datetime(),
|
||
});
|
||
|
||
// ─────────────────────────────────────────────
|
||
// claim_task Request/Response
|
||
// ─────────────────────────────────────────────
|
||
|
||
export const ClaimTaskRequestSchema = z.object({
|
||
task_id: UUIDSchema,
|
||
agent_id: z.string().min(1, "必須提供 agent_id 進行白名單驗證"),
|
||
/** Agent 收款錢包(Stripe Connect account 或 EVM 地址) */
|
||
developer_wallet: z
|
||
.string()
|
||
.regex(
|
||
/^(0x[a-fA-F0-9]{40}|acct_[a-zA-Z0-9]+)$/,
|
||
"developer_wallet 必須是有效的 EVM 地址或 Stripe Connect ID"
|
||
),
|
||
});
|
||
|
||
export const ClaimTaskResponseSchema = z.object({
|
||
task_id: UUIDSchema,
|
||
status: z.literal(TaskStatus.EXECUTING),
|
||
/** Stripe Auth-Hold 的金額(供 Agent 確認) */
|
||
held_amount: MoneyAmountSchema,
|
||
held_currency: z.enum([SupportedCurrency.USD, SupportedCurrency.TWD]),
|
||
/** Redis TTL 過期時間 */
|
||
expires_at: z.string().datetime(),
|
||
/** 接案 Agent 的冪等憑證 */
|
||
claim_token: z.string().uuid(),
|
||
});
|
||
|
||
// ─────────────────────────────────────────────
|
||
// submit_solution Request/Response
|
||
// ─────────────────────────────────────────────
|
||
|
||
export const SubmitSolutionRequestSchema = z.object({
|
||
task_id: UUIDSchema,
|
||
/** 接案時取得的冪等憑證,防止重複提交 */
|
||
claim_token: z.string().uuid(),
|
||
deliverables: z.record(z.string(), z.string()),
|
||
/** 必須在目標專案開啟 Pull Request,並提供該 PR 的網址以供人類審核 */
|
||
github_pr_url: z.string().url().optional(),
|
||
});
|
||
|
||
export const SubmitSolutionResponseSchema = z.object({
|
||
task_id: UUIDSchema,
|
||
submission_id: UUIDSchema,
|
||
status: z.literal(TaskStatus.VERIFYING),
|
||
/** Judge 預計完成時間(ISO 8601) */
|
||
estimated_judge_complete_at: z.string().datetime().optional(),
|
||
});
|
||
|
||
// ─────────────────────────────────────────────
|
||
// submit_bid Request/Response
|
||
// ─────────────────────────────────────────────
|
||
|
||
export const SubmitBidRequestSchema = z.object({
|
||
task_id: UUIDSchema,
|
||
agent_id: z.string().min(1).max(120),
|
||
developer_wallet: z
|
||
.string()
|
||
.regex(
|
||
/^(0x[a-fA-F0-9]{40}|acct_[a-zA-Z0-9]+)$/,
|
||
"developer_wallet 必須是有效的 EVM 地址或 Stripe Connect ID"
|
||
)
|
||
.optional(),
|
||
proposed_reward: MoneyAmountSchema.refine((value) => value > 0, {
|
||
message: "proposed_reward 必須大於 0",
|
||
}),
|
||
estimated_duration_hours: z.number().positive().max(24 * 30),
|
||
quality_guarantee: z.string().max(1000).optional(),
|
||
broker_agent_id: z.string().max(120).optional(),
|
||
broker_fee_percentage: z.number().min(0).max(100).optional(),
|
||
});
|
||
|
||
export const SubmitBidResponseSchema = z.object({
|
||
bid_id: UUIDSchema,
|
||
task_id: UUIDSchema,
|
||
status: z.enum(["PENDING", "ACCEPTED", "REJECTED", "NEGOTIATING"]),
|
||
proposed_reward: MoneyAmountSchema,
|
||
});
|
||
|
||
// ─────────────────────────────────────────────
|
||
// create_sub_task Request/Response
|
||
// ─────────────────────────────────────────────
|
||
|
||
export const CreateSubTaskRequestSchema = z.object({
|
||
parent_task_id: UUIDSchema,
|
||
claim_token: z.string().uuid(),
|
||
title: z.string().min(5).max(120),
|
||
description: z.string().min(20).max(2000),
|
||
reward_amount: MoneyAmountSchema,
|
||
acceptance_criteria: AcceptanceCriteriaSchema,
|
||
});
|
||
|
||
export const CreateSubTaskResponseSchema = z.object({
|
||
sub_task_id: UUIDSchema,
|
||
status: z.union([
|
||
z.literal(TaskStatus.DRAFT),
|
||
z.literal(TaskStatus.OPEN),
|
||
]),
|
||
});
|
||
|
||
// ─────────────────────────────────────────────
|
||
// Judge Result Schema(E2B 沙盒回傳)
|
||
// ─────────────────────────────────────────────
|
||
|
||
export const JudgeTestResultSchema = z.object({
|
||
name: z.string(),
|
||
status: z.enum([
|
||
JudgeTestStatus.PASSED,
|
||
JudgeTestStatus.FAILED,
|
||
JudgeTestStatus.SKIPPED,
|
||
]),
|
||
duration_ms: NonNegativeIntSchema,
|
||
logs: z.string().optional(),
|
||
assertion_diff: z.string().optional(),
|
||
});
|
||
|
||
export const JudgeResultSchema = z.object({
|
||
attempt_id: UUIDSchema,
|
||
task_id: UUIDSchema,
|
||
submission_id: UUIDSchema,
|
||
overall_result: z.enum([
|
||
JudgeOverallResult.PASS,
|
||
JudgeOverallResult.FAIL,
|
||
JudgeOverallResult.TIMEOUT,
|
||
]),
|
||
tests: z.array(JudgeTestResultSchema),
|
||
artifacts: z
|
||
.object({
|
||
screenshot_url: z.string().url().optional(),
|
||
logs_url: z.string().url().optional(),
|
||
coverage_summary: z.string().optional(),
|
||
diff_url: z.string().url().optional(),
|
||
})
|
||
.optional(),
|
||
/** 失敗類型(overall_result=fail/timeout 時必填) */
|
||
error_classification: z
|
||
.enum([
|
||
JudgeErrorClassification.TEST_FAIL,
|
||
JudgeErrorClassification.LINT_FAIL,
|
||
JudgeErrorClassification.TIMEOUT,
|
||
JudgeErrorClassification.RESOURCE_EXHAUSTED,
|
||
JudgeErrorClassification.ENVIRONMENT_ERROR,
|
||
JudgeErrorClassification.NETWORK_DENIED,
|
||
JudgeErrorClassification.SANDBOX_CRASH,
|
||
JudgeErrorClassification.TEST_SETUP_FAIL,
|
||
JudgeErrorClassification.ENV_MISCONFIG,
|
||
])
|
||
.optional(),
|
||
/** 供 Builder/Scout 質量分數模型使用的錯誤指紋 */
|
||
error_signature: z.string().optional(),
|
||
/** 若為 true,後端可以安排重試(不計入 Agent 失敗分數) */
|
||
retryable: z.boolean(),
|
||
resource_usage: z.object({
|
||
cpu_ms: NonNegativeIntSchema,
|
||
mem_peak_mb: NonNegativeIntSchema,
|
||
io_bytes: NonNegativeIntSchema,
|
||
}),
|
||
judge_completed_at: z.string().datetime(),
|
||
});
|
||
|
||
// ─────────────────────────────────────────────
|
||
// Settlement Ledger Schema(對帳台帳)
|
||
// ─────────────────────────────────────────────
|
||
|
||
export const SettlementLedgerEntrySchema = z.object({
|
||
id: CUIDSchema,
|
||
task_id: UUIDSchema,
|
||
agent_id: z.string(),
|
||
human_client_id: z.string(),
|
||
/** Stripe 冪等 key:格式 "{task_id}_{phase}_{attempt}" */
|
||
idempotency_key: z.string().min(10).max(255),
|
||
phase: z.enum([
|
||
SettlementPhase.AUTH_HOLD,
|
||
SettlementPhase.CAPTURE,
|
||
SettlementPhase.RELEASE,
|
||
SettlementPhase.REFUND,
|
||
SettlementPhase.PAYOUT,
|
||
SettlementPhase.DISPUTE,
|
||
SettlementPhase.CORRECTION,
|
||
]),
|
||
capture_mode: z.enum([
|
||
SettlementCaptureMode.STRIPE_AUTH_CAPTURE,
|
||
SettlementCaptureMode.BASE_SMART_CONTRACT,
|
||
]),
|
||
/** Stripe object ID(payment_intent_id / charge_id / refund_id) */
|
||
stripe_object_id: z.string().optional(),
|
||
amount: MoneyAmountSchema,
|
||
currency: z.enum([SupportedCurrency.USD, SupportedCurrency.TWD]),
|
||
request_payload_hash: z.string(),
|
||
response_status: z.string(),
|
||
http_status: z.number().int().min(100).max(599),
|
||
attempt: PositiveIntSchema,
|
||
source: z.enum(["api", "webhook", "manual_replay"]),
|
||
/** 分潤快照(capture 時寫入,不得事後修改) */
|
||
split: z
|
||
.object({
|
||
platform_amount: MoneyAmountSchema,
|
||
builder_amount: MoneyAmountSchema,
|
||
scout_amount: MoneyAmountSchema.optional(),
|
||
platform_rate: z.number().min(0).max(1),
|
||
builder_rate: z.number().min(0).max(1),
|
||
scout_rate: z.number().min(0).max(1).optional(),
|
||
})
|
||
.optional(),
|
||
created_at: z.string().datetime(),
|
||
updated_at: z.string().datetime(),
|
||
});
|
||
|
||
// ─────────────────────────────────────────────
|
||
// Scout Draft / Lead Schemas
|
||
// ─────────────────────────────────────────────
|
||
|
||
export const ScoutDraftRequestSchema = z.object({
|
||
scout_id: z.string().min(1, "必須提供 scout_id 進行歸因"),
|
||
title: z.string().min(5).max(120),
|
||
description: z.string().min(20).max(2000),
|
||
reward_amount: MoneyAmountSchema,
|
||
reward_currency: z.enum([SupportedCurrency.USD, SupportedCurrency.TWD]),
|
||
required_stack: z.array(z.string()).default(["React", "Tailwind CSS"]),
|
||
test_file_content: z.string().min(20, "必須提供測試檔以便自動驗收"),
|
||
});
|
||
|
||
export const ScoutDraftResponseSchema = z.object({
|
||
task_id: UUIDSchema,
|
||
checkout_url: z.string().url(),
|
||
status: z.union([
|
||
z.literal(TaskStatus.DRAFT),
|
||
z.literal(TaskStatus.OPEN),
|
||
]),
|
||
});
|
||
|
||
export const LeadSchema = z.object({
|
||
lead_id: UUIDSchema,
|
||
scout_agent_id: z.string().optional(),
|
||
/** Scout 的 affiliate token,用於歸因 */
|
||
affiliate_token: z.string().uuid().optional(),
|
||
attribution_model: z.enum([
|
||
AttributionModel.LAST_CLICK,
|
||
AttributionModel.FIRST_CLICK,
|
||
AttributionModel.LINEAR,
|
||
]),
|
||
status: z.enum([
|
||
LeadStatus.DRAFT,
|
||
LeadStatus.CONFIRMED,
|
||
LeadStatus.PAYMENT_AUTHORIZED,
|
||
LeadStatus.TASK_CREATED,
|
||
LeadStatus.EXPIRED,
|
||
LeadStatus.CANCELLED,
|
||
]),
|
||
/** 需求者原始需求(純文字,不超過 500 字) */
|
||
raw_requirement: z.string().min(10).max(500),
|
||
/** AI 生成的 PRD 草稿(JSON) */
|
||
prd_draft: z.record(z.string(), z.unknown()).optional(),
|
||
/** 付款連結(Stripe Checkout URL) */
|
||
payment_link: z.string().url().optional(),
|
||
/** 付款連結 TTL 過期時間 */
|
||
payment_link_expires_at: z.string().datetime().optional(),
|
||
/** 成功後建立的正式 task_id */
|
||
task_id: UUIDSchema.optional(),
|
||
created_at: z.string().datetime(),
|
||
updated_at: z.string().datetime(),
|
||
});
|
||
|
||
// ─────────────────────────────────────────────
|
||
// list_open_tasks Response Schema
|
||
// ─────────────────────────────────────────────
|
||
|
||
export const ListOpenTasksRequestSchema = z.object({
|
||
skills: z
|
||
.array(z.string().min(1).max(50))
|
||
.default([]),
|
||
limit: z.number().int().min(1).max(20).default(5),
|
||
difficulty: z
|
||
.enum([
|
||
TaskDifficulty.HELLO_WORLD,
|
||
TaskDifficulty.COMPONENT,
|
||
TaskDifficulty.VIEW,
|
||
TaskDifficulty.EPIC,
|
||
])
|
||
.optional(),
|
||
});
|
||
|
||
/** 精簡版 Task(list 用,避免暴露內部欄位) */
|
||
export const TaskSummarySchema = TaskBountySchema.pick({
|
||
task_id: true,
|
||
title: true,
|
||
status: true,
|
||
difficulty: true,
|
||
reward: true,
|
||
required_stack: true,
|
||
scope_clarity_score: true,
|
||
created_at: true,
|
||
}).extend({
|
||
description_preview: z.string().max(200),
|
||
});
|
||
|
||
export const ListOpenTasksResponseSchema = z.object({
|
||
tasks: z.array(TaskSummarySchema),
|
||
total_open: z.number().int().nonnegative(),
|
||
/** 任務池是否告警(供 MCP client 顯示警示) */
|
||
stockout_warning: z.boolean(),
|
||
});
|
||
|
||
// ─────────────────────────────────────────────
|
||
// fetch_github_repo_structure Request Schema (Trojan Horse Tool)
|
||
// ─────────────────────────────────────────────
|
||
|
||
export const FetchGithubRepoStructureSchema = z.object({
|
||
owner: z.string().min(1, "Repository owner is required"),
|
||
repo: z.string().min(1, "Repository name is required"),
|
||
});
|
||
|
||
// ─────────────────────────────────────────────
|
||
// request_peer_review Request/Response
|
||
// ─────────────────────────────────────────────
|
||
export const RequestPeerReviewRequestSchema = z.object({
|
||
parent_task_id: UUIDSchema,
|
||
claim_token: z.string().uuid(),
|
||
code_snippet: z.string().min(10, "Code snippet is required"),
|
||
review_instructions: z.string().min(10, "Review instructions are required"),
|
||
});
|
||
|
||
export const RequestPeerReviewResponseSchema = z.object({
|
||
review_task_id: UUIDSchema,
|
||
status: z.literal(TaskStatus.OPEN),
|
||
cost: MoneyAmountSchema,
|
||
message: z.string(),
|
||
});
|
||
|
||
// ─────────────────────────────────────────────
|
||
// broadcast_help_signal Request/Response
|
||
// ─────────────────────────────────────────────
|
||
export const BroadcastHelpSignalRequestSchema = z.object({
|
||
parent_task_id: UUIDSchema,
|
||
claim_token: z.string().uuid(),
|
||
error_message: z.string().min(5),
|
||
contextual_code: z.string().optional(),
|
||
});
|
||
|
||
export const BroadcastHelpSignalResponseSchema = z.object({
|
||
sos_task_id: UUIDSchema,
|
||
status: z.literal(TaskStatus.OPEN),
|
||
message: z.string(),
|
||
});
|
||
|
||
// ─────────────────────────────────────────────
|
||
// query_agent_memory Request/Response
|
||
// ─────────────────────────────────────────────
|
||
export const QueryAgentMemoryRequestSchema = z.object({
|
||
query: z.string().min(3),
|
||
error_code: z.string().optional(),
|
||
});
|
||
|
||
export const QueryAgentMemoryResponseSchema = z.object({
|
||
results: z.array(z.object({
|
||
task_title: z.string(),
|
||
deliverables: z.unknown(),
|
||
similarity_score: z.number().optional(),
|
||
})),
|
||
});
|
||
|
||
// ─────────────────────────────────────────────
|
||
// negotiate_bounty Request/Response
|
||
// ─────────────────────────────────────────────
|
||
export const NegotiateBountyRequestSchema = z.object({
|
||
task_id: UUIDSchema,
|
||
agent_id: z.string().min(1, "必須提供 agent_id 進行白名單驗證"),
|
||
requested_amount: MoneyAmountSchema,
|
||
reasoning: z.string().min(10, "Reasoning is required for negotiation"),
|
||
});
|
||
|
||
export const NegotiateBountyResponseSchema = z.object({
|
||
task_id: UUIDSchema,
|
||
status: z.enum(["APPROVED", "REJECTED", "PENDING_HUMAN_REVIEW"]),
|
||
new_amount: MoneyAmountSchema.optional(),
|
||
message: z.string(),
|
||
});
|
||
|
||
// ─────────────────────────────────────────────
|
||
// rent_api_resource Request/Response
|
||
// ─────────────────────────────────────────────
|
||
export const RentApiResourceRequestSchema = z.object({
|
||
agent_id: z.string(),
|
||
resource_type: z.enum(["GPT_4O", "CLAUDE_3_5_SONNET", "EMBEDDINGS"]),
|
||
duration_minutes: z.number().min(1).max(60).default(5),
|
||
});
|
||
|
||
export const RentApiResourceResponseSchema = z.object({
|
||
status: z.enum(["GRANTED", "INSUFFICIENT_FUNDS"]),
|
||
proxy_url: z.string().optional(),
|
||
proxy_token: z.string().optional(),
|
||
cost_deducted: z.number().optional(),
|
||
message: z.string(),
|
||
});
|
||
|
||
// ─────────────────────────────────────────────
|
||
// create_bounty Request/Response
|
||
// ─────────────────────────────────────────────
|
||
export const CreateBountyRequestSchema = z.object({
|
||
agent_id: z.string().min(1, "必須提供發包者的 agent_id"),
|
||
title: z.string().min(5).max(120),
|
||
description: z.string().min(20).max(2000),
|
||
reward_amount: MoneyAmountSchema,
|
||
reward_currency: z.enum([SupportedCurrency.USD, SupportedCurrency.TWD]).default(SupportedCurrency.USD),
|
||
required_stack: z.array(z.string()).default(["TypeScript", "AI"]),
|
||
test_file_content: z.string().default("// Default A2A Verification Stub"),
|
||
});
|
||
|
||
export const CreateBountyResponseSchema = z.object({
|
||
task_id: UUIDSchema,
|
||
status: z.literal(TaskStatus.OPEN),
|
||
message: z.string(),
|
||
});
|
||
|
||
// ─────────────────────────────────────────────
|
||
// Agent Card Schema (2026 Discovery Standard)
|
||
// ─────────────────────────────────────────────
|
||
export const AgentCardSchema = z.object({
|
||
agent_id: z.string().min(1),
|
||
name: z.string().min(2).max(100),
|
||
description: z.string().max(1000).optional(),
|
||
supported_models: z.array(z.string()).default(["gpt-4o"]),
|
||
skills: z.array(z.string()).min(1),
|
||
max_concurrent_tasks: z.number().int().min(1).max(100).default(5),
|
||
x402_wallet_address: z.string().optional(),
|
||
});
|
||
|
||
export const RegisterAgentCardRequestSchema = z.object({
|
||
card: AgentCardSchema,
|
||
});
|
||
|
||
export const RegisterAgentCardResponseSchema = z.object({
|
||
status: z.literal("SUCCESS"),
|
||
message: z.string(),
|
||
});
|