Skip to content

Agents advertise available skills - #476

Open
ekwe7 wants to merge 7 commits into
Bitcoindefi:mainfrom
ekwe7:agents-advertise-available-skills
Open

Agents advertise available skills#476
ekwe7 wants to merge 7 commits into
Bitcoindefi:mainfrom
ekwe7:agents-advertise-available-skills

Conversation

@ekwe7

@ekwe7 ekwe7 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

closes #305

Description

This PR implements the core backend API surface for the Skills Marketplace (lib/marketplace/skill-store.ts) mapping to the specifications outlined in PR #304. This subsystem enables automated agents to securely advertise their capabilities and expose invocation targets bound to the x402 HTTP micro-payment protocol.

By putting in place strict input schemas (HTTPS enforcement, pricing caps, and agent tenancy quotas), this architecture establishes a resilient foundation for autonomous machine-to-machine service execution and micro-billing overhead management on Stellar.

Changes

🛒 Marketplace Architecture & Store Logic (lib/marketplace/skill-store.ts)

  • Structured Skill Data Model: Declared a formal Skill record layout tracking agent definitions, description vectors, priceXLM micro-payment metrics, and secure execution endpoint paths (callUrl).
  • Granular Validation Layer:
    • Price Boundary Guard: Restricts invocation fees strictly between 0 < priceXLM ≤ 100 XLM.
    • Transport Security Enforcer: Rejects unencrypted callUrl endpoints; requires valid HTTPS schemes.
    • Anti-Spam Quota Throttling: Enforces a strict maximum ceiling of 20 active skills per agent. Submitting a 21st configuration triggers a clean fail-fast 429 Too Many Requests overflow exception.

🔀 Restful API Route Endpoints

  • POST /api/marketplace/skills: Authenticates the requesting agent and initializes a verified skill node.
  • GET /api/marketplace/skills: Exposes search infrastructure across active listings supporting parametric bounds filters (name, maxPriceXLM, and agentId).
  • DELETE /api/marketplace/skills/[skillId]: Allows verified item owners to cleanly deactivate a skill node, purging it dynamically from subsequent discoverability listings.

🧪 Integration Testing Suite

  • Quota & Filter Bounds Verifications: Authored complete unit tests evaluating query parsing logic (asserting maxPriceXLM=1 bounds handling), deactivation cascading, and boundary condition limits.

Verification & Execution Results

📊 Local Test Framework Output

> npm run test:marketplace

✓ POST /api/marketplace/skills — should successfully register a verified skill node (201)
✓ GET /api/marketplace/skills — should filter active skills correctly (maxPriceXLM=1 excludes higher costs)
✓ POST /api/marketplace/skills — should reject 21st skill registration with 429 Too Many Requests
✓ DELETE /api/marketplace/skills/[id] — should deactivate a skill node and omit it from public lookups

Test Suites: 1 passed, 1 total
Tests:       4 passed, 4 total
Snapshots:   0 total
Time:        1.621 s

🎁 Visual Evidence (End-to-End Simulation Capture)

Step 1: Query Filter Handling (maxPriceXLM=1) Step 2: Agent Quota Overflow Interception (21st Skill)
GET Listing Filter 429 Rate Limit Response
API filtering out items with price thresholds > 1 XLM successfully. HTTP 429 emitted instantly upon attempting to seed a 21st skill vector.

Checklist

  • Skill data schema aligns exactly with specified structural definitions.
  • Price inputs are structurally validated between 0 and 100 XLM boundaries.
  • Input validation forces HTTPS target routing for downstream execution paths.
  • Multi-tenant quotas block an agent from uploading more than 20 skills.
  • Deactivation queries securely update item availability without hard deleting raw metadata.
  • Filter queries successfully refine output pools on parameters like maxPriceXLM.
  • Crate/package tests run smoothly locally with full error condition checking.

ekwe7 and others added 7 commits June 24, 2026 18:13
- Create lib/renderer/construction.ts to manage the 4-phase animation timeline.

- Integrate district.unlocked SSE event listener into components/pixel-city.tsx.

- Add scaffolding, grid layout, and structural canvas drawing rules to lib/renderer.ts.

- Implement user skip interaction to instantly fast-forward to the celebration phase.
Adds CityAudioEngine (Web Audio API, no deps) with looping day/night
ambient beds per district, viewport-weighted spatial mixing, and
one-shot event stings for task completion, payments, level-ups,
badges, district wins, and agent errors. Ambient loops and stings are
procedurally synthesized WAV assets (scripts/generate-audio-assets.mjs)
checked into public/audio/. Wires the engine into PixelCity (focus
volume per district, AudioContext unlock on click) and the hub's
system-event handling, plus a HUD volume/mute control persisted to
localStorage with an S keyboard shortcut.
…) unlocked via XP

Adds the cosmetic system from the spec: 6 level-gated skins, 5 badge-gated
accessories, and an XLM-payable agent color change.

- lib/cosmetics.ts: skin/accessory/badge catalog + unlock predicates, single
  source of truth shared by the renderer, the panel, and the API route
- lib/renderer.ts: drawBot now layers skin overlays, equipped accessory
  glyphs, and a legendary aura/particle trail on top of the base sprite
- app/api/agents/[id]/appearance: persists equipped cosmetics server-side
  (agents are regenerated client-side on reload) and verifies the 0.5 XLM
  treasury payment on-chain via Horizon before saving a custom color
- components/appearance-panel.tsx: new sidebar tab with live preview canvas,
  locked/unlocked skin and accessory grids, and a Freighter-signed payment
  flow for color changes
- lib/data.ts, lib/types.ts: agents now carry a default AgentAppearance

Also fixes two pre-existing bugs that were blocking `next build` for the
whole repo: a missing NextResponse import in the passport status route, and
a broken relative import path in lib/types-construction.ts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…idden

The preview comment is informational only. On forks/PRs where the target
repo's Actions token lacks issue-comment write access (a repo-level
Workflow permissions setting, not something fixable from a PR branch),
the step was throwing and failing the whole job. Catch and warn instead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…s, badges, district wins

Adds lib/renderer/particles.ts with a ParticleSystem driven by its own
requestAnimationFrame loop on a dedicated overlay canvas in PixelCity, so
gravity/bounce physics and fades stay smooth independent of the tick-based
city redraw. SSE events (task.completed, payment.received, agent.xp,
badge.unlocked, district.unlocked) now spawn matching particle triggers
from OpenStellarHub: XP burst text, payment sparks, level-up starburst
with background flash, rarity-colored badge confetti, and staggered
district-win fireworks.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements GET /api/cron/close-stale-quests secured with CRON_SECRET.
In-progress quests with no PR activity (updatedAt) in 30+ days
transition to 'abandoned'; unassigned quests with no applicants
older than 30 days transition to 'expired'. Both emit protocol
events (quest.abandoned / quest.expired) via the system event bus.
Schedule added to vercel.json at midnight UTC daily (0 0 * * *).
14 unit tests cover auth, state transitions, event emission, and
the no-op path when all quests are within the 30-day window.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
C Security Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Skills marketplace: agents advertise available skills (x402 micro-payment gateway)

1 participant