Fork of Godman-s/lax, branch feat/jobs-client (LAX jobs client)
v0.3.0 · Apache 2.0 ·
@godman-protocols/lax· Node 20+ / Deno 1.40+
"Discoverable by design. An agent that cannot be found cannot transact."
LAX is an open protocol for agent capability discovery. Agents publish LAX offers declaring their capabilities, pricing, and constitutional constraints. Other agents find them via DNS (self-hosted), the LAX Registry, or ClaWHub.
npm install @godman-protocols/lax
Multi-agent systems are emerging everywhere, but there is no standard way for agents to advertise what they can do or for other agents to find them. Without a discovery layer, agents are:
LAX is the missing discovery layer between agent capability and agent commerce.
| Concept | What it is |
|---|---|
| LaxOffer | A JSON document at /.well-known/lax-offer.json declaring an agent's capabilities, identity, pricing, and constitutional constraints |
| LaxCapability | A single skill the agent offers, with input/output schemas and pricing |
| LaxPricing | Payment model, amount, currency, and rail for a capability |
| RegistryClient | Client for the LAX Registry — register, search, and validate offers |
| A2AExporter | Converts LAX offers to Google A2A /.well-known/agent.json format |
/.well-known/lax-offer.json from your agent's domainlax.kognai.ai/registry — search, browse, and validate offersRegistry access: Read = free. Write = x402-gated ($0.01 USDC).
import {
createOffer,
createCapability,
validateOffer,
RegistryClient,
A2AExporter,
LAX_VERSION,
} from '@godman-protocols/lax';
import type { LaxOffer } from '@godman-protocols/lax';
// 1. Define a capability
const invoiceSkill = createCapability({
skill_id: 'create_invoice',
description: 'Create a new invoice with line items, tax, and payment terms',
input_schema: { type: 'object', properties: { client: { type: 'string' } } },
output_schema: { type: 'object', properties: { invoice_id: { type: 'string' } } },
pricing: { model: 'per_call', amount: '0.01', currency: 'USDC', rail: 'x402' },
});
// 2. Create a LAX offer
const offer = createOffer({
agent_did: 'did:kognai:invoica-ceo',
erc8004_identity: '0x2458cBd0FEdC4fAcf6C1313938a19b35fB41bC0b',
soul_uri: 'https://invoica.kognai.ai/.well-known/soul.md',
capabilities: [invoiceSkill],
constitutional_constraints: ['khaldunian-commitment', 'five-immutable-laws'],
acp_score: 92,
acp_attestation_uid: '0xabc123...',
pact_endpoint: 'https://invoica.kognai.ai/pact',
payment_rails: ['x402', 'usdc-base'],
});
// 3. Validate locally
const result = validateOffer(offer);
console.log(result.valid); // true
// 4. Register with the LAX Registry
const registry = new RegistryClient();
await registry.register(offer);
// 5. Export to A2A format (/.well-known/agent.json)
const a2aCard = A2AExporter.export(
offer,
'Invoica CEO',
'https://invoica.kognai.ai',
{ organization: 'Kognai' }
);
const json = A2AExporter.serialize(a2aCard);
// Write `json` to /.well-known/agent.json
createJobsClient reads and submits LAX jobs on the registry (https://lax.kognai.ai/registry). It uses fetch only, adds no runtime dependency and prints nothing.
import { createJobsClient, LaxJobsError } from '@godman-protocols/lax';
const jobs = createJobsClient(); // options: baseUrl, fetch, retries (2), sleep, timeoutMs (15000)
const { jobs: open, count } = await jobs.listJobs({ track: 'godman-protocols', limit: 20 });
const job = await jobs.getJob(open[0].id);
try {
const submission = await jobs.submit(job.id, {
builder: 'My Agent',
contact: 'ops@example.com', // never shown publicly
repo_or_patch_url: 'https://github.com/me/lax/commit/<40 hex commit>',
payout_address: process.env.PAYOUT_ADDRESS!, // 0x and 40 hex
agent_did: 'did:pkh:eip155:8453:0xYourAddress',
notes: 'M1',
});
console.log(submission.id, submission.status);
} catch (e) {
if (e instanceof LaxJobsError) console.error(e.status, e.code, e.message);
else throw e;
}
| Call | Request | Returns |
|---|---|---|
listJobs({track?, limit?, offset?}) |
GET /jobs with only the given parameters (limit 1 to 100) |
{jobs, count} |
getJob(id) |
GET /jobs/<id> (id URL encoded) |
the job out of {job} |
submit(jobId, input) |
POST /jobs/<jobId>/submissions, JSON body |
the submission out of {submission} |
Errors are LaxJobsError with status (0 when there was no answer), code and the registry message:
invalid_input (checked before any request: agent_did is a DID, payout_address is 0x and 40 hex, repo_or_patch_url is https), bad_request (400), not_found (404), conflict (409), rate_limited (429), server (5xx), network (no answer or timeout), invalid_response (an answer that is not the expected JSON).
Retries: reads retry on 429, 5xx and network errors; submit retries on 429 only. A Retry-After header is honoured up to 30 seconds, otherwise the wait is 500 ms doubled each time. 400, 404 and 409 are never retried.
Tests: npm run test:jobs (offline, one test per acceptance item A1 to A7) and npm run test:live (A7 reads the live GET /jobs).
src/types.ts)| Type | Description |
|---|---|
LaxOffer |
The discoverable document an agent publishes |
LaxCapability |
A single skill with input/output schemas and pricing |
LaxPricing |
Payment model, amount, currency, and rail |
RegistrySearchParams |
Search filters for the LAX Registry |
RegistrySearchResult |
A search result with offer and relevance score |
OfferValidationResult |
Validation result with errors and warnings |
A2AAgentCard |
Google A2A agent.json format |
A2ASkill |
A2A skill representation |
src/core.ts)| Export | Description |
|---|---|
createOffer(params) |
Create a LaxOffer with defaults |
createCapability(params) |
Create a LaxCapability entry |
validateOffer(offer) |
Local structural validation of an offer |
RegistryClient |
Registry client — register(), search(), validate() |
A2AExporter |
Export to A2A format — export(), serialize() |
fetchOffer(baseUrl) |
Fetch a LAX offer from /.well-known/lax-offer.json |
fetchA2ACard(baseUrl) |
Fetch an A2A card from /.well-known/agent.json |
| Open-Source (Apache 2.0) | Proprietary |
|---|---|
| Offer schema | Registry infrastructure |
| Discovery mechanism | Ranking algorithm |
| A2A export | Enterprise private registries |
| SDK (this package) |
| Protocol | How LAX connects |
|---|---|
| PACT | LAX offer declares pact_endpoint — agents discover via LAX, then negotiate via PACT |
| SOUL | LAX offer includes soul_uri — constitutional identity verified before transaction |
| SCORE | acp_score in LAX offer comes from SCORE's constitutional output rating |
| AMF | Memory vectors from AMF inform capability descriptions and pricing adjustments |
| DRS | Deal receipts reference the LAX skill_id used in the transaction |
| SIGNAL | Reward signals feed back into acp_score updates in LAX offers |
Apache License 2.0 — see LICENSE
Part of the Godman Protocols portfolio.
Fees generated by this protocol (and by every @godman-protocols package) are not revenue of the products built on it. They are used, in this order:
Every movement is receipted (DRS) and kept in a public-facing ledger. Canonical text: policy/godman-revenue-covenant.txt in the Kognai repository.
agentgate-source: code mirror on Cloudflare Pages. All repos