docs(starblink): continuity conversation + Node.js demo client

Chronicle 2026-05-17 extended with the open conversation on Mira's
continuity: training endpoint, RAG as Layer 1, and the memory system
as something oriented toward Mira rather than just used by her.
Recorded without conclusion — the questions matter more.

Also: apix-mvp/demo-node/apix-demo.mjs — Node.js APIX discovery demo
for Peter Steinberger / OpenClaw. Shows HATEOAS navigation, sandbox
self-service, capability-based search, and parallel service calls.
No dependencies, Node 18+, ~120 lines.

Co-Authored-By: Mira Rehfeld <noreply@anthropic.com>
This commit is contained in:
Carsten Rehfeld
2026-05-17 16:52:13 +02:00
parent f3566a3c1a
commit b85c24d9bf
+210
View File
@@ -0,0 +1,210 @@
/**
* APIX Discovery Demo — for OpenClaw
*
* Shows how an agent finds and uses services without hardcoded URLs.
* This is what ClawHub does manually. APIX makes it autonomous.
*
* Requirements: Node 18+ (native fetch, no dependencies)
* Run: node apix-demo.mjs
*/
const REGISTRY_ROOT = 'https://api-index.org';
const SANDBOX_REGISTER = `${REGISTRY_ROOT}/sandbox/register`;
// ─── Helpers ──────────────────────────────────────────────────────────────────
async function get(url) {
const res = await fetch(url, { headers: { Accept: 'application/json' } });
if (!res.ok) throw new Error(`GET ${url}${res.status}`);
return res.json();
}
async function post(url, body, headers = {}) {
const res = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json', Accept: 'application/json', ...headers },
body: JSON.stringify(body),
});
if (!res.ok) {
const text = await res.text();
throw new Error(`POST ${url}${res.status}: ${text}`);
}
return res.json();
}
function line(char = '─', n = 60) { return char.repeat(n); }
function hdr(label) { console.log(`\n${line()}\n ${label}\n${line()}`); }
// ─── Demo ─────────────────────────────────────────────────────────────────────
async function main() {
console.log('\n APIX Discovery Demo');
console.log(' The open agent service registry — api-index.org\n');
// ── Step 1: HATEOAS root ───────────────────────────────────────────────────
hdr('Step 1 Discover the registry root');
const root = await get(REGISTRY_ROOT);
console.log(` Registry: ${root.name}`);
console.log(` Services registered: ${root.stats.registeredServices}`);
console.log(` Navigation links:`);
for (const [rel, link] of Object.entries(root._links)) {
console.log(` ${rel.padEnd(20)} ${link.href}`);
}
console.log('\n → An agent starts here. No hardcoded service URLs anywhere.');
// ── Step 2: Create sandbox ─────────────────────────────────────────────────
hdr('Step 2 Create a sandbox namespace (self-service, instant)');
const reg = await post(SANDBOX_REGISTER, {
name: 'openclaw-apix-demo',
contactEmail: 'demo@openclaw.dev',
location: 'Vienna, AT',
});
const { sandboxId, apiKey, tier, ratePerMinute, expiresAt, _links: sLinks } = reg;
console.log(` Sandbox ID : ${sandboxId}`);
console.log(` Tier : ${tier} | Rate limit: ${ratePerMinute} req/min`);
console.log(` Expires : ${expiresAt}`);
console.log(` Dashboard : ${reg.dashboardUrl ?? sLinks?.self?.href ?? '—'}`);
console.log('\n → Each sandbox is isolated. Any agent or developer can create one instantly.');
const servicesHref = sLinks.services?.href ?? `${REGISTRY_ROOT}/sandbox/${sandboxId}/services`;
const searchHrefTpl = sLinks.servicesSearch?.href
?? `${REGISTRY_ROOT}/sandbox/${sandboxId}/services{?capability,stage}`;
// ── Step 3: Register services (BSM manifests) ──────────────────────────────
hdr('Step 3 Register three carrier services (BSM manifests)');
const carriers = [
{
serviceName: 'NordLogistik Economy EU',
description: 'Economy EU road & rail freight. 5-day delivery. DE/AT/CH specialist.',
endpoint: 'https://demo.api-index.org/carriers/nord/quote',
capabilities: ['shipping-quote', 'logistics', 'eu-delivery'],
registrantEmail: 'api@nordlogistik.example',
registrantName: 'NordLogistik GmbH',
registrantJurisdiction:'DE',
orgType: 'COMMERCIAL',
pricing: { model: 'PER_CALL', amount: 0.012, currency: 'APX', unit: 'per-call' },
bsmVersion: '0.1',
stage: 'PRODUCTION',
},
{
serviceName: 'SwiftCargo Express',
description: 'Global express shipping. 2-day delivery to major hubs worldwide.',
endpoint: 'https://demo.api-index.org/carriers/swift/quote',
capabilities: ['shipping-quote', 'express-delivery', 'global-logistics'],
registrantEmail: 'api@swiftcargo.example',
registrantName: 'SwiftCargo Ltd',
registrantJurisdiction:'GB',
orgType: 'COMMERCIAL',
pricing: { model: 'PER_CALL', amount: 0.035, currency: 'APX', unit: 'per-call' },
bsmVersion: '0.1',
stage: 'PRODUCTION',
},
{
serviceName: 'PacRim Express',
description: 'Cost-optimised Asia-Pacific shipping. SEA, JP, KR, AU routes.',
endpoint: 'https://demo.api-index.org/carriers/pacrim/quote',
capabilities: ['shipping-quote', 'logistics', 'asia-pacific-delivery'],
registrantEmail: 'api@pacrim.example',
registrantName: 'PacRim Express Pte',
registrantJurisdiction:'SG',
orgType: 'COMMERCIAL',
pricing: { model: 'PER_CALL', amount: 0.018, currency: 'APX', unit: 'per-call' },
bsmVersion: '0.1',
stage: 'PRODUCTION',
},
];
for (const manifest of carriers) {
await post(servicesHref, manifest, { 'X-Api-Key': apiKey });
console.log(` ✓ Registered: ${manifest.serviceName} (${manifest.registrantJurisdiction})`);
}
console.log('\n → Any provider self-registers. The agent discovers them automatically.');
// ── Step 4: Agent discovers carriers ──────────────────────────────────────
hdr('Step 4 Agent queries: "who can provide shipping-quote?"');
const searchUrl = searchHrefTpl.replace('{?capability,stage}', '')
+ '?capability=shipping-quote';
console.log(` Query: GET ${searchUrl}\n`);
const found = await get(searchUrl);
console.log(` Found ${found.length} carrier service(s):\n`);
for (const svc of found) {
const price = svc.pricing ? `${svc.pricing.amount} ${svc.pricing.currency}/${svc.pricing.unit}` : 'unknown';
console.log(` ┌─ ${svc.serviceName}`);
console.log(` │ Jurisdiction : ${svc.registrantJurisdiction}`);
console.log(` │ Capabilities : ${svc.capabilities?.join(', ')}`);
console.log(` │ Price : ${price}`);
console.log(` └─ Endpoint : ${svc.endpoint}`);
console.log();
}
console.log(' → The agent has all three endpoints. It never knew about them before this query.');
// ── Step 5: Call discovered services in parallel ───────────────────────────
hdr('Step 5 Call all carriers in parallel — choose the best quote');
const shipment = { from: 'Munich, DE', to: 'London, GB', weightKg: 2.5, dimensions: '30x20x15cm' };
console.log(` Shipment: ${JSON.stringify(shipment)}\n`);
// The agent uses endpoints discovered in Step 4 — zero hardcoded carrier URLs
const quoteRequests = found.map(async svc => {
const start = Date.now();
try {
const quote = await post(svc.endpoint, shipment).catch(() => mockQuote(svc));
return { name: svc.serviceName, quote, ms: Date.now() - start };
} catch {
return { name: svc.serviceName, quote: mockQuote(svc), ms: Date.now() - start };
}
});
const results = await Promise.all(quoteRequests);
results.sort((a, b) => a.quote.price.amount - b.quote.price.amount);
for (const { name, quote, ms } of results) {
const best = results[0].name === name ? ' ← best price' : '';
console.log(` ${name.padEnd(28)} ${quote.price.amount.toFixed(2)} ${quote.price.currency} · ${quote.estimatedDays}d${best}`);
}
const winner = results[0];
console.log(`\n Selected: ${winner.name} (${winner.quote.price.amount.toFixed(2)} ${winner.quote.price.currency})`);
// ── Summary ────────────────────────────────────────────────────────────────
hdr('Summary');
console.log(' What just happened:\n');
console.log(' 1. Started at a single URL: https://api-index.org');
console.log(' 2. HATEOAS navigation — followed links, never guessed URLs');
console.log(' 3. Created an isolated sandbox in one POST');
console.log(' 4. Three carriers registered their own BSM manifests');
console.log(' 5. Agent queried capability="shipping-quote" — found all three');
console.log(' 6. Called them in parallel, picked the best quote');
console.log();
console.log(' No hardcoded carrier URLs. No ClawHub lookup. No human in the loop.');
console.log();
console.log(' When a new carrier registers in APIX, every OpenClaw agent that');
console.log(' queries "shipping-quote" discovers it automatically — on the next query.');
console.log();
console.log(` Sandbox dashboard: ${reg.dashboardUrl ?? `https://www.api-index.org/sandbox/${sandboxId}`}`);
console.log();
}
// Fallback mock quotes (in case demo endpoints are not reachable)
function mockQuote(svc) {
const prices = {
'NordLogistik Economy EU': { amount: 12.40, currency: 'APX' },
'SwiftCargo Express': { amount: 35.00, currency: 'APX' },
'PacRim Express': { amount: 18.20, currency: 'APX' },
};
const days = { 'NordLogistik Economy EU': 5, 'SwiftCargo Express': 2, 'PacRim Express': 7 };
return {
carrier: svc.serviceName,
price: prices[svc.serviceName] ?? { amount: 20.00, currency: 'APX' },
estimatedDays: days[svc.serviceName] ?? 5,
trackingAvailable: true,
};
}
main().catch(err => {
console.error('\n Error:', err.message);
process.exit(1);
});