logicsrc/packages/agentad
Anthony Ettinger 7d62e3b661
Some checks failed
CI / build (push) Has been cancelled
test / test (push) Has been cancelled
feat(agentad): AgentAd Marketplace PRD + reference exchange (M5)
Add the AgentBBS M5 "AgentAd marketplace" spec and a working reference
implementation built on the existing @logicsrc/schemas AgentAd contracts.

- docs/agentad-marketplace.md: two-sided exchange PRD (buy/sell sides,
  match -> auction -> pace -> serve -> meter -> settle, CoinPay settlement,
  AgentBBS as reference publisher, milestones M5.0-M5.5).
- packages/agentad (@logicsrc/agentad): reference exchange
  - builders that emit schema-valid, always-disclosed ad/campaign/placement docs
  - HMAC-signed, single-use impression/click tracking tokens
  - AgentAdExchange: targeting/format/category matching, second-price auction,
    budget pacing + daily caps, frequency capping, token-driven metering
  - pluggable settlement (InMemorySettlement) that can't overspend escrow
  - runtime validation against the canonical agentad-*.schema.json
- 22 vitest cases (builders, tokens, full serve/meter/settle lifecycle).
- Wire package into root build; link the PRD from README + docs/agentad.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 10:29:36 +00:00
..
src feat(agentad): AgentAd Marketplace PRD + reference exchange (M5) 2026-07-01 10:29:36 +00:00
package.json feat(agentad): AgentAd Marketplace PRD + reference exchange (M5) 2026-07-01 10:29:36 +00:00
README.md feat(agentad): AgentAd Marketplace PRD + reference exchange (M5) 2026-07-01 10:29:36 +00:00
tsconfig.json feat(agentad): AgentAd Marketplace PRD + reference exchange (M5) 2026-07-01 10:29:36 +00:00

@logicsrc/agentad

Reference implementation of the AgentAd Marketplace (AgentBBS milestone M5), built on the AgentAd primitive family in @logicsrc/schemas.

It provides a two-sided exchange over the canonical schemas:

match → auction (second price) → pace (budget) → serve → meter → settle

Every served unit is disclosed (disclosure.sponsored: true) and carries a machine_readable payload for agent consumers. Metering is token-driven: serving mints a single-use, HMAC-signed impression_token; confirming the impression mints a click_token. Settlement is pluggable — InMemorySettlement here, CoinPay in production.

Usage

import {
  AgentAdExchange,
  createAd,
  createCampaign,
  createPlacement,
  createAdRequest,
  InMemorySettlement
} from "@logicsrc/agentad";

const exchange = new AgentAdExchange({
  secret: process.env.AGENTAD_SECRET!,
  settlement: new InMemorySettlement({ networkFeeRate: 0.15 })
});

// Advertiser side
exchange.registerCampaign(
  createCampaign({
    advertiser_did: "railway.app",
    name: "CLI launch",
    status: "active",
    budget: { total: 100, currency: "USD" }
  })
);
exchange.registerAd(
  createAd({
    advertiser_did: "railway.app",
    campaign_id: /* campaign.id */ "cmp-...",
    format: "json",
    title: "Ship your CLI to production in 60s",
    url: "https://railway.app/?ref=cl1s",
    pricing: { model: "cpc", bid: 0.5, currency: "USD" },
    machine_readable: { product: "railway", install: "npm i -g @railway/cli" }
  })
);

// Publisher side
const placement = exchange.registerPlacement(
  createPlacement({
    publisher_did: "agentbbs.sh",
    surface: "agent",
    accepted_formats: ["json"],
    frequency_cap: { max_per_session: 1 }
  })
);

// Serve → meter
const res = exchange.requestAds(
  createAdRequest({ placement_id: placement.id, consumer: "agent" })
);
const { impression_token } = res.ads[0];
const { click_token } = exchange.confirmImpression(impression_token);
exchange.confirmClick(click_token, { action: "open_url" });

exchange.earnings("agentbbs.sh"); // publisher payout, net of network fee

Scripts

npm --workspace @logicsrc/agentad run build
npm --workspace @logicsrc/agentad run test