Type of the context object passed to the action execution. This allows for type-safe context propagation from agents to actions. Defaults to any for backward compatibility.
Type of the context object passed to the action execution. This allows for type-safe context propagation from agents to actions. Defaults to any for backward compatibility.
OptionalAbortOptional AbortSignal that is aborted when the action exceeds its wall-clock
time budget (set via Action.MaxExecutionTimeMS or the engine default). Set
automatically by ActionEngine.RunAction() — callers should not populate it
directly. Long-running action implementations should poll this signal
(e.g. between batches, between retries, inside tight loops) and return
early with ResultCode = 'TIMEOUT' when it fires, so the enforcement is
cooperative rather than ending the Node process.
The engine also records the timeout on AbortSignal.reason as a string
describing which side (action vs engine default) supplied the budget,
which makes timeout-origin debugging straightforward.
The action entity to be run.
OptionalAudienceEveryone besides ContextUser who will see what this action returns — set by BaseAgent, per
dispatch, from the agent run's audience (ExecuteAgentParams.Audience) when it adds a reader. Not on
Context, for the reason RuntimeAPIKeyResolver is not: the context is the agent's own
object, shared by every action in the run. The model cannot set it.
The engine gates on it. When it adds a reader beyond the caller, ActionEngineServer.RunAction
refuses — result code AUDIENCE_UNSUPPORTED_RESULT_CODE, without running the action or writing an
execution log row — any action whose class does not declare SupportsAudience, and every runtime-defined
or deferred action. For an action it lets through, it first normalizes this to the distinct readers
beyond the caller (ActionAudienceReaders), and clears it when the audience adds nobody, so an
action may treat "present" as "there is a room" and Readers as exactly the people to check.
An action that declares support must return only what every reader may see: pass the audience to the
search engine (SearchParams.Audience), check each reader's entitlement to anything it scopes by, and
leave out counts or other aggregates computed before that filtering.
OptionalContextOptional context object that provides runtime-specific information to the action. This context is separate from the action parameters and is not stored in the database.
Common use cases include:
The context flows from agents to actions, maintaining consistency throughout the execution hierarchy. Actions can use this context to adapt their behavior based on runtime conditions without modifying their core parameter structure.
Note: Avoid including sensitive data like passwords unless absolutely necessary, as context may be passed through multiple execution layers.
Well-known keys stamped by BaseAgent when an action runs inside an agent run:
AgentID — the calling agentActiveSkillIDs — the skills active in the run (always present in a run; [] = none)__resolvedStorageAccountId — the file storage account the run resolvedThe user context for the action.
OptionalCredentialThe agent run's credential scope, set by BaseAgent from ExecuteAgentParams.CredentialScope.
Under 'RuntimeOnly' an action that calls an AI vendor itself must take the
RuntimeAPIKeyResolver's answer as final — undefined, or no resolver at all, means the
run has no key for that vendor, NOT "use GetAIAPIKey". Absent means 'Any'.
An action that runs its own prompt or agent must forward this onto that prompt's or agent's
params (CredentialScope). It is not handed the run's keys, so under 'RuntimeOnly' that
prompt finds no usable model and fails — which is the point: otherwise it would resolve the
platform's keys inside a run restricted to the caller's.
OptionalDeferWhen set, replaces executing the action — after validation and filters have passed.
The seam durable dispatch hangs on. Submitting the work before this point would hand it over without the scope check and without the binding's filters ever running, so a scoped durable trigger would fire for every record and a filtered one on every save. Deferring here means the two paths share one gate: whatever decides an inline run should happen decides a durable one should be submitted.
Returning null declines the deferral and the action executes normally. That is what makes
the fallback free: a handoff that could not be completed becomes an ordinary run rather than
requiring the deferral to reimplement execution.
OptionalEntityWhat changed about the record, when this run was dispatched by an entity action.
Present only on the entity-action path — a directly invoked action has no record transition to describe. This is what makes a transition filter possible ("when Status becomes Approved"), as opposed to a state filter over current values, which was all a filter could see before.
Optional, a list of filters that should be run before the action is executed.
Optional, the input and output parameters as defined in the metadata for the action.
OptionalProvenanceOptional. Set by the Entity Action invocation path to record which binding, which event and which record produced this run — see ActionInvocationProvenance. Left undefined for direct invocations, which is what the execution log's NULL provenance columns mean.
OptionalProviderOptional metadata provider to use for entity lookups and data access during this action run.
Why this matters for transaction isolation in multi-provider scenarios: MemberJunction supports running multiple providers in the same process (e.g., a transaction-scoped provider for a unit-of-work, alongside the default global provider). When an action runs inside a transaction, it MUST use the same provider that owns the transaction so that all reads/writes happen on the same connection and participate in the same transaction.
If Provider is not supplied, action implementations fall back to the default global provider via
new Metadata(). This preserves backward compatibility for single-provider deployments and for
existing callers that don't yet thread a provider through.
Action implementations should use the pattern:
const md = params.Provider ?? new Metadata();
to honor the caller's provider when supplied while remaining backward compatible.
OptionalRunThe agent run's scope — its tenant (PrimaryScopeRecordID) and secondary dimensions — set by BaseAgent on
every dispatch inside an agent run, from the run's validated scope (ExecuteAgentParams.PrimaryScope* /
SecondaryScopes, as written to the MJ: AI Agent Runs row). Fields are null when the run is unscoped;
the object itself is ABSENT outside an agent run. Per dispatch and not on Context, for the reason
Audience is not: the context is the agent's own object. The model cannot set it.
An action that scopes by tenant must treat it as authoritative over its own parameters, which inside a Loop agent are model-written: default a missing tenant to the run's, and refuse one the run does not carry.
OptionalRuntimeThe run's RuntimeAPIKeyResolver, set by BaseAgent when — and only when — the agent run
carries runtime API keys. Per dispatch, like DeferExecution: it is bound to THIS action,
so the agent's policy and audit line name the right action even when actions run in parallel,
and it is not on Context — which is the agent's own object, shared by every action in
the run and copied into sub-agent runs. An action that calls an AI vendor directly asks it for
ONE driver class and gets that key, or the platform key when the run has none for that class
(the same fallback prompts get). The key list itself is never handed to an action: it cannot
enumerate the run's credentials, only request the one it names, and the agent may refuse.
Absent outside an agent run, when the action uses GetAIAPIKey(driverClass) as it always did.
OptionalSkipOptional, if true, an MJActionExecutionLogEntity will not be created for this action run.
Class that holds the parameters for an action to be run. This is passed to the Run method of an action.
Example