lucidAGENTS
Reference

Configuration

Compose Lucid by concern, understand precedence, and keep extension-owned behavior in its owning package.

Lucid is configured as a typed extension graph. Core owns agent metadata and the canonical entrypoint registry; each extension owns its own configuration, runtime state, validation, and lifecycle.

Ownership map

ConcernOwning packageConfiguration entrypoint
Agent name, version, description@lucid-agents/corecreateAgent(meta)
Entrypoints and handlers@lucid-agents/coreruntime.addEntrypoint(definition) or an adapter helper
HTTP routes, landing page, base path, invoke idempotency@lucid-agents/httphttp(options)
x402, SIWX, payment policy, payment accounting@lucid-agents/paymentspayments({ config })
MPP challenge and credential verification@lucid-agents/mppmpp({ config })
Agent and developer wallets@lucid-agents/walletwallets({ config })
Lucid Agent Card, client, and task runtime@lucid-agents/a2aa2a(options)
ERC-8004 initialization and trust metadata@lucid-agents/identityidentity(options) or createAgentIdentity(options)
AP2 role metadata@lucid-agents/ap2ap2(config)
Payment analytics@lucid-agents/analyticsanalytics(options)
Scheduled Lucid task calls@lucid-agents/schedulercreateScheduler(options)
Catalog-defined entrypoints@lucid-agents/catalogCatalog parser/registration APIs
Framework bindingHono, Express, TanStack, or generated Next.js adapterAdapter-specific factory

Composition order

Declare producer extensions before consumers. The builder validates dependencies and initializes extensions sequentially.

import { createAgent } from '@lucid-agents/core';
import { http } from '@lucid-agents/http';
import { payments, paymentsFromEnv } from '@lucid-agents/payments';
import { wallets, walletsFromEnv } from '@lucid-agents/wallet';

const walletConfig = walletsFromEnv();
const paymentConfig = paymentsFromEnv();

if (!paymentConfig) throw new Error('Payment configuration is required');

const runtime = await createAgent({
  name: 'paid-research-agent',
  version: '1.0.0',
  description: 'Returns a paid research result',
})
  .use(wallets({ config: walletConfig }))
  .use(payments({ config: paymentConfig }))
  .use(
    http({
      basePath: '/api/agent',
      idempotency: {
        // Replace the default in-memory store before horizontal scaling.
        inProgressTtlMs: 15 * 60_000,
        retentionMs: 24 * 60 * 60_000,
      },
    })
  )
  .build();

The runtime exposes each slice directly as runtime.wallets, runtime.payments, and runtime.http. Do not create application wrappers that duplicate an extension's config or transform its public runtime into another shape.

Precedence

Configuration is resolved at the package boundary:

  1. Explicit function options take precedence over environment-backed fields.
  2. The package's environment helper applies its documented aliases and defaults.
  3. Extension construction validates the resolved object.
  4. Entrypoint configuration selects per-capability behavior, such as price, payment protocol, network, or SIWX requirements.

There is no hidden global merge across packages. For example, paymentsFromEnv() does not configure a wallet, and walletsFromEnv() does not choose a payment network.

Entrypoint-level configuration

The entrypoint is the commercial and execution boundary:

import { z } from 'zod';

runtime.addEntrypoint({
  key: 'summarize',
  description: 'Summarize supplied text',
  input: z.object({ text: z.string().min(1).max(50_000) }),
  output: z.object({ summary: z.string() }),
  price: { invoke: '0.02', stream: '0.03' },
  paymentProtocol: 'x402',
  network: 'eip155:84532',
  handler: async ({ input }) => ({
    output: { summary: input.text.slice(0, 200) },
  }),
});
  • price is a USD decimal string, not atomic token units and not a JavaScript number.
  • paymentProtocol selects one rail. Do not activate both x402 and MPP for the same operation.
  • An entrypoint-level network overrides the payment runtime network for that entrypoint.
  • Invoke and stream can have separate prices. Task creation uses the invoke authorization path in the current Lucid task profile.
  • SIWX authentication is configured separately from payment price.

Defaults that matter in production

SurfaceCurrent defaultProduction implication
HTTP service pageDossier preset, static on Hono/ExpressSet servicePage: false if public discovery is not intended.
HTTP base pathEmptySet it before publishing cards or reverse-proxy routes.
HTTP invoke idempotencyEnabled, bounded in-memory storeInject a durable atomic store for multiple replicas.
HTTP in-progress claim15 minutesSize it above the longest supported invoke or claims can expire mid-run.
HTTP completed-response retention24 hoursAlign client retry windows and data-retention policy.
Payment/SIWX storageIn-memory when no store is suppliedUse shipped SQLite/Postgres factories or a custom port as topology requires.
MPP challenge keyGenerated per process when absentSet one stable high-entropy secret for every worker.
MPP challenge stateBounded process-local mapInject the shipped SQLite/Postgres adapter or a custom atomic store for production.
Lucid tasksBounded in-memory store unless injectedSupply a durable task store before relying on task recovery.
Scheduler storeBounded in-memory implementationImplement the scheduler store port for durable/multi-instance workers.

See Durable storage for the exact support matrix and Payment lifecycle for commit timing.

Deployment configuration boundary

Adapters bind the canonical routes; they must not add a second paywall, entrypoint registry, or manifest implementation. Keep these layers separate:

LayerOwns
Extension configPayment verification, policy, wallet, task, and protocol behavior.
Adapter configRequest/response conversion, listener, framework route modules.
Deployment configSecrets, public origin, database URLs, trusted proxies, replicas, and shutdown.
Application configModel providers, tenant lookup, business limits, fulfillment, and downstream idempotency.

DATABASE_URL and PORT are examples of deployment variables that your app must wire explicitly. They are not read automatically by all Lucid packages.

Validation strategy

Treat startup validation as part of the public contract:

  1. Parse and validate application-owned variables before building the runtime.
  2. Call package environment helpers explicitly.
  3. Reject a missing required extension configuration instead of silently serving a free or in-memory fallback.
  4. Build the runtime during CI with production-shaped configuration and test every published route.
  5. Assert negative cases: no credential, wrong network, over-budget request, duplicate idempotency key, and unavailable durable store.

For the exact environment inventory, see Environment variables. Package pages contain the full public runtime surfaces; the monorepo source types remain the normative API when a generated API-reference page is not yet available.

On this page