Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use AxEventRuntime to ingest events, explicitly wake or resume AxGen, AxAgent, and AxFlow, persist state and results, and route outputs safely.
.claude/skills/ax-llm-ax-event-runtime/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 6% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 20% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 61% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 1% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 26% | 0% |
Use this skill when an Ax program should react to notifications, webhooks, timers, queues, task completion, or application events.
textsource -> inbox -> route -> target -> stored run -> sink
Sources never call an Ax program directly. A route must explicitly choose observe, invalidate, wake, or resume. Only the last two invoke a model.
tsconst source = new AxPushEventSource('application'); const target = eventTarget('triage') .program(triageAgent) .ai(llm) .input((input) => input.field('incident', eventPath.data())) .sink({ id: 'result', write: saveResult }) .build(); const events = eventRuntime({ sources: [source], routes: [ eventRoute('incident-created') .types('incident.created') .wake(target) .build(), ], }); await events.start(); await source.publish({ event, identity, trust: 'authenticated' });
eventPath.data('field') and other segment-safe selectors. Do not usedotted JSONPath strings or repurpose s() as a mapping language.
.project(path) only for same-name signature projection. Explicit.field() mappings override projection; missing or invalid signature inputs dead-letter before model invocation.
eventInput().project(...).field(...) when a declarative mapping shouldbe callback-free and reusable, then pass that plan to .input(), .wakeInput(), or .resumeInput().
mapInput is an escape hatch, not a validation bypass: its result isnormalized to the program signature and mapper failures dead-letter before invocation.
.wakeInput() and .resumeInput() when the two actions need differentcontracts. Neither action silently uses the other action's mapping.
observe for progress/logs and invalidate for catalog changes.resume only with an owned continuation correlation key.createProgram(instance) for stateful multi-tenant Agents.retrySafety: 'idempotent' only when stable delivery keys protectevery possible side effect.
debounceMs and coalesce: 'latest' only when replacing intermediateevents is part of the route's declared policy.
onSourceError.AxSQLiteEventStore from @ax-llm/ax-tools/event/sqlite with explicit retention and coordination: 'multi-worker'. Never recommend SQLite on a network filesystem.
route. This preserves independent authorization, ordering, retries, and runs.
tseventContext.registerContinuation({ correlation: [{ kind: 'task', value: taskId }], expiresAt, });
Route progress to observe. Route input_required, completed, failed, or cancelled task events to resume when the owning program must run again.
Use ax-mcp for client construction, transports, authentication, catalogs, subscriptions, tasks, and MCP-specific security policy. This skill owns the generic inbox, routing, continuation, store, and sink behavior.
Use client.inspectCatalog() to discover server-owned tools, prompts, concrete resources, and URI templates from only the endpoint. Then use AxMCPEventSource({ client, resourceSubscriptions, identity, trust }) with an explicit none/all/URI/selector policy. Omitted policy subscribes to no resources. Templates are never expanded automatically. Managed sources diff catalog changes, restore current logical ownership on reconnect, and release only their own subscriptions on close. Identity must come from the application's authenticated client or token mapping; a bare MCP session is anonymous. Add ...axMCPEventRoutes({ client }) for catalog invalidation, progress/log observation, and task resume. Resource notifications never get an implicit wake route. See docs/MCP_SUBSCRIPTIONS.md.
Use AxUCPWebhookEventSource({ client, identity }) inside an application-owned HTTP handler, then call source.ingest(request). Verification of the signer profile, RFC 9421 signature, digest, freshness window, key rotation, and replay key completes before enqueue. Resolve tenant/account identity from application state after verification; do not copy identity from the business payload.
Generated Python, Java, C++, Go, and Rust packages expose the same Core-owned single-worker event state machine plus functioning inline lifecycle dispatch, continuations, state restoration, cancellation, persisted outputs, isolated sink redrive, signature-aware path/input/target/route builders, and host-owned source, sink, clock, and store boundaries. Generated targets use the host signature plus a typed invocation callback when no common object-safe program interface exists. Do not claim persistent multi-worker support from axevent.single-worker alone.
Generated runtimes do not create worker threads. publish() drains work due at clock.now(). Hosts use nextDueAt() to schedule runDue() for debounce, retry, and continuation expiry; redrive() is due immediately. Manual clocks make these transitions deterministic. Generated in-memory stores enforce 10,000 pending deliveries, 64 MiB queued data, 1 MiB per envelope, and a five-second publication wait.
System and manual clock sleeps accept the generated cancellation token (Go uses context.Context). Cancellation wakes the sleep without advancing a manual clock, preserves the token's first reason, and removes its wake subscription on both cancellation and normal completion. Repeated completed sleeps must not retain timers, callbacks, condition registrations, or manual-clock waiters.
Use AxManualEventClock, AxInMemoryEventStore, deterministic event IDs, and an output-capturing sink. Assert that unmatched or observe-only events never invoke the program, tenant scopes do not collide, outputs exist before sinks, and uncertain side effects become outcome_unknown.
Persistent store implementations must pass runAxEventStoreConformance(createStore, { clock }). A store must not advertise multi-worker capability without the conformance marker checked by runtime startup.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 25,453 | 16,863 | -34% | 1 | 1 | 0% | 3,860 | 4,084 | +6% | 0 | 0 | — |
case-02 | fail→fail | 26,127 | 17,509 | -33% | 1 | 1 | 0% | 4,461 | 4,042 | -9% | 0 | 0 | — |
case-03 | fail→pass | 27,650 | 25,270 | -9% | 1 | 1 | 0% | 5,081 | 6,099 | +20% | 0 | 0 | — |
case-04 | pass→pass | 24,565 | 14,369 | -42% | 1 | 1 | 0% | 3,256 | 3,296 | +1% | 0 | 0 | — |
case-05 | fail→pass | 15,172 | 12,599 | -17% | 1 | 1 | 0% | 1,807 | 2,909 | +61% | 0 | 0 | — |
case-06 | fail→pass | 21,178 | 11,853 | -44% | 1 | 1 | 0% | 2,935 | 2,968 | +1% | 0 | 0 | — |
case-07 | fail→pass | 19,718 | 12,795 | -35% | 1 | 1 | 0% | 2,473 | 3,109 | +26% | 0 | 0 | — |
case-08 | pass→pass | 14,652 | 8,617 | -41% | 1 | 1 | 0% | 1,532 | 2,141 | +40% | 0 | 0 | — |
case-09 | fail→pass | 21,837 | 14,640 | -33% | 1 | 1 | 0% | 2,744 | 3,210 | +17% | 0 | 0 | — |
case-10 | fail→pass | 26,628 | 16,259 | -39% | 1 | 1 | 0% | 3,408 | 3,665 | +8% | 0 | 0 | — |
case-11 | pass→pass | 20,182 | 11,603 | -43% | 1 | 1 | 0% | 2,422 | 2,783 | +15% | 0 | 0 | — |
case-12 | pass→pass | 19,219 | 9,316 | -52% | 1 | 1 | 0% | 2,270 | 2,229 | -2% | 0 | 0 | — |
case-13 | fail→pass | 18,704 | 14,299 | -24% | 1 | 1 | 0% | 2,159 | 3,438 | +59% | 0 | 0 | — |
case-14 | fail→pass | 21,097 | 9,877 | -53% | 1 | 1 | 0% | 2,876 | 2,418 | -16% | 0 | 0 | — |
case-15 | fail→pass | 46,485 | 10,348 | -78% | 1 | 1 | 0% | 1,806 | 2,477 | +37% | 0 | 0 | — |
case-16 | fail→pass | 14,371 | 8,117 | -44% | 1 | 1 | 0% | 1,506 | 2,032 | +35% | 0 | 0 | — |
case-17 | fail→pass | 20,280 | 9,800 | -52% | 1 | 1 | 0% | 2,505 | 2,324 | -7% | 0 | 0 | — |
case-18 | pass→pass | 16,832 | 7,479 | -56% | 1 | 1 | 0% | 1,828 | 1,953 | +7% | 0 | 0 | — |
case-19 | pass→pass | 14,464 | 8,605 | -41% | 1 | 1 | 0% | 1,627 | 2,114 | +30% | 0 | 0 | — |
case-20 | pass→pass | 14,079 | 10,147 | -28% | 1 | 1 | 0% | 1,685 | 2,393 | +42% | 0 | 0 | — |
case-21 | pass→pass | 7,852 | 6,961 | -11% | 1 | 1 | 0% | 442 | 1,853 | +319% | 0 | 0 | — |
case-22 | pass→pass | 13,617 | 12,037 | -12% | 1 | 1 | 0% | 1,715 | 2,954 | +72% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 21 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +55 percentage points is the difference between those two pass rates over the 21 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 8/11/2026 | +68% |
Other measured skills in the registry, with their headline benchmark lift.