Each model request resends its context. Long runs can spend most of their budget rereading old
tool results or exceed the model’s context window. Yielded Agent bounds tool output, reports the
remaining budget, and compacts old context. Final-answer policy can grant one constrained turn
after turn, tool call, or token exhaustion.
Set these limits from the model and workload. The provider does not supply them:
tokenBudget counts cumulative input and output across the run. costBudgetMicrousd uses the
installed cost estimator and cache-split usage. contextTokenLimit bounds the live context for one
call. Set it below the model window so output and compaction have room.
At run start, the runtime evaluates instructions and the definition’s optional
inputPrompt. Without inputPrompt, the model receives
the full encoded input as a JSON user message.
Before each turn, the durable runtime commits the previous completed Tool batch, then
RunContextPreparation.hook.prepare transforms the source prompt. A host resolving the next model
from successful Tool receipts can therefore read their canonical records during preparation. The engine
compacts the prepared history, then loads optional references through
RunContextPreparation.transientContext.load. If the references exceed the remaining budget,
the engine can compact canonical history further while keeping the same reference snapshot.
It appends the references to the compacted view. OpenAI, xAI Responses, and native adapters advertising
support for system messages in history preserve chronological guidance, with the output contract
after the initial system block. Changing late instructions therefore leaves earlier history reusable.
The engine resolves this capability from the selected model on each call. Other adapters, including
the pinned Anthropic adapter, group systems before the conversation. Derived run status follows
this projection, which preserves stored history and compaction boundaries. See
prompt caching for provider differences.
Compaction summaries never receive transient references. Durable
recovery rebuilds the committed model view before applying prompt preparation; a transient loader
receives the current Attempt’s official source, Thread ID, Run ID, Turn ID, and Turn number.
Each turn releases its response trace and prepared context before the next turn starts. Official
history and detached event replay retain their own records. Resources acquired by beforeTurn
or context.prepare also close at that turn boundary, including on failure or interruption.
Acquire resources needed across turns in a surrounding run Layer or Scope.
To add application instructions to each request:
import{
classRunContextPreparation
Host-owned model-context preparation, independent of action-time Tool authorization.
Runs use this service when provided; durable coordinators capture it while their runtime
Layer is acquired. Implementations acquire dependencies in their Layer and preserve the
declared error tags. Layer acquisition failures belong to the providing Effect, not this union.
Without this service, Runs apply no host context loading. Provide ContextCompactor
separately to select native compaction; neither service replaces RunToolAuthorization.
Model-only prompt transformation. Compaction requires a safely mapped original
instruction/input block and content-equivalent covered prefixes across Turns.
Incompatible changes fail with CompactionError before compaction or model I/O.
Model-only prompt transformation. Compaction requires a safely mapped original
instruction/input block and content-equivalent covered prefixes across Turns.
Incompatible changes fail with CompactionError before compaction or model I/O.
Resources acquired by prepare belong to the current Turn and close before
the next Turn starts. Acquire resources shared across Turns in a surrounding
Run Layer or Scope instead.
prepare:({
source:Prompt.Prompt
Official engine history for this Attempt before context preparation. The
engine never replaces or mutates this value. Durable prompt
reconstruction can produce a different model-visible basis afterward, so
adapters that need canonical retrieval should key it by the supplied Run
identities rather than infer durable state from this Prompt alone.
source})=>
importEffect
Effect.
constsucceed:<{
prompt:Prompt.Prompt;
}>(value:{
prompt:Prompt.Prompt;
})=>Effect.Effect<{
prompt:Prompt.Prompt;
},never,never>
Creates an Effect that always succeeds with a given value.
When to use
Use when an effect should complete successfully with a specific value without any errors
or external dependencies.
Example (Creating a successful effect)
import{ Effect }from"effect"
// Creating an effect that represents a successful scenario
//
// ┌─── Effect<number, never, never>
// ▼
constsuccess=Effect.succeed(42)
Effect.runSync(success)// => 42
@see ― fail to create an effect that represents a failure.
Official engine history for this Attempt before context preparation. The
engine never replaces or mutates this value. Durable prompt
reconstruction can produce a different model-visible basis afterward, so
adapters that need canonical retrieval should key it by the supplied Run
identities rather than infer durable state from this Prompt alone.
@see ― sync for constructing layers from lazy values
@category ― constructors
@since ― 2.0.0
succeed(
classRunContextPreparation
Host-owned model-context preparation, independent of action-time Tool authorization.
Runs use this service when provided; durable coordinators capture it while their runtime
Layer is acquired. Implementations acquire dependencies in their Layer and preserve the
declared error tags. Layer acquisition failures belong to the providing Effect, not this union.
Without this service, Runs apply no host context loading. Provide ContextCompactor
separately to select native compaction; neither service replaces RunToolAuthorization.
Optional transformation of the model-visible prompt.
hook:
constmetricContext:RunContextHook<never,never>
metricContext});
Provide MetricContextLive to AgentRuntime.run or start with Effect.provide, or to
AgentRuntime.stream with Stream.provide.
With start, provide the Layer around the whole scoped workflow, including awaiting the handle,
so its resources remain available until the detached Run finishes.
For durable execution, install MetricContextLive when configuring the runtime.
Transforms change the model prompt, not stored input or history. Use
inputPrompt to choose which input fields the model sees.
Prepared and transient context use full provider requests, bypassing native response-ID reuse so
discarded material cannot remain in a provider-held conversation. Prompt caching still applies to
matching prefixes. A transient user-message suffix can move OpenAI’s implicit cache-write boundary
past the retained history, even when the reference text stays identical. To reuse that history,
place native explicit cache markers in the stable prefix through context preparation; keep
untrusted references in user messages. Append changing trusted system guidance after source;
supported chronological adapters keep it after the retained history. Prepending changing content
still invalidates the prefix. Anthropic needs both a capable upstream adapter and a supported model;
its pinned adapter retains grouped systems. Place native Anthropic cache markers before changing
transient context rather than relying on automatic placement after that suffix. See
provider cache settings for the release limitation and xAI routing configuration.
Token-limited calls estimate their current prepared messages. The engine reuses default counts
within each prepared prompt and recomputes them after the next context preparation. Calls without
contextTokenLimit, resolved model capacity, or tokenBudget skip admission estimates;
Context Tools still obtain their live-context estimate on demand.
For nondurable compaction, retain the original instruction/input messages or an unambiguous, content-equivalent
ordering of them. The engine rejects compaction with CompactionError when that block cannot be
mapped safely. Original message identities disambiguate repeated instructions or input text.
After compaction, preparation must preserve the content and order of the covered prefix. Rebuilding
equivalent messages is supported; replacing, inserting into, or reordering that prefix fails before
another model request. Durable reconstruction keeps its canonical coverage checks at commit time.
A host that routes between models can return modelCall from prepare. Capture one resolved
provider configuration and build both its native Model Layer and ModelCallContext from that
configuration. The engine acquires the Layer once for the turn and reuses it for admission,
dispatch, usage accounting, and bounded overflow recovery. Its resources close at the turn
boundary, including when preparation or admission fails. A separately configured compaction
model retains its own binding. A summary using the captured model must also fit its input
allowance; an oversized summary fails with CompactionError before provider I/O.
ModelCallContext carries the model’s full contextCapacity, optional maxInputTokens, its
configured outputReserveTokens, and uncountedOverheadTokens. The effective input allowance is
the minimum of the definition’s optional context limit, the model’s input limit, and context
capacity minus output reserve, less uncounted overhead. An exhausted allowance fails with
ContextBudgetError before dispatch. Capacity remains an estimate when exact token counting is
unavailable.
The engine counts the prepared prompt, transient references, output contract, run status, and
the native Tool schemas dispatched for the call. Supply the provider’s native
toolSchemaTransformer, such as toCodecOpenAI from
effect/ai/OpenAiStructuredOutput, to include its schema conversion. Reserve additional
framing or image costs only when they are absent from those estimates. Do not subtract prompt
text or Tool schemas again as overhead. The output reserve must match the selected provider’s
generation allowance; completionReserveTokens instead reserves cumulative Run budget for
delivery and does not provide this per-call allowance.
Durable hosts must capture resolved model settings in their own schema-validated admission data
and restore committed routing changes before preparation. Returning a Layer does not persist its
configuration or register a different Agent revision. Keep the original registration available for
already-admitted Runs.
Hosts may also return rollover: {} to reset prior history below the capacity threshold. The engine
selects the prefix before the current Run’s protected instructions and input; an empty or already
covered prefix is a no-op, including after recovery. For an explicit selection, return
rollover: { through, handoff? }, where through is an exclusive source-message boundary. Leave
that prefix intact in the prepared prompt. The engine maps it to complete canonical records and
commits ordinary native rollover. Protected input and pending Tool pairs cannot be discarded. This does not manufacture
a model Tool Call, start another Run, or reset its deadline and usage. Do not return a host
rollover while a successful new_context request is already pending.
Memory.recall turns readable, application-selected sources into a bounded transient model view.
The framework does not own a memory database, write recalled material, or build an embedding
index. An Agent that does not need context loading requires no context service, memory reader,
or store. RunContextPreparationPassthrough remains available to explicitly disable inherited
context preparation.
Each reader returns MemoryLookup. Found carries ranked MemoryPassage values. NoMatch is a
successful empty result. Unavailable and InsufficientFreshness remain distinct in the returned
source outcomes. An unavailable or stale essential: true source fails recall; an essential source
whose matching passages cannot fit also fails. NoMatch remains successful even for an essential
source. Expected reader failures propagate unless the reader deliberately maps them to one of the
lookup outcomes.
A passage points back to its authoritative source ID, locator, and known revision. Its attribution
records the speaker, observers, original activity time, and the application’s interpretation.
recordedAt says when the application recorded the content, while extractedAt says when it made
this passage. Neither substitutes for activityAt; use null when the original activity time is
unknown.
This source reads a known Markdown note without a store or adapter:
import{
importMemory
Memory }from"@yielded/agent";
import{
classMemoryAttribution
Evidence of who said something, where, when, and who observed it. Interpretation is
consumer-defined, for example "proposal" or "inference". Repeated references retain
the same originId; they are not independent corroboration. Unknown activity time is null.
MemoryAttribution,
classMemoryContent
Readable authoritative content, independent of any index, model, or fixed memory taxonomy.
Recording/extraction time never substitutes for the original source activity time.
No-match, unavailable, and insufficient freshness are distinct consumer-visible outcomes.
MemoryLookup,
classMemoryPassage
A bounded passage supplied directly by a document reader or external retriever.
MemoryPassage,
classMemoryRecallError
A recall contract or essential-source requirement could not be satisfied.
MemoryRecallError,
classMemoryRecallLimits
Output bounds cover the complete rendered reference text, including citations and provenance.
MemoryRecallLimits,
classMemorySourceReference
Identity in the consumer's authoritative source. null means revision is unknown.
MemorySourceReference,
}from"@yielded/agent/memory-reference";
import{
classRunContextPreparation
Host-owned model-context preparation, independent of action-time Tool authorization.
Runs use this service when provided; durable coordinators capture it while their runtime
Layer is acquired. Implementations acquire dependencies in their Layer and preserve the
declared error tags. Layer acquisition failures belong to the providing Effect, not this union.
Without this service, Runs apply no host context loading. Provide ContextCompactor
separately to select native compaction; neither service replaces RunToolAuthorization.
Supplies model-visible reference context for one Turn without changing the
prompt that compaction covers or the history that the engine commits.
The engine treats the returned input as untrusted, validates it before
provider I/O, and includes it in the Turn's context and completion-reserve
admission. It never passes this input to the compaction summary Model. A
same-Turn provider-overflow retry reuses the loaded snapshot. Return an
empty Prompt when the Turn needs no references.
Constructs a value from the make input representation synchronously.
When to use
Use when constructor input is trusted or when validation failure
should abort with a thrown Error.
Details
Applies constructor defaults and type-side validation according to
MakeOptions.
Gotchas
Throws an Error with the schema issue in its cause when validation
fails. Schema validation failures use the generic message
"Schema validation failed"; format the cause explicitly with
SchemaIssue.makeFormatterDefault() when human-readable details are needed.
Causes that contain defects, interruptions, or other non-schema reasons
throw with the underlying Cause attached instead.
@see ― BottomWithoutNew.makeOption — construct synchronously and discard validation details
@see ― BottomWithoutNew.makeEffect — construct through Effect when validation failure should stay in the error channel
make({
maxSources:number
maxSources:1,
maxItems:number
maxItems:4,
maxBytes:number
maxBytes:16_384,
maxTokens:number
maxTokens:4_096,
timeoutMillis:number
timeoutMillis:1_000,
});
const
constnote:MemoryPassage
note=
classMemoryPassage
A bounded passage supplied directly by a document reader or external retriever.
Constructs a value from the make input representation synchronously.
When to use
Use when constructor input is trusted or when validation failure
should abort with a thrown Error.
Details
Applies constructor defaults and type-side validation according to
MakeOptions.
Gotchas
Throws an Error with the schema issue in its cause when validation
fails. Schema validation failures use the generic message
"Schema validation failed"; format the cause explicitly with
SchemaIssue.makeFormatterDefault() when human-readable details are needed.
Causes that contain defects, interruptions, or other non-schema reasons
throw with the underlying Cause attached instead.
@see ― BottomWithoutNew.makeOption — construct synchronously and discard validation details
@see ― BottomWithoutNew.makeEffect — construct through Effect when validation failure should stay in the error channel
make({
version:1
version:1,
source:MemorySourceReference
source:
classMemorySourceReference
Identity in the consumer's authoritative source. null means revision is unknown.
Constructs a value from the make input representation synchronously.
When to use
Use when constructor input is trusted or when validation failure
should abort with a thrown Error.
Details
Applies constructor defaults and type-side validation according to
MakeOptions.
Gotchas
Throws an Error with the schema issue in its cause when validation
fails. Schema validation failures use the generic message
"Schema validation failed"; format the cause explicitly with
SchemaIssue.makeFormatterDefault() when human-readable details are needed.
Causes that contain defects, interruptions, or other non-schema reasons
throw with the underlying Cause attached instead.
@see ― BottomWithoutNew.makeOption — construct synchronously and discard validation details
@see ― BottomWithoutNew.makeEffect — construct through Effect when validation failure should stay in the error channel
make({
id:string
id:"project-notes",
locator:string
locator:"file:///workspace/notes/queue.md",
revision:string|null
revision:"sha256:8d31",
}),
passageId:string
passageId:"retry-policy",
content:MemoryContent
content:
classMemoryContent
Readable authoritative content, independent of any index, model, or fixed memory taxonomy.
Recording/extraction time never substitutes for the original source activity time.
Constructs a value from the make input representation synchronously.
When to use
Use when constructor input is trusted or when validation failure
should abort with a thrown Error.
Details
Applies constructor defaults and type-side validation according to
MakeOptions.
Gotchas
Throws an Error with the schema issue in its cause when validation
fails. Schema validation failures use the generic message
"Schema validation failed"; format the cause explicitly with
SchemaIssue.makeFormatterDefault() when human-readable details are needed.
Causes that contain defects, interruptions, or other non-schema reasons
throw with the underlying Cause attached instead.
@see ― BottomWithoutNew.makeOption — construct synchronously and discard validation details
@see ― BottomWithoutNew.makeEffect — construct through Effect when validation failure should stay in the error channel
make({
text:string
text:"# Retry policy\nUse a bounded queue and preserve failed work.",
attributions:readonlyMemoryAttribution[]
attributions:[
classMemoryAttribution
Evidence of who said something, where, when, and who observed it. Interpretation is
consumer-defined, for example "proposal" or "inference". Repeated references retain
the same originId; they are not independent corroboration. Unknown activity time is null.
Constructs a value from the make input representation synchronously.
When to use
Use when constructor input is trusted or when validation failure
should abort with a thrown Error.
Details
Applies constructor defaults and type-side validation according to
MakeOptions.
Gotchas
Throws an Error with the schema issue in its cause when validation
fails. Schema validation failures use the generic message
"Schema validation failed"; format the cause explicitly with
SchemaIssue.makeFormatterDefault() when human-readable details are needed.
Causes that contain defects, interruptions, or other non-schema reasons
throw with the underlying Cause attached instead.
@see ― BottomWithoutNew.makeOption — construct synchronously and discard validation details
@see ― BottomWithoutNew.makeEffect — construct through Effect when validation failure should stay in the error channel
make({
originId:string
originId:"meeting:2026-08-28:queue",
speaker:string
speaker:"Dan",
observers:readonlystring[]
observers:["Chad"],
locator:string
locator:"meeting://engineering/2026-08-28#queue",
activityAt:number|null
activityAt:1_777_334_400_000,
interpretation:string
interpretation:"proposal awaiting review",
}),
],
metadata:{
readonly [x: string]: unknown;
}
metadata:{
format:string
format:"markdown"},
recordedAt:number
recordedAt:1_777_420_800_000,
extractedAt?:number|undefined
extractedAt:1_777_420_801_000,
}),
});
const
constlookup:{
readonly_tag:"Found";
readonlypassages:readonlyMemoryPassage[];
}|{
readonly_tag:"NoMatch";
}|{
readonly_tag:"Unavailable";
readonlymessage:string;
}|{
readonly_tag:"InsufficientFreshness";
readonlymessage:string;
}
lookup:
typeMemoryLookup={
readonly_tag:"Found";
readonlypassages:readonlyMemoryPassage[];
}|{
readonly_tag:"NoMatch";
}|{
readonly_tag:"Unavailable";
readonlymessage:string;
}|{
readonly_tag:"InsufficientFreshness";
readonlymessage:string;
}
No-match, unavailable, and insufficient freshness are distinct consumer-visible outcomes.
Supplies model-visible reference context for one Turn without changing the
prompt that compaction covers or the history that the engine commits.
The engine treats the returned input as untrusted, validates it before
provider I/O, and includes it in the Turn's context and completion-reserve
admission. It never passes this input to the compaction summary Model. A
same-Turn provider-overflow retry reuses the loaded snapshot. Return an
empty Prompt when the Turn needs no references.
RunTransientContextHook<
classMemoryRecallError
A recall contract or essential-source requirement could not be satisfied.
Read in declaration/ranking order and retain whole passages that fit. Essential sources
must have a represented passage when they return matches, including exact duplicates.
Explicit passage authorities qualify source identity across readers; absent authority is
local to the reader declaration. Raw authorities stay in host passages, never rendered text.
maxSources bounds both reader declarations and authority-qualified selected sources. No-match is successful even when
essential. Optional unavailable/stale sources remain visible in outcomes. Nothing is cached.
Admitted conflicting identities are rejected even when an earlier passage does not fit the output budget.
maxInputBytes bounds cumulative JSON passage encodings before selection or identity retention;
its default is 16 MiB. Exhaustion stops validation and returns no partial context. Reader-owned
allocation and result decoding precede that input bound.
The default estimate is one token per UTF-8 byte. Supply the selected model's tokenizer
for tighter selection. The engine independently enforces its full per-call context budget.
The deadline owns a Scope, so temporary reader resources finalize on every exit path.
Transforms the value inside an effect by applying a function to it.
When to use
Use to transform an effect's success value with a function that returns a
plain value, producing a new effect without changing the original effect's
typed error or context requirements.
Details
map takes a function and applies it to the value contained within an
effect, creating a new effect with the transformed value.
It's important to note that effects are immutable, meaning that the original
effect is not modified. Instead, a new effect is returned with the updated
value.
@see ― sync for constructing layers from lazy values
@category ― constructors
@since ― 2.0.0
succeed(
classRunContextPreparation
Host-owned model-context preparation, independent of action-time Tool authorization.
Runs use this service when provided; durable coordinators capture it while their runtime
Layer is acquired. Implementations acquire dependencies in their Layer and preserve the
declared error tags. Layer acquisition failures belong to the providing Effect, not this union.
Without this service, Runs apply no host context loading. Provide ContextCompactor
separately to select native compaction; neither service replaces RunToolAuthorization.
Provide ProjectContextLive to the run. With an existing agent and input:
construnnable=AgentRuntime.run(agent,input).pipe(
Effect.provide(ProjectContextLive),
Effect.catchTags({
MemoryRecallError:handleRecallFailure,
CompactionError:handleCompactionFailure,
}),
);
The service declares AgentInputError | MemoryRecallError | CompactionError; method failures
retain their original tags and fields. RunContextPreparationError names that type union, not a
wrapper class. Effect.provide adds any errors from acquiring the Layer separately. Adapters
handle backend-specific failures or translate them into this contract. Providing a Layer does not
add undeclared service-method errors to a program’s error type.
For an application-specific error or requirement channel, the existing generic RunOptions.context
and RunOptions.transientContext hooks override the corresponding service fields for that Run.
Other service fields remain active. Attached children inherit the host context service, not the
parent’s per-Run overrides.
Memory.recall renders positional memory:N reference IDs and provenance for that one result.
RecalledMemory.outcomes separately reports what happened at each source. The rendered envelope
and every citation remain untrusted model input. Validate model claims against
RecalledMemory.passages before presenting them as sourced facts.
Source IDs are local to an authority. A host can set MemoryPassage.authority to share that
authority across readers; passages without it are scoped to their reader declaration’s id.
Deduplication, conflict detection, and the selected-source limit use authority-qualified IDs.
Two independent authorities can therefore both contain profile at revision 1 without being
merged or rejected. Direct readers must explicitly share an authority to deduplicate across
reader declarations. Authority is an identity boundary, not an authorization grant.
The rendered text substitutes positional memory-authority:N labels for private authority
values. These labels are local to the result and qualify its evidence origins; different labels
alone do not prove independent corroboration. RecalledMemory.passages retains explicit authority
for host-side composition and validation. Use RecalledMemory.text for model input, not a raw
serialization of those host passages.
MemoryRecallLimits.maxInputBytes separately bounds the aggregate UTF-8 JSON passage encodings
considered by one call, including omitted and duplicate candidates. It defaults to 16 MiB and can
be set up to 64 MiB. Exceeding it returns a typed budget error before retaining that candidate’s
identity or encoding, even when the source is optional. Reader allocation, result decoding, and
one candidate’s serialization occur before this check; it is not a whole-process heap limit.
Input-budget exhaustion stops validation and returns no partial context. Within admitted input,
conflicting known-revision identities fail even when an earlier passage exceeds the output budget.
Identity and conflict checks ignore JSON object member order, including nested metadata, while
preserving array order. Equivalent unknown-revision passages within one authority share one citation.
Keep authorization, credentials, and query policy inside an application service. This contract has
one read method; it does not create a durable copy, write to the corpus, or create embeddings:
No-match, unavailable, and insufficient freshness are distinct consumer-visible outcomes.
MemoryLookup,
classMemoryRecallError
A recall contract or essential-source requirement could not be satisfied.
MemoryRecallError,
classMemoryRecallLimits
Output bounds cover the complete rendered reference text, including citations and provenance.
MemoryRecallLimits,
}from"@yielded/agent/memory-reference";
import{
classRunContextPreparation
Host-owned model-context preparation, independent of action-time Tool authorization.
Runs use this service when provided; durable coordinators capture it while their runtime
Layer is acquired. Implementations acquire dependencies in their Layer and preserve the
declared error tags. Layer acquisition failures belong to the providing Effect, not this union.
Without this service, Runs apply no host context loading. Provide ContextCompactor
separately to select native compaction; neither service replaces RunToolAuthorization.
Supplies model-visible reference context for one Turn without changing the
prompt that compaction covers or the history that the engine commits.
The engine treats the returned input as untrusted, validates it before
provider I/O, and includes it in the Turn's context and completion-reserve
admission. It never passes this input to the compaction summary Model. A
same-Turn provider-overflow retry reuses the loaded snapshot. Return an
empty Prompt when the Turn needs no references.
Use when you need to define a context service key for a dependency that must
be provided by the surrounding context.
Details
Call Context.Service("Key") for a function-style key, or use the two-stage
form Context.Service<Self, Shape>()("Key") for class-style service
declarations. The returned key can be yielded as an Effect and passed to
Context.make, Context.add, and the Context getter functions.
Gotchas
The string key is the runtime identity of the service. Reusing the same key
string for unrelated services makes them occupy the same slot in a
Context.
The Effect interface defines a value that lazily describes a workflow or
job. The workflow requires some context R, and may fail with an error of
type E, or succeed with a value of type A.
When to use
Use when you need to represent a lazy, composable workflow that can require
services, fail with a typed error, or succeed with a typed value.
Details
Effect values model resourceful interaction with the outside world,
including synchronous, asynchronous, concurrent, and parallel interaction.
They use a fiber-based concurrency model, with built-in support for
scheduling, fine-grained interruption, structured concurrency, and high
scalability.
To run an Effect value, you need a Runtime, which is a type that is
capable of executing Effect values.
@category ― models
@since ― 2.0.0
Effect<
typeMemoryLookup={
readonly_tag:"Found";
readonlypassages:readonlyMemoryPassage[];
}|{
readonly_tag:"NoMatch";
}|{
readonly_tag:"Unavailable";
readonlymessage:string;
}|{
readonly_tag:"InsufficientFreshness";
readonlymessage:string;
}
No-match, unavailable, and insufficient freshness are distinct consumer-visible outcomes.
MemoryLookup,
classMemoryRecallError
A recall contract or essential-source requirement could not be satisfied.
MemoryRecallError>;
}
>()("app/ExternalCorpus"){}
const
constlimits:MemoryRecallLimits
limits=
classMemoryRecallLimits
Output bounds cover the complete rendered reference text, including citations and provenance.
Constructs a value from the make input representation synchronously.
When to use
Use when constructor input is trusted or when validation failure
should abort with a thrown Error.
Details
Applies constructor defaults and type-side validation according to
MakeOptions.
Gotchas
Throws an Error with the schema issue in its cause when validation
fails. Schema validation failures use the generic message
"Schema validation failed"; format the cause explicitly with
SchemaIssue.makeFormatterDefault() when human-readable details are needed.
Causes that contain defects, interruptions, or other non-schema reasons
throw with the underlying Cause attached instead.
@see ― BottomWithoutNew.makeOption — construct synchronously and discard validation details
@see ― BottomWithoutNew.makeEffect — construct through Effect when validation failure should stay in the error channel
Constructs a layer from an effect that produces a single service.
When to use
Use when you need to construct a Layer-provided service with an Effect,
dependencies, or scoped resource acquisition.
Details
This allows you to create a Layer from an Effect that produces a service.
The Effect is executed in the scope of the layer, allowing for proper
resource management.
@see ― effectContext for effectfully providing multiple services
@see ― effectDiscard for running construction work without providing services
@category ― constructors
@since ― 2.0.0
effect(
classRunContextPreparation
Host-owned model-context preparation, independent of action-time Tool authorization.
Runs use this service when provided; durable coordinators capture it while their runtime
Layer is acquired. Implementations acquire dependencies in their Layer and preserve the
declared error tags. Layer acquisition failures belong to the providing Effect, not this union.
Without this service, Runs apply no host context loading. Provide ContextCompactor
separately to select native compaction; neither service replaces RunToolAuthorization.
Provides a way to write effectful code using generator functions, simplifying
control flow and error handling.
When to use
Use when you want to write effectful code that looks and behaves like
synchronous code, while still handling asynchronous tasks, errors, and complex
control flow such as loops and conditions.
Generator functions work similarly to async/await but keep errors,
requirements, and interruption in the Effect type. You can yield* values
from effects and return the final result at the end.
Supplies model-visible reference context for one Turn without changing the
prompt that compaction covers or the history that the engine commits.
The engine treats the returned input as untrusted, validates it before
provider I/O, and includes it in the Turn's context and completion-reserve
admission. It never passes this input to the compaction summary Model. A
same-Turn provider-overflow retry reuses the loaded snapshot. Return an
empty Prompt when the Turn needs no references.
RunTransientContextHook<
classMemoryRecallError
A recall contract or essential-source requirement could not be satisfied.
Read in declaration/ranking order and retain whole passages that fit. Essential sources
must have a represented passage when they return matches, including exact duplicates.
Explicit passage authorities qualify source identity across readers; absent authority is
local to the reader declaration. Raw authorities stay in host passages, never rendered text.
maxSources bounds both reader declarations and authority-qualified selected sources. No-match is successful even when
essential. Optional unavailable/stale sources remain visible in outcomes. Nothing is cached.
Admitted conflicting identities are rejected even when an earlier passage does not fit the output budget.
maxInputBytes bounds cumulative JSON passage encodings before selection or identity retention;
its default is 16 MiB. Exhaustion stops validation and returns no partial context. Reader-owned
allocation and result decoding precede that input bound.
The default estimate is one token per UTF-8 byte. Supply the selected model's tokenizer
for tighter selection. The engine independently enforces its full per-call context budget.
The deadline owns a Scope, so temporary reader resources finalize on every exit path.
Transforms the value inside an effect by applying a function to it.
When to use
Use to transform an effect's success value with a function that returns a
plain value, producing a new effect without changing the original effect's
typed error or context requirements.
Details
map takes a function and applies it to the value contained within an
effect, creating a new effect with the transformed value.
It's important to note that effects are immutable, meaning that the original
effect is not modified. Instead, a new effect is returned with the updated
value.
Array of content parts that make up the user's message.
content:
recalled:Memory.RecalledMemory
recalled.
text:string
text }]),
),
),
};
return
classRunContextPreparation
Host-owned model-context preparation, independent of action-time Tool authorization.
Runs use this service when provided; durable coordinators capture it while their runtime
Layer is acquired. Implementations acquire dependencies in their Layer and preserve the
declared error tags. Layer acquisition failures belong to the providing Effect, not this union.
Without this service, Runs apply no host context loading. Provide ContextCompactor
separately to select native compaction; neither service replaces RunToolAuthorization.
Optional per-Turn reference context, excluded from history and compaction coverage.
transientContext });
}),
);
Provide the application’s ExternalCorpus Layer to ExternalCorpusMemoryLive, then provide that
closed Layer to an ephemeral Run or to DurableAgentRuntime.layerWithServices with
RunToolAuthorization. The durable runtime captures RunContextPreparation in its Scope.
Put hook, transientContext, and
compactor in the same service value when using all three.
The engine reloads transient context in every normal or grace Turn and after durable recovery,
after canonical context preparation and initial compaction succeed. Failure in that initial
phase does not read transient sources. Post-load admission can compact canonical history further
to make room for the references. This pass and a same-Turn provider-overflow retry reuse the
loaded snapshot. Each provider call still
has to fit contextTokenLimit; transient text participates in output-contract, run-status, token
budget, and completion-reserve admission. Oversized context fails before provider I/O.
Transient references never enter Thread history, canonical records, compaction coverage, or a
compaction summary request. Recovery reads the source again instead of replaying an earlier
snapshot. RunContextRequest.source is the current Attempt’s official pre-preparation history;
use its stable identities or an application-owned query when retrieval requires canonical durable
state.
Define namespaces with an application-owned identity Schema. Constructor inputs retain brands;
keys, writes, documents, access values, and index results retain the definition’s name, version,
and identity type. Definitions with the same identity fields but different names or versions are
not interchangeable.
Intersects a schema's output type with Brand.Brand<B> to prevent accidental
mixing of structurally identical types.
When to use
Use to make values decoded by an existing schema nominally distinct when the
schema already carries the runtime validation you need.
Gotchas
identifier must be a single concrete string literal. Widened strings,
unions, and open template literal types are rejected.
brand only narrows the TypeScript output type. It does not change the
schema's runtime AST or add runtime checks.
Schema representations and generated schema code omit the brand. Reapply
brand after rebuilding or generating a schema when the nominal type is
still required.
@see ― fromBrand for applying a Brand constructor's checks along with its branded type
Intersects a schema's output type with Brand.Brand<B> to prevent accidental
mixing of structurally identical types.
When to use
Use to make values decoded by an existing schema nominally distinct when the
schema already carries the runtime validation you need.
Gotchas
identifier must be a single concrete string literal. Widened strings,
unions, and open template literal types are rejected.
brand only narrows the TypeScript output type. It does not change the
schema's runtime AST or add runtime checks.
Schema representations and generated schema code omit the brand. Reapply
brand after rebuilding or generating a schema when the nominal type is
still required.
@see ― fromBrand for applying a Brand constructor's checks along with its branded type
Defines a struct schema from a map of field schemas.
Details
Each field value is a schema. Use
optionalKey
or
optional
to
mark fields as optional, and
mutableKey
to mark them as mutable.
The resulting schema's Type is a readonly object type with the fields'
decoded types. The Encoded form mirrors the field schemas' encoded types.
Declared fields may be inherited and are copied to own properties in the
output. The __proto__ field is accepted only when it is an own property.
Parsing does not guarantee that output keys retain their input order.
Constructs a value from the make input representation synchronously.
When to use
Use when constructor input is trusted or when validation failure
should abort with a thrown Error.
Details
Applies constructor defaults and type-side validation according to
MakeOptions.
Gotchas
Throws an Error with the schema issue in its cause when validation
fails. Schema validation failures use the generic message
"Schema validation failed"; format the cause explicitly with
SchemaIssue.makeFormatterDefault() when human-readable details are needed.
Causes that contain defects, interruptions, or other non-schema reasons
throw with the underlying Cause attached instead.
@see ― BottomWithoutNew.makeOption — construct synchronously and discard validation details
@see ― BottomWithoutNew.makeEffect — construct through Effect when validation failure should stay in the error channel
make("private")});
make takes decoded identity values and throws on invalid construction. decode(unknown)
decodes external identity input as an Effect with MemoryNamespaceError and no service
requirements. restore(address) validates a stored address against the specific definition,
including its identity codec, name, and version. It rejects noncanonical addresses and reports
wrong definitions or unsupported address formats separately. Validation does not authenticate
a principal. Two tenants still share the same TenantId type. The host must establish session
identity and authorization before constructing namespaces or access values. "private" is only
an application-defined scope name, not a built-in privacy policy.
Every adapter uses namespace.address, a branded, Schema-validated string. Its format is compact
JSON [1, definitionName, definitionVersion, encodedIdentity]. Object keys sort recursively in
UTF-16 code-unit order, including numeric-looking keys. Array order is preserved. Strings use
JSON escaping without Unicode normalization. JSON number serialization normalizes negative zero
to zero. Separator characters cannot join distinct identity fields into the same address.
Identity codecs must be deterministic, synchronous, service-free, and encode to JSON. Branded
Structs, records, arrays, and codecs such as Schema.DateFromString are supported. Encoding then
decoding normalizes constructor values through the identity codec. Another round trip must leave
the encoded identity unchanged. Schema-defined normalization, such as ignored excess Struct
fields, deliberately selects the same address. Non-JSON values such as undefined, non-finite
numbers, and bigint must be converted by the codec or are rejected.
Names contain 1–256 UTF-16 code units; definition versions are positive safe integers. The full
address is at most 4,096 UTF-8 bytes. Encoded identities allow at most 16 nested container levels
and 128 entries per container. These limits apply before storage or indexing. Changing a
definition version selects a distinct namespace, even for the same identity. It never interprets
old memory under a new Schema. Document revisions and SQLite’s storage-format version are separate.
MemoryKey.Wire, MemoryDocument.Wire, MemoryWrite.Wire, and the access/index .Wire Schemas
are explicitly heterogeneous transport representations. Their namespaces contain only the
canonical address, not a recovered application identity type. Adapter authors use
MemoryReader.fromAdapter, MemoryWriter.fromAdapter, and SemanticMemoryIndex.fromAdapter
to validate results and restore the caller’s namespace type. For persisted documents outside a
port, restore a namespace through its definition, then call MemoryDocument.restore(namespace, input).
Never assert a wire value into an application namespace type. Generic types without an explicit
namespace parameter describe heterogeneous values; use MemoryKey<typeof conversations> and
the equivalent document/write/access/index types for family-specific application APIs.
Namespace identities and addresses can contain sensitive identifiers. They are not retrieval
parameters for the model and are not automatically added to recall text, logs, or telemetry.
The framework does not supply a registry, tenant membership checks, wildcard search, or a fixed
memory taxonomy.
This changes SQLite memory storage to format 2. Format-1 memory data and old string-namespace
prepared activity outputs are incompatible and fail decoding. Reset affected development memory
and processor data before reusing it. There is no migration or raw-string fallback. Existing
Thread history is a separate retention concern.
MemoryReader and MemoryWriter are separate optional capabilities. Use a reader to validate
search or cache candidates against the current source. A writer is appropriate only when its
adapter can atomically check an expected revision and retain idempotency receipts. A read-only
corpus needs no writer. An external memory service can implement these ports without copying its
corpus into a framework store.
The host selects a namespace and access scope. A document explicitly lists the scopes allowed to
recall it; an empty list grants none. No scope name, shared persona, channel, or DM is enabled by
default. Call revalidateMemoryLookup(candidates, access, limits) inside the reader supplied to
Memory.recall, immediately before composition. It requires only MemoryReader. The optional
third argument accepts maxInputBytes from the recall limits, defaulting to 16 MiB and capped
at 64 MiB. Revalidation reads one authoritative source at a time and checks aggregate UTF-8
replacement JSON before retaining it, including duplicate passages. Exceeding this bound fails
with MemoryRecallError reason budget before reading later source groups. A single reader
result and its schema decoding precede the aggregate retention bound.
Validation binds each returned passage’s private authority to the host-selected namespace,
replacing any candidate-supplied authority. Combining independently authorized namespaces
therefore preserves their distinct source identities without exposing namespace values in model text.
Validation reloads each candidate’s source, excludes missing, withdrawn, or access-revoked
documents, and replaces stale text with the current document. Even a same-revision excerpt gets
its attribution and metadata from the current source. It survives only if its text occurs there.
The usual recall budget can omit a replacement that no longer fits. Source failures stay typed;
the consumer must explicitly choose any optional fallback.
import{
importMemoryNamespace
MemoryNamespace }from"@yielded/agent";
import{
classMemoryContent
Readable authoritative content, independent of any index, model, or fixed memory taxonomy.
Recording/extraction time never substitutes for the original source activity time.
Host-defined recall visibility label. A scope identifies access policy; it does not grant it.
MemoryScope,
classMemoryWriter
Optional conditional writer. Implement only where atomic expected-revision checks and
durable idempotency receipts can be guaranteed. Apply authorization before calling it.
Reconcile an existing operation receipt before evaluating tombstones or expected revisions:
identical commands return the original result; changed commands fail MemoryOperationConflict.
Original results include content, even for a historical Put replayed after withdrawal;
replay does not change the current head. Revalidate a source before using recalled content.
A failed acknowledgement can hide a committed change: retain and retry the exact command.
Successful withdrawal excludes checks begun afterward; already captured views may finish.
Receipts and original Thread history are separate retention concerns.
Readable authoritative content, independent of any index, model, or fixed memory taxonomy.
Recording/extraction time never substitutes for the original source activity time.
Optional conditional writer. Implement only where atomic expected-revision checks and
durable idempotency receipts can be guaranteed. Apply authorization before calling it.
Reconcile an existing operation receipt before evaluating tombstones or expected revisions:
identical commands return the original result; changed commands fail MemoryOperationConflict.
Original results include content, even for a historical Put replayed after withdrawal;
replay does not change the current head. Revalidate a source before using recalled content.
A failed acknowledgement can hide a committed change: retain and retry the exact command.
Successful withdrawal excludes checks begun afterward; already captured views may finish.
Receipts and original Thread history are separate retention concerns.
Constructs a value from the make input representation synchronously.
When to use
Use when constructor input is trusted or when validation failure
should abort with a thrown Error.
Details
Applies constructor defaults and type-side validation according to
MakeOptions.
Gotchas
Throws an Error with the schema issue in its cause when validation
fails. Schema validation failures use the generic message
"Schema validation failed"; format the cause explicitly with
SchemaIssue.makeFormatterDefault() when human-readable details are needed.
Causes that contain defects, interruptions, or other non-schema reasons
throw with the underlying Cause attached instead.
@see ― BottomWithoutNew.makeOption — construct synchronously and discard validation details
@see ― BottomWithoutNew.makeEffect — construct through Effect when validation failure should stay in the error channel
Optional conditional writer. Implement only where atomic expected-revision checks and
durable idempotency receipts can be guaranteed. Apply authorization before calling it.
Reconcile an existing operation receipt before evaluating tombstones or expected revisions:
identical commands return the original result; changed commands fail MemoryOperationConflict.
Original results include content, even for a historical Put replayed after withdrawal;
replay does not change the current head. Revalidate a source before using recalled content.
A failed acknowledgement can hide a committed change: retain and retry the exact command.
Successful withdrawal excludes checks begun afterward; already captured views may finish.
Receipts and original Thread history are separate retention concerns.
The same operation ID must always carry exactly the same Schema-encoded command.
operationId,
expectedRevision:string
expectedRevision,
reason:string
reason:"Withdrawn by the source owner",
});
});
Create a source with Put and expectedRevision: null. Later writes use the current revision;
a competing edit returns MemoryConflict without discarding the winning edit. Every replacement
records its predecessor reference. modifiedAt tracks the update, while the caller’s original
activity, recording, and extraction times remain separate. Applications decide how to correct
attribution, resolve conflicting claims, and age discussions or commitments. Timestamps alone
never choose a winning claim.
Retry an uncertain write with its original operationId and exactly the same Schema-encoded
command. A successful replay returns the original receipt’s document and does not undo later
edits or withdrawal. Reusing an operation ID for different content returns
MemoryOperationConflict. Revalidate the returned document before recall because a receipt can
describe an older revision.
Withdrawal is terminal for that source ID within its namespace. A committed withdrawal excludes the
source from validation checks begun afterward. The same rule applies after access revocation.
An already captured view, including a same-Turn provider retry, may finish. This guarantee needs
an authoritative reader; an eventually consistent service must refuse a view it cannot validate.
Do not run the SQLite reader inside a caller-owned stale snapshot transaction.
Withdrawal governs future recall. Original Thread records, past model outputs, idempotency
receipts, and backups have separate retention policies. Sensitive-information screening is best
effort and does not authorize sharing or guarantee privacy.
For a local persistent source, install the optional SQLite adapter:
Feeds the output services of the dependency layer into the requirements of
this layer, returning a layer that only provides the services from this layer.
When to use
Use when you need to hide an implementation dependency layer from callers.
Details
In serviceLayer.pipe(Layer.provide(dependencyLayer)), the dependency layer is
built first and is used to satisfy the requirements of serviceLayer.
Builds a layer from a node SQLite client configuration, providing both SqliteClient and the generic SqlClient service.
@category ― layers
@since ― 4.0.0
layer({
SqliteClientConfig.filename: string
filename:"memory.sqlite"})),
);
memoryStoreLayer provides both ports and creates only its own memory tables. It does not
initialize Thread history or a Submission Ledger. memoryReaderLayer checks an existing schema
without creating tables or starting a write transaction, and supports SqliteClient.layer({ filename, readonly: true }). It fails with MemoryStorageError when the schema is absent or
incompatible; initialize it through memoryStoreLayer in the writer process first.
The connection belongs to its Layer’s Scope. The adapter rejects a change before writing when
its canonical command, document, or receipt-result JSON exceeds 16,777,216 JavaScript string code
units. memoryStoreLayerWithFailpoints accepts a MemoryMutationFailpoint service for transaction
and lost-acknowledgement tests. Replayed receipts must match their original command’s predecessor,
result kind, content, locator, scopes, and withdrawal reason; mismatches fail as corrupt data.
Recall and validation helpers add named Effect spans without source text or metadata annotations.
For shared Worker memory, use the Cloudflare memory owner.
It validates an entire candidate batch locally and returns one attributed response over one RPC.
RecalledMemory.outcomes reports source availability and selected, deduplicated, and omitted counts;
the host decides which diagnostics to retain and who can inspect them.
Remembering separates durable admission from extraction and memory updates. The foreground
submits an identity-bound intent and receives a queued acknowledgement after persistence succeeds.
Queued means accepted for processing. It does not mean that a fact was accepted, saved, or made
available to another Thread. Admission adds bounded persistence work and can fail with a typed error.
Use Remembering.admit(store, intent) from @yielded/agent/remembering for admission and
Remembering.make({ proposal, loadSource, extract, merge, cleanup }).advance(...) for a finite
worker pass. The RememberingStore module defines the portable Schemas and injectable port.
Use native Effect AI extraction and source-aware profile callbacks. Provide
RememberingStore.MutationFailpoint.layer in production and replace it for fault tests.
Automatic remembering follows the host’s committed source activity and outbox. It needs no memory
Tool or extra model turn. The outbox retains activity when admission is unavailable or full;
that backlog does not turn a completed chat response into a failure. Explicit remember actions
report admission failure instead of claiming success.
The host runs a finite processing pass in a separate Scope with its own concurrency and model
budgets. It owns discovery, source order, job quotas, retry deadlines, parking, and wake repair.
Do not await processing after AgentRuntime.run: an awaited callback still delays the response.
Do not hold a producer lock, database transaction, or all foreground provider permits while
extracting, checking evidence, reading profiles, writing, retrying conflicts, or cleaning up.
The protocol saves two different values:
An extracted proposal, encoded with the application’s Schema and bound to the admitted source.
The exact prepared MemoryWrite, including its operation ID, expected revision, scopes,
content, and content timestamps, before dispatch to MemoryWriter.
Unknown write outcomes retry that saved command unchanged. Only a definite MemoryConflict
allows a new operation ID and rebase against the latest target. Rebase retains the saved proposal
and does not repeat extraction. The application supplies source-aware merging so concurrent source
contributions and human corrections survive. An operation-ID/content mismatch remains
MemoryOperationConflict; it is not permission to create another command.
loadSource checks the current authorized source after extraction and before saving a new command.
It can return an authoritative invalidation event, which the worker durably admits. A saved command
is already an uncertain write and must reconcile even if the source is now unavailable. Source
changes after preparation therefore rely on durable suppression and current-source recall checks.
Extraction may return null when there is no accepted fact; that finishes without reading a target.
The application also supplies canonical source loading, fact acceptance, authorization, and
conditional cleanup. Evidence must identify a known source revision and a literal quote or range
from that source. The model cannot select a tenant, target, or authority. A valid quote proves
provenance, not the truth of an extracted claim.
Source edits, deletion, revocation, and Forget require durable suppression and cleanup admission
before acknowledging the source event. Suppression does not discard an uncertain command:
reconciliation must still establish its outcome and remove obsolete source-owned contributions.
Current-source recall checks exclude invalid evidence while cleanup is pending. Human corrections
have independent provenance and survive source cleanup. Disable new extraction separately from
required reconciliation and cleanup.
Active job removal must retain bounded source-to-target references, so later invalidation finds
completed contributions without a prior read. Retain those references, suppression, and admission
and write receipts throughout the host’s supported replay, backfill, and restore window. Reject
new work at capacity without evicting existing obligations. Hosts define source-position authority.
Sequence numbers are ordered only within the same opaque authority generation. Different generations
are incomparable, and revision strings are never ordered. The host fences old workers and performs
any restore or authority cutover explicitly.
An old database snapshot cannot prove that no later Forget or revocation occurred. Verify its
lineage against the current source authority outside that restored snapshot and reject incompatible
state before processing or recall. The protocol supplies no migration or automatic authority cutover.
Recall remains the existing transient read path. Load current permitted memory and run the
application’s grouped canonical-source checks without draining jobs, waiting for readiness, or
refreshing an index. Track first token, completed response, admission duration, and
source-to-authorized-recall delay separately. Healthy background progress and cross-Thread
freshness depend on the host’s scheduling and source availability.
Callbacks retain their typed errors and Effect service requirements. Defects and interruption
remain distinct from expected failure; a processing deadline interrupts cooperative work and runs
its finalizers. The helpers use named Effect spans without attaching source text, proposals,
profiles, or private namespace identities. Hosts choose retry policy and operational metrics.
processCommittedActivity is an optional, finite pass over one application-selected Thread.
The host chooses the processor ID and version, eligible records, extractor, destination, sharing
scope, invocation schedule, and Thread discovery. No background worker starts when the package
is imported. A read-only corpus or direct Markdown recall needs none of these services.
The pass claims its own processor lease and receives any pending output atomically with that
claim. It captures ThreadStore.inspectTail once and reads
bounded, contiguous pages through that prefix. Records appended afterward belong to a later
pass. Pending work beyond the captured tail fails as noncontiguous, including when progress and
Thread storage were restored to different points. PersistentHistory exposes the batch from a
successful Run together; durable Runs expose
incremental committed records. A record’s presence is evidence of its commit, not evidence that
the whole Run succeeded. Eligibility rules must account for that distinction.
For each record the processor saves a Schema-encoded extraction, applies that saved output, and
then advances its separate cursor. The work ID depends on processor, version, Thread, and
sequence, never the worker or clock. Advancing clears pending output in the same transaction;
there is no separate pending-work read per record. A saved output wins over re-extraction after restart. Its
canonical record digest excludes the adapter’s opaque observation cursor. Another processor
version has independent progress; changing a version is an application decision about
reprocessing and destination identities.
The destination must reconcile the work ID durably before returning. If application and progress
storage are separate, application can repeat after a lost acknowledgment. Keep its receipts for
as long as pending output can return, including supported backup/restore windows. Conditional
writes must prevent delayed work from overwriting later corrections or withdrawals. The SQLite
memory writer supplies those properties; an ordinary non-idempotent external effect does not.
This example opts a structured Dan–Chad discussion into a scope the host also grants Tim. Its
extraction policy accepts only original user statements. An assistant repeating the statement
does not become another witness. Applications that extract assistant references should retain
the original originId instead of assigning independent evidence identity.
import{
importMemoryNamespace
MemoryNamespace }from"@yielded/agent";
import{
classMemoryContent
Readable authoritative content, independent of any index, model, or fixed memory taxonomy.
Recording/extraction time never substitutes for the original source activity time.
Optional conditional writer. Implement only where atomic expected-revision checks and
durable idempotency receipts can be guaranteed. Apply authorization before calling it.
Reconcile an existing operation receipt before evaluating tombstones or expected revisions:
identical commands return the original result; changed commands fail MemoryOperationConflict.
Original results include content, even for a historical Put replayed after withdrawal;
replay does not change the current head. Revalidate a source before using recalled content.
A failed acknowledgement can hide a committed change: retain and retry the exact command.
Successful withdrawal excludes checks begun afterward; already captured views may finish.
Receipts and original Thread history are separate retention concerns.
Process one bounded committed prefix of one application-selected Thread. Nothing runs until
invoked, and no daemon, global Thread directory, admission ledger, or engine checkpoint is
involved. PersistentHistory makes a successful Run's batch visible together; durable Runs
expose incremental committed records. The application decides what each record means.
A durable pending output wins over a new extraction after restart. Apply finishes before
progress advances, so separate output stores require durable idempotency. This does not
promise exactly-once external side effects. Each callback owns a Scope; the finite pass has
a timeout and a longer lease. Claim release has a separate 500ms deadline; failure leaves
the bounded lease to expire.
// The application owns this message format and which Threads use it.
const
constStatement:Schema.Struct<{
readonlyspeaker:Schema.NonEmptyString;
readonlyobserver:Schema.NonEmptyString;
readonlytext:Schema.NonEmptyString;
readonlyactivityAt:Schema.NullOr<Schema.Finite>;
readonlyinterpretation:Schema.NonEmptyString;
}>
Statement=
importSchema
Schema.
functionStruct<{
readonlyspeaker:Schema.NonEmptyString;
readonlyobserver:Schema.NonEmptyString;
readonlytext:Schema.NonEmptyString;
readonlyactivityAt:Schema.NullOr<Schema.Finite>;
readonlyinterpretation:Schema.NonEmptyString;
}>(fields:{
readonlyspeaker:Schema.NonEmptyString;
readonlyobserver:Schema.NonEmptyString;
readonlytext:Schema.NonEmptyString;
readonlyactivityAt:Schema.NullOr<Schema.Finite>;
readonlyinterpretation:Schema.NonEmptyString;
}):Schema.Struct<...>
Defines a struct schema from a map of field schemas.
Details
Each field value is a schema. Use
optionalKey
or
optional
to
mark fields as optional, and
mutableKey
to mark them as mutable.
The resulting schema's Type is a readonly object type with the fields'
decoded types. The Encoded form mirrors the field schemas' encoded types.
Declared fields may be inherited and are copied to own properties in the
output. The __proto__ field is accepted only when it is an own property.
Parsing does not guarantee that output keys retain their input order.
Decodes an unknown input against a schema, returning an Effect that
succeeds with the decoded value or fails with a
SchemaError
.
When to use
Use when you need to decode unknown input in an Effect whose failure
channel is SchemaError.
Details
Prefer
decodeEffect
when the input is already typed as the schema's
Encoded type.
Options may be provided either when creating the decoder or when applying it;
application options override creation options.
@see ― SchemaParser.decodeUnknownEffect for the adapter that fails with SchemaIssue.Issue directly
Readable authoritative content, independent of any index, model, or fixed memory taxonomy.
Recording/extraction time never substitutes for the original source activity time.
Constructs a value from the make input representation, returning validation
failures in the Effect error channel.
When to use
Use when construction must compose with other Effect operations or when
the result supplies a nested constructor default. Otherwise, use
BottomWithoutNew.make
when invalid construction should throw.
Details
SchemaParser uses SchemaIssue.Issue as its canonical structured failure,
and this method exposes the same representation directly. Keeping the issue
unwrapped lets an enclosing schema attach its own path when the effect is
used with
withConstructorDefault
. It also avoids allocating a
SchemaError and keeps its formatting path out of the resulting bundle.
Gotchas
Unlike the decoding helpers in Schema, validation failures are not wrapped
in SchemaError. Map the issue to SchemaError or to a domain-specific error
when a wrapped error is needed at the application boundary.
@see ― BottomWithoutNew.make — construct synchronously when validation failure should throw
@see ― BottomWithoutNew.makeOption — construct synchronously and discard validation details
Encodes a typed input (the schema's Type) against a schema, returning an
Effect that succeeds with the encoded value or fails with a
SchemaError
.
When to use
Use when you need to encode input already typed as the schema's Type in
an Effect whose failure channel is SchemaError.
Details
For unknown input use
encodeUnknownEffect
.
Options may be provided either when creating the encoder or when applying it;
application options override creation options.
@see ― SchemaParser.encodeEffect for the adapter that fails with SchemaIssue.Issue directly
@category ― encoding
@since ― 4.0.0
encodeEffect(
classMemoryContent
Readable authoritative content, independent of any index, model, or fixed memory taxonomy.
Recording/extraction time never substitutes for the original source activity time.
Decodes an unknown input against a schema, returning an Effect that
succeeds with the decoded value or fails with a
SchemaError
.
When to use
Use when you need to decode unknown input in an Effect whose failure
channel is SchemaError.
Details
Prefer
decodeEffect
when the input is already typed as the schema's
Encoded type.
Options may be provided either when creating the decoder or when applying it;
application options override creation options.
@see ― SchemaParser.decodeUnknownEffect for the adapter that fails with SchemaIssue.Issue directly
Readable authoritative content, independent of any index, model, or fixed memory taxonomy.
Recording/extraction time never substitutes for the original source activity time.
Optional conditional writer. Implement only where atomic expected-revision checks and
durable idempotency receipts can be guaranteed. Apply authorization before calling it.
Reconcile an existing operation receipt before evaluating tombstones or expected revisions:
identical commands return the original result; changed commands fail MemoryOperationConflict.
Original results include content, even for a historical Put replayed after withdrawal;
replay does not change the current head. Revalidate a source before using recalled content.
A failed acknowledgement can hide a committed change: retain and retry the exact command.
Successful withdrawal excludes checks begun afterward; already captured views may finish.
Receipts and original Thread history are separate retention concerns.
Constructs a value from the make input representation synchronously.
When to use
Use when constructor input is trusted or when validation failure
should abort with a thrown Error.
Details
Applies constructor defaults and type-side validation according to
MakeOptions.
Gotchas
Throws an Error with the schema issue in its cause when validation
fails. Schema validation failures use the generic message
"Schema validation failed"; format the cause explicitly with
SchemaIssue.makeFormatterDefault() when human-readable details are needed.
Causes that contain defects, interruptions, or other non-schema reasons
throw with the underlying Cause attached instead.
@see ― BottomWithoutNew.makeOption — construct synchronously and discard validation details
@see ― BottomWithoutNew.makeEffect — construct through Effect when validation failure should stay in the error channel
Constructs a value from the make input representation synchronously.
When to use
Use when constructor input is trusted or when validation failure
should abort with a thrown Error.
Details
Applies constructor defaults and type-side validation according to
MakeOptions.
Gotchas
Throws an Error with the schema issue in its cause when validation
fails. Schema validation failures use the generic message
"Schema validation failed"; format the cause explicitly with
SchemaIssue.makeFormatterDefault() when human-readable details are needed.
Causes that contain defects, interruptions, or other non-schema reasons
throw with the underlying Cause attached instead.
@see ― BottomWithoutNew.makeOption — construct synchronously and discard validation details
@see ― BottomWithoutNew.makeEffect — construct through Effect when validation failure should stay in the error channel
Decodes a typed input (the schema's Encoded type) against a schema
synchronously, returning the decoded value or throwing a
SchemaError
for schema mismatches.
When to use
Use when you already have input typed as the schema's Encoded type and
want schema mismatches to throw SchemaError synchronously.
Details
For unknown input use decodeUnknownSync.
Only service-free schemas can be decoded synchronously. Options may be
provided either when creating the decoder or when applying it; application
options override creation options.
Gotchas
Non-schema failures may throw a runtime failure instead of SchemaError.
@see ― SchemaParser.decodeSync for the adapter that throws an Error whose cause is SchemaIssue.Issue
Constructs a value from the make input representation synchronously.
When to use
Use when constructor input is trusted or when validation failure
should abort with a thrown Error.
Details
Applies constructor defaults and type-side validation according to
MakeOptions.
Gotchas
Throws an Error with the schema issue in its cause when validation
fails. Schema validation failures use the generic message
"Schema validation failed"; format the cause explicitly with
SchemaIssue.makeFormatterDefault() when human-readable details are needed.
Causes that contain defects, interruptions, or other non-schema reasons
throw with the underlying Cause attached instead.
@see ― BottomWithoutNew.makeOption — construct synchronously and discard validation details
@see ― BottomWithoutNew.makeEffect — construct through Effect when validation failure should stay in the error channel
make({
maxRecords:number
maxRecords:128,
pageSize:number
pageSize:16,
timeoutMillis:number
timeoutMillis:30_000,
leaseMillis:number
leaseMillis:31_000,
});
// Supply a unique owner for each worker lifetime and the application's Layers.
Process one bounded committed prefix of one application-selected Thread. Nothing runs until
invoked, and no daemon, global Thread directory, admission ledger, or engine checkpoint is
involved. PersistentHistory makes a successful Run's batch visible together; durable Runs
expose incremental committed records. The application decides what each record means.
A durable pending output wins over a new extraction after restart. Apply finishes before
progress advances, so separate output stores require durable idempotency. This does not
promise exactly-once external side effects. Each callback owns a Scope; the finite pass has
a timeout and a longer lease. Claim release has a separate 500ms deadline; failure leaves
the bounded lease to expire.
Must durably reconcile workId before returning, using atomic idempotency and conditional
writes. This may run again after any lost acknowledgement. A stale invocation can finish
only the already pinned output; it must not overwrite a later correction or withdrawal.
Retain reconciliation evidence for the lifetime of pending work, including any supported
backup/restore window. Returning before durable application would permit skipped output.
apply});
The optional SQLite progress Layer can share a connection with the memory writer. Supply the
host’s existing ThreadStore and Crypto Layer to the pass as well; the processor never uses
Thread ownership epochs, SubmissionLedger, or engine checkpoints for its own progress.
Combines all the provided layers concurrently, creating a new layer with
merged input, error, and output types.
When to use
Use when you need to combine multiple independent layers.
Details
All layers are built concurrently, and their outputs are merged into a single layer.
If multiple merged layers depend on the same layer value, that dependency is
shared by default. Reuse a named layer value when you want services to share
the same resource, such as one database pool.
Feeds the output services of the dependency layer into the requirements of
this layer, returning a layer that only provides the services from this layer.
When to use
Use when you need to hide an implementation dependency layer from callers.
Details
In serviceLayer.pipe(Layer.provide(dependencyLayer)), the dependency layer is
built first and is used to satisfy the requirements of serviceLayer.
Builds a layer from a node SQLite client configuration, providing both SqliteClient and the generic SqlClient service.
@category ― layers
@since ― 4.0.0
layer({
SqliteClientConfig.filename: string
filename:"memory.sqlite"})),
);
Every claim acquisition allocates a fresh fencing epoch, including reacquisition by the same
owner after release. Expired or superseded workers cannot replace pending output or advance
progress. A destination invocation already in flight may finish the saved output, so its own
idempotency and conditional writes remain required. Extraction and application each own a Scope;
the pass has a deadline and release gets at most another 500ms. If release fails, the lease
expires. The failpoint-enabled Layer exposes initialization and each mutation before, inside,
and after its transaction for recovery tests.
SQLite rejects activity progress whose JSON exceeds 16,777,216 JavaScript string code units before
writing, with ActivityStoreError reason invalid-input. Rejected writes leave prior progress intact.
ActivityProcessorStore.inspect exposes the per-processor, per-version, per-Thread cursor,
pending work, and last advancement time. A successful pass reports its captured tail, through
sequence, and remaining records in that prefix. These are per-Thread watermarks, not a global
freshness promise. Process selected Threads with bounded Effect.forEach and handle each pass’s
typed result independently when one failed Thread should not hold back others.
For the example workflow, the healthy commit-to-recallable target is 60 seconds. Hosts must
measure that interval from the source commit to successful authoritative recall and choose a
schedule that meets it. Recorded, extracted, advanced, indexed, and accessed times describe
different events; none replaces the original activity time. An embedding index has its own
progress and readiness, and must not advance this extraction cursor.
indexMemorySource and querySemanticMemory use the pinned upstream Effect AI
EmbeddingModel. Supply its provider Layer directly. Direct loading, keyword retrieval, external
attributed passages, and the cross-Thread workflow above need no embedding model or vector index.
The framework does not define another provider abstraction or impose a ranking or aging policy.
The host binds SemanticMemoryProfile to the actual provider, model revision, dimensions, and
chunking configuration. Rebuild when any of those change. Matching dimensions alone does not
make two models compatible. Provider configuration overrides must not silently change the model
behind a live index. Treat different preprocessing or precision settings as a new profile identity.
Choose chunk sizes within the selected provider’s input limits. Read-only external sources can
implement MemoryReader without a writer; sources with unknown revisions should use direct
passage retrieval instead of this index.
Rebuild one selected source through the native Effect EmbeddingModel. The host binds the
index profile to that provider's immutable model revision. A fresh Layer starts empty.
Every invocation rebuilds; the host owns source discovery, scheduling, and freshness policy.
Chunking and embedding leave the last successful index intact. A final authoritative read
rejects a source changed during embedding, then replace atomically exchanges its chunks.
An independent source can still change between that read and replacement;
querySemanticMemory always revalidates and excludes such stale candidates.
No model or source text is attached to telemetry. Errors retain native provider/index types.
Query an optional derivative index, then read each distinct source once. Attribution and
metadata always come from that current source. Revision, generation, namespace, access,
locator, and exact UTF-8 excerpt checks run before returning any passage. Older candidates
are omitted rather than assigning their similarity score to changed text.
Process candidates in source groups, retain only passage excerpts, and restore index rank.
maxSourceBytes bounds aggregate UTF-8 JSON for distinct authorized sources with matching
generation/revision/locator candidates. Its default is 16 MiB; exhaustion returns no partial
result. Reader allocation, decoding, and one source serialization precede this bound.
Compose result.lookup through Memory.recall to enforce the final rendered item/byte/token
budget and overall deadline. An empty result says nothing about undiscovered sources.
Checks begun before an acknowledged correction/withdrawal may finish with their already
captured source view.
Rebuild one selected source through the native Effect EmbeddingModel. The host binds the
index profile to that provider's immutable model revision. A fresh Layer starts empty.
Every invocation rebuilds; the host owns source discovery, scheduling, and freshness policy.
Chunking and embedding leave the last successful index intact. A final authoritative read
rejects a source changed during embedding, then replace atomically exchanges its chunks.
An independent source can still change between that read and replacement;
querySemanticMemory always revalidates and excludes such stale candidates.
No model or source text is attached to telemetry. Errors retain native provider/index types.
Constructs a value from the make input representation synchronously.
When to use
Use when constructor input is trusted or when validation failure
should abort with a thrown Error.
Details
Applies constructor defaults and type-side validation according to
MakeOptions.
Gotchas
Throws an Error with the schema issue in its cause when validation
fails. Schema validation failures use the generic message
"Schema validation failed"; format the cause explicitly with
SchemaIssue.makeFormatterDefault() when human-readable details are needed.
Causes that contain defects, interruptions, or other non-schema reasons
throw with the underlying Cause attached instead.
@see ― BottomWithoutNew.makeOption — construct synchronously and discard validation details
@see ― BottomWithoutNew.makeEffect — construct through Effect when validation failure should stay in the error channel
Read in declaration/ranking order and retain whole passages that fit. Essential sources
must have a represented passage when they return matches, including exact duplicates.
Explicit passage authorities qualify source identity across readers; absent authority is
local to the reader declaration. Raw authorities stay in host passages, never rendered text.
maxSources bounds both reader declarations and authority-qualified selected sources. No-match is successful even when
essential. Optional unavailable/stale sources remain visible in outcomes. Nothing is cached.
Admitted conflicting identities are rejected even when an earlier passage does not fit the output budget.
maxInputBytes bounds cumulative JSON passage encodings before selection or identity retention;
its default is 16 MiB. Exhaustion stops validation and returns no partial context. Reader-owned
allocation and result decoding precede that input bound.
The default estimate is one token per UTF-8 byte. Supply the selected model's tokenizer
for tighter selection. The engine independently enforces its full per-call context budget.
The deadline owns a Scope, so temporary reader resources finalize on every exit path.
Query an optional derivative index, then read each distinct source once. Attribution and
metadata always come from that current source. Revision, generation, namespace, access,
locator, and exact UTF-8 excerpt checks run before returning any passage. Older candidates
are omitted rather than assigning their similarity score to changed text.
Process candidates in source groups, retain only passage excerpts, and restore index rank.
maxSourceBytes bounds aggregate UTF-8 JSON for distinct authorized sources with matching
generation/revision/locator candidates. Its default is 16 MiB; exhaustion returns no partial
result. Reader allocation, decoding, and one source serialization precede this bound.
Compose result.lookup through Memory.recall to enforce the final rendered item/byte/token
budget and overall deadline. An empty result says nothing about undiscovered sources.
Checks begun before an acknowledged correction/withdrawal may finish with their already
captured source view.
Constructs a value from the make input representation synchronously.
When to use
Use when constructor input is trusted or when validation failure
should abort with a thrown Error.
Details
Applies constructor defaults and type-side validation according to
MakeOptions.
Gotchas
Throws an Error with the schema issue in its cause when validation
fails. Schema validation failures use the generic message
"Schema validation failed"; format the cause explicitly with
SchemaIssue.makeFormatterDefault() when human-readable details are needed.
Causes that contain defects, interruptions, or other non-schema reasons
throw with the underlying Cause attached instead.
@see ― BottomWithoutNew.makeOption — construct synchronously and discard validation details
@see ― BottomWithoutNew.makeEffect — construct through Effect when validation failure should stay in the error channel
Constructs a value from the make input representation synchronously.
When to use
Use when constructor input is trusted or when validation failure
should abort with a thrown Error.
Details
Applies constructor defaults and type-side validation according to
MakeOptions.
Gotchas
Throws an Error with the schema issue in its cause when validation
fails. Schema validation failures use the generic message
"Schema validation failed"; format the cause explicitly with
SchemaIssue.makeFormatterDefault() when human-readable details are needed.
Causes that contain defects, interruptions, or other non-schema reasons
throw with the underlying Cause attached instead.
@see ― BottomWithoutNew.makeOption — construct synchronously and discard validation details
@see ― BottomWithoutNew.makeEffect — construct through Effect when validation failure should stay in the error channel
Transforms the value inside an effect by applying a function to it.
When to use
Use to transform an effect's success value with a function that returns a
plain value, producing a new effect without changing the original effect's
typed error or context requirements.
Details
map takes a function and applies it to the value contained within an
effect, creating a new effect with the transformed value.
It's important to note that effects are immutable, meaning that the original
effect is not modified. Instead, a new effect is returned with the updated
value.
Constructs a value from the make input representation synchronously.
When to use
Use when constructor input is trusted or when validation failure
should abort with a thrown Error.
Details
Applies constructor defaults and type-side validation according to
MakeOptions.
Gotchas
Throws an Error with the schema issue in its cause when validation
fails. Schema validation failures use the generic message
"Schema validation failed"; format the cause explicitly with
SchemaIssue.makeFormatterDefault() when human-readable details are needed.
Causes that contain defects, interruptions, or other non-schema reasons
throw with the underlying Cause attached instead.
@see ― BottomWithoutNew.makeOption — construct synchronously and discard validation details
@see ― BottomWithoutNew.makeEffect — construct through Effect when validation failure should stay in the error channel
make({
maxSources:number
maxSources:8,
maxItems:number
maxItems:8,
maxBytes:number
maxBytes:16_384,
maxTokens:number
maxTokens:4_096,
timeoutMillis:number
timeoutMillis:1_000,
}),
);
Provide the same index instance, MemoryReader, and native EmbeddingModel to both operations.
Refresh also requires Effect Crypto. The provider Layer owns its resources; the index belongs
to its Layer’s Scope. Captured index methods fail after that Scope closes. Put recall in the
transient-context hook above. The final envelope, including attribution and citations, must fit
Memory.recall’s item, UTF-8 byte, and token limits; the engine separately admits the full prompt.
essential: false permits explicitly returned unavailable outcomes. It does not swallow errors.
Map only intended expected failures to an Unavailable lookup in application policy.
SemanticQueryLimits.maxOutputBytes bounds aggregate UTF-8 JSON passage output before retention,
including repeated attribution and metadata. It defaults to 16 MiB, accepts at most 64 MiB, and
fails with SemanticMemoryError reason budget. Source-byte limits count each distinct source
once; they do not substitute for this output bound or the final rendered recall limits.
Chunking greedily packs complete Unicode codepoints up to maxChunkBytes. It neither summarizes
nor silently drops a source suffix. Chunk IDs include a digest of the whole profile and the
ordinal; candidates also carry source identity, revision, generation, and byte offsets. Indexing
checks source-byte and chunk-count limits before calling the provider. Returned vectors must
match the profile and have a positive finite norm. This simple chunker is a deterministic
baseline; it makes no sentence-boundary or relevance promise.
inMemorySemanticIndexLayer is a replaceable exact cosine adapter. It bounds all registered source
keys, including withdrawal tombstones, and all ready chunks. A search over its scan limit fails
instead of ranking an arbitrary prefix. Scores tie by source ID, revision, and chunk ordinal.
Configuration rejects maxChunks * profile.dimensions above 16,777,216 vector components before
allocating index state. For a 4,096-dimensional profile, set maxChunks to at most 4,096. This bounds
stored vectors, not total process memory or allocations made by callers.
maxSourceBytes caps the aggregate UTF-8 JSON of retained source identities, including terminal
tombstones. It defaults to 16 MiB and accepts at most 64 MiB. Replacement and withdrawal check
this bound atomically before changing the index. A rejected change leaves the prior source and
chunks intact; a smaller replacement releases identity capacity. Replaying a withdrawal does not
charge the same tombstone twice. Map keys, object overhead, and vector storage are not included
in this source-encoding budget.
The adapter holds no authoritative documents or attribution.
Refresh prepares chunks and embeddings before calling SemanticMemoryIndex.replace. Replacement
validates the profile and source revision, then exchanges all chunks atomically. Failed or cancelled
refreshes leave the last successful index intact. Older generations and divergent same-generation
identities are fenced. Withdrawal is terminal within the instance and blocks delayed replacements.
The index exposes no build epochs, publication states, inspection, or mutation failpoints.
Closing and recreating the Layer discards all chunks and tombstones;
rebuild from current authoritative sources before requiring complete semantic recall.
The index and source are independent. Refresh reads the source again before publication, but a
change can still occur between that read and the index write. Every query therefore rereads each
candidate source, checks namespace, access, revision, generation, locator, and exact excerpt, and
takes attribution and metadata from that source. Stale candidates are omitted; their old score is
never assigned to corrected text. A source correction may temporarily reduce recall until refresh
finishes. Missing, withdrawn, or revoked sources cannot pass checks begun after the authoritative
change. Already captured views may finish, as described under withdrawal. Returned passages bind
their private authority to the query’s authorized namespace, so downstream recall can combine
independent namespaces without confusing their source IDs. Recall renders only opaque authority labels.
Queries group candidates by source, read each source once, and restore the original index ranking
after validation. Full source documents and their excerpt-check encodings are local to one group.
SemanticQueryLimits.maxSourceBytes separately bounds the aggregate UTF-8 JSON of distinct
authorized sources with generation, revision, and locator matches. It defaults to 16 MiB and can
be set up to 64 MiB. Missing, withdrawn, unauthorized, and identity-stale sources are excluded
without consuming this budget. Exceeding it returns a typed budget error with no partial result.
Reader allocation, decoding, and one source’s serialization precede this check; it is not a
whole-process heap limit. The indexing limit with the same name bounds one source’s text instead.
SemanticQueryResult reports scanned chunks, excluded stale and unauthorized candidates, query
embedding usage when the provider supplies it. It makes no completeness claim;
the host owns discovery, refresh scheduling, and required freshness.
An empty index or no-match result does not prove the corpus has no relevant memory. No source text,
query text, attribution, or vectors are attached to the helpers’ Effect spans.
Deadlines interrupt cooperative work and run finalizers. A provider that cannot cancel native I/O
may need to drain its active call before finalizing; account for that in the host’s latency policy.
The reproducible tooling/semantic-memory-eval consumer compares direct, lexical, and real local
embedding recall on a frozen synthetic corpus. It separates warm query latency, cached-file cold
model startup, source-commit-to-recallable lag, background extraction/indexing, and injected slow or
failed requests. Its declared targets are 250 ms warm added recall, 3 seconds with a cold model
instance and cached files, and 60 seconds from a healthy source commit to recall. These are example
targets, not provider or production guarantees. The example reports misses and contradictory
retrievals; applications must choose their own decision, commitment, and aging policies.
Every application tool result, including MCP output, passes through toolResultBounds once before
history or durable storage. Results within the limit keep their encoded bytes. Larger results use
one canonical envelope:
{
"truncatedToolResult":true,
"originalBytes":412887,
"head":"...first half of the byte budget...",
"tail":"...last half..."
}
The model and journal see the same envelope. Replay therefore stays consistent. The default limit
is 50 KiB. Provider-executed tool results are exempt because the provider has already put them in
the response.
At 80 percent of a limit, the line asks the model to wrap up. The token warning uses the research
balance after reserving completion capacity. The runtime also warns when that balance cannot cover
another input as large as the last call.
runStatus defaults to "off". The optional status line is built for each request and never
enters canonical history. With chronological adapters, it is trailing system/developer guidance,
leaving the retained user/tool message available as a cache boundary. Other adapters receive it as a
trailing user message; account for their cache-boundary behavior when enabling it. Provider cache
settings remain host-owned, and changing other prompt content can still prevent reuse.
Host-enforced limits and BudgetWarning events remain active with either setting.
Crossing 80 percent emits one BudgetWarning event for that dimension. Turn, tool call, and token
exhaustion follow onExhaustion.
With "final-answer", an over-budget tool batch runs no handlers. The next request forbids tool
use, except for the definition’s singleton completion tool. Turn exhaustion allows one grace turn.
Token exhaustion completes from the breaching response when it already contains decodable output;
otherwise it allows the same single constrained turn.
The result and RunCompleted event report finishReason: "budget-exhausted".
Their exhausted field names the limit: "tokens", "turns", or "tool-calls".
Delegated child results carry the same marker through SubagentCompleted.exhausted and
projectResult. onExhaustion: "fail" rejects work after the breach. Duration and cost breaches
always fail because another model call would add time or cost.
With contextTokenLimit, the engine estimates the next prompt before every turn. Ordinary
append-only history starts from the last provider-reported input and estimates appended content.
Preparation and transient-context hooks use a fresh estimate. Full estimates exclude repeated
system messages removed from the outgoing request. Within a turn, the engine reuses
the history view and estimate until compaction changes them. The default compactor then:
clears old application tool results outside the preferred keepRecentTokens tail while keeping
message structure and call/result pairs;
if pruning is insufficient, makes one metered summary call and keeps the instruction prefix,
summary, and recent tail. The retained tail can exceed keepRecentTokens to keep user inputs
with their replies and tool calls with their results.
Compaction changes the model view. It never rewrites the thread log. CompactionPerformed
reports each reduction. DN and DC also append CompactionCreated, so later attempts and runs use
the same compacted view.
A summary must finish successfully and contain non-whitespace text. The interpreter charges its
usage before validating it. A rejected summary leaves the previous summary and coverage in place;
already committed pruning remains. All summaries, including custom strategy decisions, are limited
to 65,536 characters and fail with CompactionError above that bound. Summaries are never silently
truncated to fit.
The complete default summarizer request fits within 80,000 characters, including instructions,
transcript delimiters, and the previous summary. It retains the oldest and newest covered messages
and marks the omitted middle. Message and string-result previews are clipped before rendering;
oversized structured tool results receive an explicit omission marker. An oversized previous summary
is rejected before rendering. These limits change only the model view, leaving canonical evidence
intact.
If the provider reports context overflow, the engine may compact and retry once. Transport
ambiguity can duplicate that model call. A second rejection, or overflow without a definition
context limit or resolved modelCall allowance, fails as ContextOverflowError.
Install a ContextCompactor Layer to change the strategy, estimator, or summary model. The default
is ContextCompactor.layer. All AgentRuntime entry points also need a
Thread history policy.
The summary model’s Layer requirements stay visible. Its usage is charged under that model’s
provider and name.
A custom compact implementation emits CompactionDecision values. Each decision covers an
exclusive source prefix and clears old tool results, supplies a summary, or starts a fresh context
window. The interpreter rejects cuts through tool pairs, changes to protected instructions or input,
decisions that make no progress, and more than one prune followed by one replacement in a turn.
request.trigger distinguishes pressure, overflow, and an explicit requested rollover;
request.modelCallAllowed tells the strategy whether a separate summary call is admitted.
Summary calls must use
request.summarize so metering, response limits, and the run deadline still apply.
estimate must return a non-negative finite integer. Strategy failures use CompactionError.
Defects and interruption retain their Effect meaning.
Durable coordinators map the covered prefix to complete canonical records before committing a
decision. Summarization covers prior-run records. Pruning and rollover can also cover settled batches
inside the current run, preserving its original instructions and input. A transform or decision that
cannot map cleanly fails before the view changes. The canonical log remains append-only.
A completed Tool batch enters official history before the repeated-failure limit ends a Run,
including provider-executed results. A later Run may cover an incomplete prior-Run batch already
omitted from its prompt only when canonical records prove that prior Run ended after its final
response. This changes coverage eligibility without settling, rewriting, or replaying the old call.
Current-Run, nonterminal, and malformed post-terminal batches remain protected.
Provide the summary model’s client to CompactorLive. The same composition works with the
Node host Layer,
Cloudflare application layer, or
custom runtime assembly.
To use a prompt transform and a custom compactor together, provide RunContextPreparation and
ContextCompactor independently. The runtime captures both when its Layer is acquired and retains
them across replacement attempts. Providing a different compactor around a worker call does not
replace the host’s choice.
ContextCompactor.layerRollover starts a fresh window under context pressure or on the one allowed
provider-overflow retry. It makes no summary-model call. The engine retains the original instructions
and input, inserts a window marker and bounded recovery excerpts, and keeps trailing user steering
verbatim. A rollover changes the prompt within the same run; turn, tool, duration, and spending limits
continue accumulating. An automatic rollover that cannot reduce the prompt or fit its handoff fails
with CompactionError; admission still checks the final prompt against contextTokenLimit.
For model-directed control, include the native ContextTools.toolkit and its handlers:
Merge tools into the Agent’s toolkit and provide toolHandlers when building the Agent. Install
compactor directly to the durable host Layer, as shown above. Supply history
where the registered Agent’s tool services are provided. It depends on the host’s ThreadStore;
an ephemeral application can implement the ContextHistory port over its retained transcript.
Tool
Behavior
new_context({ handoff? })
Requests a rollover before the next turn. Call it alone; a short handoff is optional.
get_context_remaining({})
Returns window identity and estimated live tokens. Unconfigured capacity is null.
Reads up to 5,000 characters; use nextOffset to continue.
History search matches one literal substring, after trimming surrounding whitespace and
JavaScript case folding. It does not interpret multiple keywords, AND/OR, wildcards, regular
expressions, or quotes as query syntax. Search for a short exact phrase, document label, or
identifier: "RECEIPTS dock-03" only finds those characters together; "dock-03" finds that label
wherever it occurs in eligible text.
Recent search calls and notes can themselves match. To reach older records, repeat the query
with beforeRecordId set to the last hit’srecordId. The anchor and every newer canonical
position are excluded. Continue until the result contains fewer than the requested limit
(default three), including an empty array. A full final page needs one more request to see the
empty page. For example, these model tool calls use an illustrative returned ID:
// Once an original source is found, read its recordId with read_context_window.
ContextHistory.search keeps its existing hit-array result and one-to-twenty result limit;
existing callers can omit the new optional field. IDs are opaque, not sortable positions or
authorization capabilities. An anchor must be eligible retained evidence in the current Thread,
but need not match the query. An unknown, removed, foreign, or non-evidence anchor returns
ContextHistoryError with reason not-found; malformed parameters return invalid-input.
Each request captures a fresh tail and checks current authorization. New appends cannot push
older matches out of a continued page, but pages do not share a retained snapshot or bypass
retention. A scan, deadline, or index-work limit is an explicit failure, never an exhausted page.
ThreadContextHistory searches backwards from the captured tail or exact anchor in eight-record
pages. maxRecords limits work per search, regardless of Thread age; finding a full page can stop
early. Exact reads and window ownership use native locators across archived ranges. Storage
verification separately checks global integrity. Search snippets remain at most 2,000 UTF-16
characters each; text reads use their existing bounds.
Every continuation is another Tool call charged to the Run’s ordinary cumulative limits.
Both the default compactor and layerRollover honor an explicit new_context request. Custom
strategies must emit its requested rollover and cutoff. The engine recognizes the trusted Tool
annotation, never the tool’s name. Mixed batches and programmatic broker calls are rejected before
handlers start. Failed tool results do not trigger rollover. A successful request is recovered from
its canonical result if ownership is lost before the boundary is written; after the boundary is
written, recovery uses the saved window without replaying covered tools.
The optional handoff is saved with the rollover boundary and included in the next model prompt;
it does not require separate notes tools. It is limited to 20,000 characters and 32 KiB of
JSON-encoded UTF-8. Automatic handoffs are smaller deterministic excerpts of covered user messages
and the last tool batch; they may omit older progress and do not claim that external actions
succeeded. Notes and history are
untrusted working evidence. Verify live state before repeating an action.
MemoryNotes.toolkit supplies read_notes and write_notes. Bind MemoryNotes.layer to one
host-selected MemoryKey, locator, attributions, and scopes, then supply your existing MemoryReader,
MemoryWriter, and Effect AI IdGenerator.IdGenerator. For default operation identities, provide
Layer.succeed(IdGenerator.IdGenerator, IdGenerator.defaultIdGenerator) from effect/ai.
Notes are a full document replacement with expectedRevision; conflicts require
reading and merging again. Durable Steps retain the exact write command and operation identity for
recovery. Notes survive a process restart only when the selected Memory store does. The model cannot
choose a filesystem path, another memory key, or another thread through these tools.
When using MemoryNotes, tell the Agent to save important state before new_context, read its
notes after rollover, and use history to verify details. Notes are optional and independent of
window transitions; the framework does not synthesize or overwrite them automatically. This works
with any model that can use the native tools.
The canonical history adapter scans a fixed tail in bounded pages, with a default 10-second deadline.
It fails explicitly when the configured scan limit is exceeded. It exposes model-visible text, tool
calls, and retained tool results, excluding system instructions and operational records. It can
retrieve evidence removed by compaction, but cannot recover tool bytes discarded by result bounds,
transient references, or records removed by a separate retention policy. Tightening Tool result
bounds below these tools’ maximum payloads may truncate their results too.
For an indexed adapter, use @yielded/agent/thread-context-history-projection to project each
canonical record into eligible retained text or a rollover boundary. Its query normalization and
snippet matching preserve the native literal, case-folded search semantics. Operational records
still consume their canonical sequence even when their projection is empty.
Commit each contiguous projection batch and its watermark atomically. Window membership uses
coversThrough, which may precede the boundary’s own record: a later rollover can relabel evidence
already in the index. Capture one canonical tail for each lookup and restrict both evidence and
boundary records to it. Do not return partial results when the index has not covered that prefix.
The index supplies candidate identities and sequences; recheck host authorization and reread each
selected canonical record before returning evidence. A known sequence permits a single
ThreadStore.read with afterSequence: sequence - 1 and limit: 1, followed by identity checks.
Custom ContextHistory adapters, including application-owned Cloudflare indexes, must implement
beforeRecordId before using the updated native search tool. Resolve the anchor in the authorized
Thread and captured tail, reread its canonical record, and check its identity and evidence
eligibility. Then select literal matches with sequence < anchor.sequence, ordered by descending
sequence, up to the requested limit. Keep boundary lookup bounded by the captured tail, not
the anchor: a later rollover commit can assign older evidence to a window. Reverify each selected
source and its literal match. Bound index catch-up, candidate work, result bytes, and deadlines;
fail explicitly when a complete page cannot be established. Do not emulate this with an offset
into a changing result set, silently ignore the anchor, or truncate candidates before matching.
An adapter awaiting this update must reject anchored requests with unavailable rather than
returning the first page again. The built-in ThreadContextHistory.layer implements the contract
over every ThreadStore; its default scan ceiling and deadline are unchanged, and storage
adapters need no persisted-format migration.
An evidence index supplies retrieval candidates; canonical facts and the submission ledger own
recovery. A Run continuation references the exact
original input, saved context, and declared operations. Compaction changes model context without
changing those execution facts or accumulated charges. Selected recovery reads a bounded Run
prefix and suffix; unavailable or corrupt required evidence fails typed and leaves the work owed.
Initial context assembly and complete history export have their own costs and storage bounds.
@yielded/agent also has an application-managed data path.
prepareModelContext derives bounded text from a Thread.Thread.
digestCompactionSource binds a CompactionArtifact to that source. applyCompaction validates
the artifact before replacing covered view messages with its summary. The application creates,
stores, and applies the artifact.
RetainedFact values remain artifact metadata. They do not enter the prompt or a separate memory
store automatically. This path is separate from ContextCompactor; the interpreter does not call
applyCompaction. Memory.recall is the optional read path for application-owned sources; it does
not persist passages or turn compaction artifacts into memory.
The budget snapshot separates cumulative and live context usage:
constreport=Effect.gen(function*(){
constusage=yield*budget.snapshot;
usage.inputTokens;
usage.cacheReadInputTokens;
usage.cacheWriteInputTokens;
usage.lastInputTokens;
usage.lastOutputTokens;
});
Watch lastInputTokens for current context pressure. inputTokens is cumulative and grows on
every call. Provider caching may lower its cost. See Run & stream for hook
setup.
Leave output and summary room under the model window. For a 200k window, start with a
contextTokenLimit between 150k and 170k.
keepRecentTokens defaults to 20k. Pruning retains this preferred tail while the full prompt fits
its target; under pressure it clears additional older results. The newest tool result always
stays verbatim. If the remaining prompt cannot fit, the configured summary or overflow policy applies.
Use tokenBudget as a runaway limit. Use costBudgetMicrousd to bound estimated spend.
Delegate noisy research to bounded children so their raw tool output stays out of the parent
context.