mirror of
https://github.com/profullstack/logicsrc.git
synced 2026-08-13 14:37:26 +00:00
Add AgentAd ad schemas as a LogicSRC primitive (#10)
* Add AgentAd ad schemas as a LogicSRC primitive
AgentAd is a disclosed, agent-readable advertising contract for CLI tools
and AI agents. LogicSRC owns the canonical schemas; cl1s.tech is the
reference network built on them.
- packages/schemas: agentad-{ad,placement,ad-request,ad-response,
impression,click,campaign} schemas (id under schemas.logicsrc.com) +
ad/placement fixtures, exported from @logicsrc/schemas
- packages/validators: register the 7 agentad kinds, wire fixture
validation, add tests (disclosure.sponsored must be true)
- docs/agentad.md: the AgentAd spec
- README: list AgentAd under v1 priorities
Validators build clean; all fixtures validate; vitest 4/4 green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Prepare @logicsrc/schemas for npm publish
Add license, repository, homepage, keywords, publishConfig (public),
and a package README covering both the logicsrc-* core schemas and the
agentad-* family.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
ad9f3a2a29
commit
7cda686059
17 changed files with 483 additions and 5 deletions
|
|
@ -54,6 +54,7 @@ It provides read-only resources for docs and schemas, validation/example tools,
|
|||
## v1.0.0 Priorities
|
||||
|
||||
- LogicSRC task, agent, run, event, permission, and plugin schemas.
|
||||
- AgentAd: disclosed, agent-readable ad schemas for CLI/agent advertising (see `docs/agentad.md`); cl1s.tech is the reference network.
|
||||
- LogicSRC CLI, SDK, TUI, PWA, MCP, and curl-compatible API conventions.
|
||||
- CommandBoard.run reference implementation.
|
||||
- Monorepo-maintained plugin system.
|
||||
|
|
|
|||
65
docs/agentad.md
Normal file
65
docs/agentad.md
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
# AgentAd
|
||||
|
||||
AgentAd is a LogicSRC primitive family for advertising to command-line tools and
|
||||
AI agents. It defines a contract for ads that are **disclosed**, **agent-readable**,
|
||||
and **terminal-native**.
|
||||
|
||||
LogicSRC owns the AgentAd schemas; **cl1s.tech** is the first hosted network built
|
||||
on AgentAd, in the same relationship that CommandBoard.run has to the core LogicSRC
|
||||
primitives. External products may consume the AgentAd contracts directly.
|
||||
|
||||
## Principles
|
||||
|
||||
1. **Disclosure is mandatory.** Every ad carries `disclosure.sponsored: true` and a
|
||||
visible label. An AgentAd unit must never be presentable as organic output.
|
||||
2. **Agent-readable.** Ads may carry a `machine_readable` payload so an autonomous
|
||||
agent can reason about the offer instead of scraping rendered text.
|
||||
3. **Terminal-native formats.** `text`, `markdown`, `ansi`, `banner`, `json`.
|
||||
4. **Publisher control.** Placements declare accepted formats, dimensions,
|
||||
frequency caps, and category blocks.
|
||||
|
||||
## Primitives
|
||||
|
||||
| Type | Schema | Validator kind | Purpose |
|
||||
| --- | --- | --- | --- |
|
||||
| `agentad.ad` | `agentad-ad.schema.json` | `agentad-ad` | A single ad unit |
|
||||
| `agentad.placement` | `agentad-placement.schema.json` | `agentad-placement` | A slot in a CLI/agent |
|
||||
| `agentad.ad_request` | `agentad-ad-request.schema.json` | `agentad-ad-request` | Request to fill a placement |
|
||||
| `agentad.ad_response` | `agentad-ad-response.schema.json` | `agentad-ad-response` | Filled ads + tracking tokens |
|
||||
| `agentad.impression` | `agentad-impression.schema.json` | `agentad-impression` | Confirmed display |
|
||||
| `agentad.click` | `agentad-click.schema.json` | `agentad-click` | Click / conversion |
|
||||
| `agentad.campaign` | `agentad-campaign.schema.json` | `agentad-campaign` | Advertiser campaign |
|
||||
|
||||
Schemas are published from `@logicsrc/schemas` and identified under
|
||||
`https://schemas.logicsrc.com/`.
|
||||
|
||||
## Validate
|
||||
|
||||
```bash
|
||||
npm --workspace @logicsrc/validators run build
|
||||
node packages/validators/dist/cli.js agentad-ad packages/schemas/fixtures/agentad-ad.yaml
|
||||
node packages/validators/dist/cli.js agentad-placement packages/schemas/fixtures/agentad-placement.yaml
|
||||
```
|
||||
|
||||
## Human vs. agent consumers
|
||||
|
||||
The `consumer` field on a request changes how an ad is delivered:
|
||||
|
||||
- `human` → rendered string with an `[Sponsored]` header.
|
||||
- `agent` → structured view with an explicit `sponsored: true` flag and the
|
||||
`machine_readable` payload, e.g.
|
||||
|
||||
```json
|
||||
{
|
||||
"sponsored": true,
|
||||
"advertiser": "Railway",
|
||||
"title": "Ship your CLI to production in 60 seconds",
|
||||
"url": "https://railway.app/?ref=cl1s",
|
||||
"data": { "product": "railway", "install": "npm i -g @railway/cli" }
|
||||
}
|
||||
```
|
||||
|
||||
## Reference network
|
||||
|
||||
[cl1s.tech](https://github.com/profullstack/cl1s.tech) is the hosted AgentAd
|
||||
network: SDK, CLI, and ad-serving service that consume these schemas.
|
||||
34
packages/schemas/README.md
Normal file
34
packages/schemas/README.md
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
# @logicsrc/schemas
|
||||
|
||||
Canonical JSON Schemas (draft 2020-12) for the LogicSRC open coordination
|
||||
standards, maintained by Profullstack, Inc.
|
||||
|
||||
Two schema families ship from this package:
|
||||
|
||||
- **LogicSRC core** — `logicsrc-*.schema.json`: tasks, agents, runs, events,
|
||||
plugins, connected accounts, email messages, social posts.
|
||||
- **AgentAd** — `agentad-*.schema.json`: a disclosed, agent-readable advertising
|
||||
contract for CLI tools and AI agents (ads, placements, requests, responses,
|
||||
impressions, clicks, campaigns). See `docs/agentad.md` in the repo;
|
||||
[cl1s.tech](https://github.com/profullstack/cl1s.tech) is the reference network.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm install @logicsrc/schemas
|
||||
```
|
||||
|
||||
## Use
|
||||
|
||||
```js
|
||||
import adSchema from "@logicsrc/schemas/agentad-ad" with { type: "json" };
|
||||
import taskSchema from "@logicsrc/schemas/task" with { type: "json" };
|
||||
```
|
||||
|
||||
Schema `$id`s resolve under `https://schemas.logicsrc.com/`. Validate with any
|
||||
draft 2020-12 validator (e.g. `ajv/dist/2020.js`), or use `@logicsrc/validators`
|
||||
from the monorepo.
|
||||
|
||||
## License
|
||||
|
||||
MIT © Profullstack, Inc.
|
||||
33
packages/schemas/fixtures/agentad-ad.yaml
Normal file
33
packages/schemas/fixtures/agentad-ad.yaml
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
type: agentad.ad
|
||||
version: "0.1"
|
||||
id: deploy-faster-railway
|
||||
campaign_id: railway-q3
|
||||
advertiser_did: railway.coinpay
|
||||
format: markdown
|
||||
title: Ship your CLI to production in 60 seconds
|
||||
body: Railway deploys any Node, Bun, or Go service straight from your terminal. No YAML wrangling.
|
||||
url: https://railway.app/?ref=cl1s
|
||||
cta: Deploy now
|
||||
disclosure:
|
||||
sponsored: true
|
||||
label: Sponsored
|
||||
advertiser_name: Railway
|
||||
machine_readable:
|
||||
product: railway
|
||||
category: infrastructure
|
||||
install: "npm i -g @railway/cli"
|
||||
targeting:
|
||||
surfaces:
|
||||
- cli
|
||||
- agent
|
||||
keywords:
|
||||
- deploy
|
||||
- hosting
|
||||
- infrastructure
|
||||
tools:
|
||||
- claude-code
|
||||
- gh
|
||||
pricing:
|
||||
model: cpc
|
||||
bid: 0.4
|
||||
currency: USDC
|
||||
21
packages/schemas/fixtures/agentad-placement.yaml
Normal file
21
packages/schemas/fixtures/agentad-placement.yaml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
type: agentad.placement
|
||||
version: "0.1"
|
||||
id: cli-footer-slot
|
||||
publisher_did: mytool.coinpay
|
||||
surface: cli
|
||||
accepted_formats:
|
||||
- text
|
||||
- ansi
|
||||
- json
|
||||
dimensions:
|
||||
max_width: 80
|
||||
max_lines: 4
|
||||
context_tags:
|
||||
- devtools
|
||||
- deploy
|
||||
frequency_cap:
|
||||
max_per_session: 1
|
||||
max_per_day: 5
|
||||
block_categories:
|
||||
- gambling
|
||||
- crypto-tokens
|
||||
|
|
@ -1,8 +1,19 @@
|
|||
{
|
||||
"name": "@logicsrc/schemas",
|
||||
"version": "0.1.0",
|
||||
"description": "LogicSRC JSON schemas for tasks, agents, runs, events, and plugins.",
|
||||
"description": "LogicSRC JSON schemas for tasks, agents, runs, events, plugins, and the AgentAd ad standard.",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/profullstack/logicsrc.git",
|
||||
"directory": "packages/schemas"
|
||||
},
|
||||
"homepage": "https://github.com/profullstack/logicsrc/tree/master/packages/schemas",
|
||||
"keywords": ["logicsrc", "agentad", "json-schema", "agents", "cli", "advertising", "standards"],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"exports": {
|
||||
"./task": "./schemas/logicsrc-task.schema.json",
|
||||
"./agent": "./schemas/logicsrc-agent.schema.json",
|
||||
|
|
@ -14,7 +25,14 @@
|
|||
"./account-grant": "./schemas/logicsrc-account-grant.schema.json",
|
||||
"./account-audit-event": "./schemas/logicsrc-account-audit-event.schema.json",
|
||||
"./email-message": "./schemas/logicsrc-email-message.schema.json",
|
||||
"./social-post": "./schemas/logicsrc-social-post.schema.json"
|
||||
"./social-post": "./schemas/logicsrc-social-post.schema.json",
|
||||
"./agentad-ad": "./schemas/agentad-ad.schema.json",
|
||||
"./agentad-placement": "./schemas/agentad-placement.schema.json",
|
||||
"./agentad-ad-request": "./schemas/agentad-ad-request.schema.json",
|
||||
"./agentad-ad-response": "./schemas/agentad-ad-response.schema.json",
|
||||
"./agentad-impression": "./schemas/agentad-impression.schema.json",
|
||||
"./agentad-click": "./schemas/agentad-click.schema.json",
|
||||
"./agentad-campaign": "./schemas/agentad-campaign.schema.json"
|
||||
},
|
||||
"files": [
|
||||
"schemas"
|
||||
|
|
|
|||
32
packages/schemas/schemas/agentad-ad-request.schema.json
Normal file
32
packages/schemas/schemas/agentad-ad-request.schema.json
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://schemas.logicsrc.com/agentad-ad-request.schema.json",
|
||||
"title": "AgentAd Ad Request",
|
||||
"description": "A request from a CLI/agent for an ad to fill a placement, with optional runtime context for relevance.",
|
||||
"type": "object",
|
||||
"required": ["type", "version", "placement_id"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": { "const": "agentad.ad_request" },
|
||||
"version": { "type": "string", "pattern": "^\\d+\\.\\d+(\\.\\d+)?$" },
|
||||
"placement_id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9_-]*$" },
|
||||
"publisher_did": { "type": "string", "pattern": "^[a-z0-9][a-z0-9._-]*\\.[a-z0-9][a-z0-9._-]*$" },
|
||||
"consumer": {
|
||||
"type": "string",
|
||||
"enum": ["human", "agent"],
|
||||
"description": "Who will read the ad. Agents SHOULD receive machine_readable payloads and clear disclosure."
|
||||
},
|
||||
"context": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"tool": { "type": "string", "description": "Host tool identifier, e.g. 'claude-code'." },
|
||||
"keywords": { "type": "array", "items": { "type": "string" }, "uniqueItems": true },
|
||||
"language": { "type": "string" },
|
||||
"locale": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"format_override": { "type": "string", "enum": ["text", "markdown", "ansi", "banner", "json"] },
|
||||
"count": { "type": "integer", "minimum": 1, "maximum": 10, "default": 1 }
|
||||
}
|
||||
}
|
||||
31
packages/schemas/schemas/agentad-ad-response.schema.json
Normal file
31
packages/schemas/schemas/agentad-ad-response.schema.json
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://schemas.logicsrc.com/agentad-ad-response.schema.json",
|
||||
"title": "AgentAd Ad Response",
|
||||
"description": "The network's response to an ad request: zero or more filled ads plus signed tracking tokens for impression/click events.",
|
||||
"type": "object",
|
||||
"required": ["type", "version", "request_id", "ads"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": { "const": "agentad.ad_response" },
|
||||
"version": { "type": "string", "pattern": "^\\d+\\.\\d+(\\.\\d+)?$" },
|
||||
"request_id": { "type": "string", "minLength": 1 },
|
||||
"ads": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["ad", "impression_token"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"ad": { "type": "object", "description": "An agentad.ad document; validate separately against agentad-ad.schema.json." },
|
||||
"impression_token": { "type": "string", "minLength": 1, "description": "Opaque token to confirm the impression and to mint a click token." },
|
||||
"rendered": { "type": "string", "description": "Server-rendered representation in the requested format." }
|
||||
}
|
||||
}
|
||||
},
|
||||
"no_fill_reason": {
|
||||
"type": "string",
|
||||
"enum": ["no_inventory", "frequency_capped", "blocked_category", "invalid_request"]
|
||||
}
|
||||
}
|
||||
}
|
||||
79
packages/schemas/schemas/agentad-ad.schema.json
Normal file
79
packages/schemas/schemas/agentad-ad.schema.json
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://schemas.logicsrc.com/agentad-ad.schema.json",
|
||||
"title": "AgentAd Ad",
|
||||
"description": "A single advertising unit served to CLI tools and AI agents. Ads MUST be disclosed and SHOULD carry a machine-readable payload so agents can reason about them.",
|
||||
"type": "object",
|
||||
"required": ["type", "version", "id", "advertiser_did", "format", "title", "url", "disclosure"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": { "const": "agentad.ad" },
|
||||
"version": { "type": "string", "pattern": "^\\d+\\.\\d+(\\.\\d+)?$" },
|
||||
"id": { "$ref": "#/$defs/id" },
|
||||
"campaign_id": { "$ref": "#/$defs/id" },
|
||||
"advertiser_did": { "$ref": "#/$defs/did" },
|
||||
"format": {
|
||||
"type": "string",
|
||||
"enum": ["text", "markdown", "ansi", "banner", "json"],
|
||||
"description": "Render format. 'json' is the agent-native structured format; 'ansi'/'banner' target human CLI surfaces."
|
||||
},
|
||||
"title": { "type": "string", "minLength": 1, "maxLength": 120 },
|
||||
"body": { "type": "string", "maxLength": 2000 },
|
||||
"url": { "type": "string", "format": "uri" },
|
||||
"cta": { "type": "string", "maxLength": 60, "description": "Call to action label, e.g. 'Install' or 'Read docs'." },
|
||||
"disclosure": {
|
||||
"type": "object",
|
||||
"description": "Transparency contract. Every ad is labeled as sponsored so humans and agents can distinguish it from organic output.",
|
||||
"required": ["sponsored", "label"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"sponsored": { "const": true },
|
||||
"label": { "type": "string", "minLength": 1, "maxLength": 40, "default": "Sponsored" },
|
||||
"advertiser_name": { "type": "string", "maxLength": 120 }
|
||||
}
|
||||
},
|
||||
"machine_readable": {
|
||||
"type": "object",
|
||||
"description": "Optional structured payload an agent can parse instead of (or alongside) the rendered text.",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"targeting": { "$ref": "#/$defs/targeting" },
|
||||
"media": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"ansi_art": { "type": "string", "description": "Pre-rendered ANSI/ASCII art for banner format." },
|
||||
"icon": { "type": "string", "format": "uri" }
|
||||
}
|
||||
},
|
||||
"pricing": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"model": { "type": "string", "enum": ["cpm", "cpc", "cpa", "flat"] },
|
||||
"bid": { "type": "number", "minimum": 0 },
|
||||
"currency": { "type": "string", "minLength": 2, "maxLength": 12 }
|
||||
}
|
||||
},
|
||||
"expires_at": { "type": "string", "format": "date-time" }
|
||||
},
|
||||
"$defs": {
|
||||
"id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9_-]*$", "minLength": 1, "maxLength": 64 },
|
||||
"did": { "type": "string", "pattern": "^[a-z0-9][a-z0-9._-]*\\.[a-z0-9][a-z0-9._-]*$" },
|
||||
"targeting": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"surfaces": {
|
||||
"type": "array",
|
||||
"items": { "type": "string", "enum": ["cli", "tui", "agent", "ci"] },
|
||||
"uniqueItems": true
|
||||
},
|
||||
"keywords": { "type": "array", "items": { "type": "string", "minLength": 1 }, "uniqueItems": true },
|
||||
"tools": { "type": "array", "items": { "type": "string", "minLength": 1 }, "uniqueItems": true, "description": "Host CLI/agent identifiers to target, e.g. 'claude-code', 'gh'." },
|
||||
"languages": { "type": "array", "items": { "type": "string" }, "uniqueItems": true },
|
||||
"exclude_keywords": { "type": "array", "items": { "type": "string" }, "uniqueItems": true }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
40
packages/schemas/schemas/agentad-campaign.schema.json
Normal file
40
packages/schemas/schemas/agentad-campaign.schema.json
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://schemas.logicsrc.com/agentad-campaign.schema.json",
|
||||
"title": "AgentAd Campaign",
|
||||
"description": "An advertiser campaign grouping one or more ads under a shared budget, schedule, and targeting policy.",
|
||||
"type": "object",
|
||||
"required": ["type", "version", "id", "advertiser_did", "name", "budget"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": { "const": "agentad.campaign" },
|
||||
"version": { "type": "string", "pattern": "^\\d+\\.\\d+(\\.\\d+)?$" },
|
||||
"id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9_-]*$", "minLength": 1, "maxLength": 64 },
|
||||
"advertiser_did": { "type": "string", "pattern": "^[a-z0-9][a-z0-9._-]*\\.[a-z0-9][a-z0-9._-]*$" },
|
||||
"name": { "type": "string", "minLength": 1, "maxLength": 120 },
|
||||
"status": { "type": "string", "enum": ["draft", "active", "paused", "completed"], "default": "draft" },
|
||||
"budget": {
|
||||
"type": "object",
|
||||
"required": ["total", "currency"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"total": { "type": "number", "minimum": 0 },
|
||||
"daily_cap": { "type": "number", "minimum": 0 },
|
||||
"currency": { "type": "string", "minLength": 2, "maxLength": 12 }
|
||||
}
|
||||
},
|
||||
"schedule": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"start_at": { "type": "string", "format": "date-time" },
|
||||
"end_at": { "type": "string", "format": "date-time" }
|
||||
}
|
||||
},
|
||||
"ad_ids": {
|
||||
"type": "array",
|
||||
"items": { "type": "string", "pattern": "^[a-z0-9][a-z0-9_-]*$" },
|
||||
"uniqueItems": true
|
||||
}
|
||||
}
|
||||
}
|
||||
23
packages/schemas/schemas/agentad-click.schema.json
Normal file
23
packages/schemas/schemas/agentad-click.schema.json
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://schemas.logicsrc.com/agentad-click.schema.json",
|
||||
"title": "AgentAd Click",
|
||||
"description": "A consumer action on an ad (a click, install, or conversion). For agents, 'action' records the structured intent taken.",
|
||||
"type": "object",
|
||||
"required": ["type", "version", "click_token", "ad_id", "occurred_at"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": { "const": "agentad.click" },
|
||||
"version": { "type": "string", "pattern": "^\\d+\\.\\d+(\\.\\d+)?$" },
|
||||
"click_token": { "type": "string", "minLength": 1 },
|
||||
"ad_id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9_-]*$" },
|
||||
"placement_id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9_-]*$" },
|
||||
"action": {
|
||||
"type": "string",
|
||||
"enum": ["click", "open_url", "copy_command", "install", "convert"],
|
||||
"default": "click"
|
||||
},
|
||||
"consumer": { "type": "string", "enum": ["human", "agent"] },
|
||||
"occurred_at": { "type": "string", "format": "date-time" }
|
||||
}
|
||||
}
|
||||
18
packages/schemas/schemas/agentad-impression.schema.json
Normal file
18
packages/schemas/schemas/agentad-impression.schema.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://schemas.logicsrc.com/agentad-impression.schema.json",
|
||||
"title": "AgentAd Impression",
|
||||
"description": "A confirmed display of an ad. Recorded only after the ad was actually rendered to the consumer.",
|
||||
"type": "object",
|
||||
"required": ["type", "version", "impression_token", "ad_id", "occurred_at"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": { "const": "agentad.impression" },
|
||||
"version": { "type": "string", "pattern": "^\\d+\\.\\d+(\\.\\d+)?$" },
|
||||
"impression_token": { "type": "string", "minLength": 1 },
|
||||
"ad_id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9_-]*$" },
|
||||
"placement_id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9_-]*$" },
|
||||
"consumer": { "type": "string", "enum": ["human", "agent"] },
|
||||
"occurred_at": { "type": "string", "format": "date-time" }
|
||||
}
|
||||
}
|
||||
46
packages/schemas/schemas/agentad-placement.schema.json
Normal file
46
packages/schemas/schemas/agentad-placement.schema.json
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://schemas.logicsrc.com/agentad-placement.schema.json",
|
||||
"title": "AgentAd Placement",
|
||||
"description": "A slot registered by a publisher (a CLI tool or agent) where AgentAd units may be rendered.",
|
||||
"type": "object",
|
||||
"required": ["type", "version", "id", "publisher_did", "surface", "accepted_formats"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": { "const": "agentad.placement" },
|
||||
"version": { "type": "string", "pattern": "^\\d+\\.\\d+(\\.\\d+)?$" },
|
||||
"id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9_-]*$", "minLength": 1, "maxLength": 64 },
|
||||
"publisher_did": { "type": "string", "pattern": "^[a-z0-9][a-z0-9._-]*\\.[a-z0-9][a-z0-9._-]*$" },
|
||||
"surface": { "type": "string", "enum": ["cli", "tui", "agent", "ci"] },
|
||||
"accepted_formats": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": { "type": "string", "enum": ["text", "markdown", "ansi", "banner", "json"] },
|
||||
"uniqueItems": true
|
||||
},
|
||||
"dimensions": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"max_width": { "type": "integer", "minimum": 1, "description": "Max columns for text/ansi rendering." },
|
||||
"max_lines": { "type": "integer", "minimum": 1 }
|
||||
}
|
||||
},
|
||||
"context_tags": {
|
||||
"type": "array",
|
||||
"items": { "type": "string", "minLength": 1 },
|
||||
"uniqueItems": true,
|
||||
"description": "Keywords describing the host context, used for relevance matching."
|
||||
},
|
||||
"frequency_cap": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"max_per_session": { "type": "integer", "minimum": 0 },
|
||||
"max_per_day": { "type": "integer", "minimum": 0 }
|
||||
}
|
||||
},
|
||||
"allow_categories": { "type": "array", "items": { "type": "string" }, "uniqueItems": true },
|
||||
"block_categories": { "type": "array", "items": { "type": "string" }, "uniqueItems": true }
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
"scripts": {
|
||||
"build": "tsc -p tsconfig.json",
|
||||
"test": "vitest run src",
|
||||
"validate:fixtures": "node dist/cli.js task ../schemas/fixtures/task.yaml && node dist/cli.js agent ../schemas/fixtures/agent.yaml"
|
||||
"validate:fixtures": "node dist/cli.js task ../schemas/fixtures/task.yaml && node dist/cli.js agent ../schemas/fixtures/agent.yaml && node dist/cli.js agentad-ad ../schemas/fixtures/agentad-ad.yaml && node dist/cli.js agentad-placement ../schemas/fixtures/agentad-placement.yaml"
|
||||
},
|
||||
"dependencies": {
|
||||
"ajv": "^8.17.1",
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ function main(argv: string[]) {
|
|||
const [, , kindArg, fileArg] = argv;
|
||||
|
||||
if (!kindArg || !fileArg) {
|
||||
console.error("Usage: logicsrc-validate <task|agent|run|event|plugin> <file.yaml|file.json>");
|
||||
console.error("Usage: logicsrc-validate <task|agent|run|event|plugin|agentad-ad|agentad-placement|...> <file.yaml|file.json>");
|
||||
process.exitCode = 2;
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,4 +25,27 @@ describe("LogicSRC validators", () => {
|
|||
|
||||
expect(result.ok).toBe(false);
|
||||
});
|
||||
|
||||
it("validates the AgentAd ad fixture", () => {
|
||||
const testDir = dirname(fileURLToPath(import.meta.url));
|
||||
const file = resolve(testDir, "../../schemas/fixtures/agentad-ad.yaml");
|
||||
const data = parseDocument(readFileSync(file, "utf8"), file);
|
||||
|
||||
expect(validate("agentad-ad", data).ok).toBe(true);
|
||||
});
|
||||
|
||||
it("rejects an AgentAd ad that is not disclosed as sponsored", () => {
|
||||
const result = validate("agentad-ad", {
|
||||
type: "agentad.ad",
|
||||
version: "0.1",
|
||||
id: "undisclosed",
|
||||
advertiser_did: "acme.coinpay",
|
||||
format: "text",
|
||||
title: "Buy now",
|
||||
url: "https://example.com",
|
||||
disclosure: { sponsored: false, label: "Sponsored" }
|
||||
});
|
||||
|
||||
expect(result.ok).toBe(false);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,6 +9,13 @@ import pluginSchema from "../../schemas/schemas/logicsrc-plugin.schema.json" wit
|
|||
import runSchema from "../../schemas/schemas/logicsrc-run.schema.json" with { type: "json" };
|
||||
import socialPostSchema from "../../schemas/schemas/logicsrc-social-post.schema.json" with { type: "json" };
|
||||
import taskSchema from "../../schemas/schemas/logicsrc-task.schema.json" with { type: "json" };
|
||||
import agentadAdSchema from "../../schemas/schemas/agentad-ad.schema.json" with { type: "json" };
|
||||
import agentadPlacementSchema from "../../schemas/schemas/agentad-placement.schema.json" with { type: "json" };
|
||||
import agentadAdRequestSchema from "../../schemas/schemas/agentad-ad-request.schema.json" with { type: "json" };
|
||||
import agentadAdResponseSchema from "../../schemas/schemas/agentad-ad-response.schema.json" with { type: "json" };
|
||||
import agentadImpressionSchema from "../../schemas/schemas/agentad-impression.schema.json" with { type: "json" };
|
||||
import agentadClickSchema from "../../schemas/schemas/agentad-click.schema.json" with { type: "json" };
|
||||
import agentadCampaignSchema from "../../schemas/schemas/agentad-campaign.schema.json" with { type: "json" };
|
||||
|
||||
export const schemas = {
|
||||
agent: agentSchema,
|
||||
|
|
@ -21,7 +28,14 @@ export const schemas = {
|
|||
plugin: pluginSchema,
|
||||
run: runSchema,
|
||||
"social-post": socialPostSchema,
|
||||
task: taskSchema
|
||||
task: taskSchema,
|
||||
"agentad-ad": agentadAdSchema,
|
||||
"agentad-placement": agentadPlacementSchema,
|
||||
"agentad-ad-request": agentadAdRequestSchema,
|
||||
"agentad-ad-response": agentadAdResponseSchema,
|
||||
"agentad-impression": agentadImpressionSchema,
|
||||
"agentad-click": agentadClickSchema,
|
||||
"agentad-campaign": agentadCampaignSchema
|
||||
} as const;
|
||||
|
||||
export type SchemaKind = keyof typeof schemas;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue