Instance modes
Every Core declares an instance mode in its @core block. It governs whether the Core has memory at all, whether that memory is shared across invocations, and how the host routes incoming requests. Pick it up front — changing it later requires migrating the memory backend.
:stateless#
1 2 3 | |
The default and simplest mode. Every invocation runs against an empty memory namespace; nothing persists across calls. Use this for pure transformations, classifiers, anything where the answer is a function only of the inputs. Multiple invocations run in parallel without coordination.
:entity#
1 2 3 4 5 6 7 8 9 | |
One instance per entity. The host extracts entity_key from each request's input and routes to a memory partition keyed on that value. Memory writes from one entity don't leak to another. Use this for per-user agents, per-order workflows, anything with a natural sharding key.
The optional fields cover instance lifecycle:
idle_timeout— milliseconds before an idle instance is deactivated. Memory persists; the in-memory cache is dropped.max_concurrent— concurrent invocations against the same entity.1serializes (no races on memory); higher values let the entity handle parallel work.max_active_instances— cap on resident instances. Combined withoverflowto control eviction.overflow—"deactivate_lru","reject", or"queue". What happens when an incoming request would exceedmax_active_instances.
The verifier rejects entity-mode Cores whose entity key never appears in any flow's input (E402). If you declare it, you must use it.
:singleton#
1 2 3 | |
Exactly one instance, exactly one memory partition, shared across all invocations. Use this for configuration agents, global rate limiters, system-wide deduplication caches — anything that needs a single source of truth and tolerates serialized access.
Singleton + high concurrency is a contention recipe; pair it with max_concurrent = 1 if state correctness matters, or accept the race.
Picking one#
The decision rule, in order:
- Does the Core need memory at all? If no,
:stateless. You're done. - Is there a natural per-entity boundary in the inputs (user ID, order ID, tenant ID)? If yes,
:entitywith that field asentity_key. - Does the state genuinely need to be global? If yes,
:singleton. Be intentional about contention.
If you find yourself wishing for "stateless with shared memory" — that's :singleton with no instance bounds. If you find yourself wishing for "entity, but the entity_key is computed" — derive it before invocation and pass it in as a regular input field. The runtime won't infer it.