Contexts
context, when, match, and createContexts.
import { context, when, match, createContexts } from "@use-crux/core";context(def)
Creates a reusable context fragment that can contribute system text, input fields, and tools to any prompt.
Static form
context({
id?: string,
description?: string,
priority?: number, // 0–100, default: 50
use?: ContextEntry[],
system: string | { segments: ContextTextSegment[] },
tools?: ToolSet,
})Dynamic form
context({
id?: string,
description?: string,
priority?: number,
input: ZodType,
use?: ContextEntry[],
when?: ({ input }) => boolean,
system: ({ input }) => string | { segments: ContextTextSegment[] } | Promise<string | { segments: ContextTextSegment[] }>,
tools?: ({ input }) => ToolSet,
rawFields?: string[],
memo?: { ttl: number },
cache?: boolean,
})Parameters
| Field | Type | Description |
|---|---|---|
id | string? | Identifier for debugging and devtools display |
description | string? | Human-readable description |
priority | number? | 0–100, default 50. Higher = dropped later under token pressure. Does not change normal render order. |
input | ZodType? | Schema for input fields this context needs. Merged into prompt input. |
use | ContextEntry[]? | Nested entries resolved before this context's own system text. Supports context(), when(), match(), skills, memory, blackboards, retrievers and grounding, and custom contributor entries. |
when | ({ input }) => boolean? | When false, context is excluded entirely (no resolution, no tools, no tokens) |
system | string | { segments } | (args) => string | { segments } | Promise<...> | Static or dynamic system text. Segments preserve static/dynamic attribution for inspection. |
tools | ToolSet | (args) => ToolSet? | Static or dynamic tool set |
rawFields | string[]? | Top-level input fields skipped by auto-escape (use for HTML/Markdown that should be passed verbatim) |
memo | { ttl: number }? | App-side resolver memoization for dynamic contexts. Requires id. |
cache | boolean? | Provider cache hint for stable prompt-prefix blocks. |
Caching
Use memo to skip redundant resolver calls and cache: true to request provider-level prompt caching:
| Form | Effect |
|---|---|
memo: { ttl: 300_000 } | Resolver memoization for 300 seconds |
cache: true | Provider cache hint only |
memo: { ttl: 300_000 }, cache: true | Resolver memoization plus provider cache hint |
Contexts with memo require an id for cache key derivation. Static string contexts cannot use memo; use cache: true when static content should participate in provider prefix caching.
Segmented system text
Return { segments } when devtools need to distinguish authored boilerplate from runtime values:
const workspace = context({
id: "workspace",
input: z.object({ workspaceName: z.string() }),
system: ({ input }) => ({
segments: [
{ text: "Current workspace: ", dynamic: false },
{ text: input.workspaceName, dynamic: true, source: "workspaceName" },
],
}),
});The runtime concatenates the segment text into the final system message. .inspect().system.parts[], context.contribution artifacts, and prompt.budget dropped previews preserve segments, staticTokens, and dynamicTokens. Segments can also carry observedAt and sourceVersion when a primitive knows when the source data was observed. Plain static strings are reported as one static segment, and dynamic string functions are reported as one dynamic segment without a source key.
Nested use
Use context({ use }) to bundle a reusable capability instead of repeating prompt wiring.
const supportContext = context({
id: "support-context",
use: [userMemory, docsGrounding],
system: "Answer with user memory and cited product docs when relevant.",
});
const supportPrompt = prompt({
id: "support",
use: [supportContext],
system: "Help the user.",
});Nested entries resolve before the context's own system text. Their tools, constraints, guardrails, and metadata are merged through the same path as prompt-level use entries.
Use this when the context is more than text. For example, a supportContext can bundle product-doc grounding, user memory, skills, and a policy instruction. Prompt authors then write use: [supportContext] instead of remembering every individual primitive.
Returns
Context<TInput>: frozen instance.
when(predicate, ctx)
Wraps a context with a runtime predicate for conditional inclusion in the use array.
import { when } from "@use-crux/core";
prompt({
use: [
when((i) => !!i.brandVoice, brandCtx), // partial context input
when<{ mode: string }>((i) => i.mode === "edit", editCtx), // explicit generic
],
});Returns: ConditionalContext<TCtx>: the wrapped context's input keys become Partial<> in the merged prompt input type.
The default predicate parameter is typed as a partial view of the wrapped context's input, because wrapping makes those fields optional at the prompt level. Use the explicit generic form when the predicate reads prompt-owned fields. When the predicate returns false, the context is excluded entirely, the same semantics as setting when on the context definition.
match(opts)
Selects between contexts based on a discriminator value (multi-way switch).
import { match } from "@use-crux/core";
prompt({
use: [
match({
on: (input) => input.mode,
cases: { research: researchCtx, create: createCtx },
default: createCtx,
}),
],
});| Option | Type | Description |
|---|---|---|
on | (input) => string | Extracts the discriminator value |
cases | Record<string, Context | Context[]> | Contexts per discriminator value |
default? | Context | Context[]? | Fallback when no case matches |
Every input key declared by any branch is included in the prompt's merged input type as optional, because only the selected branch is active at runtime.
Returns: MatchSpec: frozen instance.
createContexts(tree)
Same pattern as createPrompts() but for contexts.
const contexts = createContexts({
brand: { voice, terms },
editor: { schema },
});
contexts.brand.voice; // Context<...>
contexts._all; // Context[]: flat listHow contexts merge
When a prompt is resolved, the pipeline:
- Filters out contexts where
when()returns false, falsy entries, and unmatchedmatch()branches. - Resolves each remaining context's
system()callback inuseorder, with nestedcontext({ use })entries before the context that owns them within their cache tier. - Composes the prompt's own system text first, then cached contexts (
cache: true) as a stable prefix, then uncached contexts as the budget-droppable tail. Each group keepsusearray order. - Drops under budget if a token budget is set. Lowest-priority uncached contexts are dropped first, while the prompt's own system text and cached prefix are always kept.
Priority controls token-budget degradation, not normal rendering order. Excluded contexts contribute nothing: not system text, not tools, not tokens. Budget-dropped contexts still contribute their tools.
Related
- Guide: Contexts
- Reference: Prompts: how prompts compose contexts via
use - Guide: Caching: resolver memoization and provider cache hints
- Guide: Token budget: automatic context dropping