Releases: use-crux/crux
Release list
Crux 0.6.1-nightly.20260723060833.shaf056b65
Automated nightly build from main at f056b65. Install from npm with: npm install @use-crux/local@nightly
Crux 0.6.1-nightly.20260722060311.sha3140e0b
Automated nightly build from main at 3140e0b. Install from npm with: npm install @use-crux/local@nightly
Crux v0.6.0
Highlights
-
Replace the pre-release Quality authoring, execution, CLI, storage, and
Devtools model with Crux Evals V1. Applications now bind ordinary callable
production tasks withgenerate.task()orstream.task(), define inert typed
Cases and Variants through@use-crux/core/eval, run them withcrux eval,
reuse exact safe evidence automatically, and explicitly accept complete Eval
run arms as Baselines. The old@use-crux/core/qualityexports and
crux qualitycommands are removed without compatibility aliases.Add
stableModel()to attest a standard or custom AI SDK model's secret-free
versioned identity for safe automatic Eval reuse. Unattested model objects keep
working fresh and receive one actionable CLI and Devtools remedy.Reuse function-form prompt, system, and message renderers through their tracked
literal-ESM source closure and an exact one-way fingerprint captured from the
real normalized generate/stream request. The comparison projects only fields
that can affect the provider request, excluding per-resolution observability
IDs while retaining Context text and cache boundaries. Evidence candidates are locally
re-rendered before reuse; mismatches execute fresh with actionable
nondeterministic_rendererCLI and Devtools guidance, and raw prompt material
never crosses the evidence boundary. Unresolved source dependencies remain
fresh.Fingerprint callback-free Crux router, split, retry, fallback, and cascade
trees by recursively projecting attested model leaves and structural options,
then include the resolved model target in observed identity.stableModel()
rejects whole route trees. Static contexts, inline skills, and schema-only
tools can reuse exact evidence; dynamic context renderers/selectors, executable tools,
function-produced tools, memoized or effectful context families execute fresh.
Route-tree evidence remains fresh when its resolved target was not covered at
planning.Fail closed for inline managed-task bindings and callback-bearing Variant
prompt overrides, report the distincttask_binding_untrackedremedy, and
derive deployed Variant fingerprints from adapter semantic projections so
schema-backed prompt changes cannot collide. Fingerprint Current and imported
replacement task bindings independently so an unrelated candidate edit does
not invalidate Current evidence.Add Runtime-hosted Eval execution with generated identity-only registries,
strict offline and pre-spend planning, Node/serverless/Convex conformance, and
the first-party@use-crux/cloudflareDurable Object host. Explicit fresh
executions use a new durable admission identity while retries reconnect to the
same admitted action. Strict offline runs load the generated data-only privacy
policy without importing Runtime code or touching the network, and fail closed
when that projection is missing or stale. Add awaited
run-linked feedback through@use-crux/core/feedbackand AI message metadata
through@use-crux/ai/feedback, plus durable Review and explicit Add-to-eval
workflows in Crux Local and Devtools.Add first-class Eval catalog and run views to Devtools, including same-origin
run triggering, exact run comparisons, Baseline promotion, Eval search, reuse
and invalidation reasons, cost and score evidence, feedback, and Review links.
Keep the CLI coordinator protocol bounded by sending diagnostic run summaries
instead of duplicating stored inputs and outputs over NDJSON.Keep durable result writes type-safe and bounded: reject non-JSON media before
redaction, preserve supported structured values exactly, and omit oversized
provider response envelopes from the stored run while retaining their linked
trace references. Align privacy-policy fingerprints across TypeScript and Go,
including HTML-sensitive keys and JavaScript UTF-16 key ordering.Make
--max-costfail closed on conservative per-call USD ceilings. Managed AI
tasks, routing trees, bounded tool loops, and judges estimate from
experimental.eval.pricing; unknown paths report missing model keys and an
actionable remedy before any billable work. -
Add portable MCP tool sources over Streamable HTTP and stdio. MCP tools now
materialize lazily across every first-party generation adapter and retain the
ordinary Crux middleware, Safety, approval, Eval, observability, and
cleanup contracts.Project Index and Devtools now connect authored MCP servers with
runtime-discovered tools, safe schemas and fingerprints, health and lifecycle state,
Run Detail preparation evidence, and exact Catalog activity. The new
@use-crux/mcppackage owns both supported client paths and keeps MCP optional
for Core and adapter installations.The release also validates widened runtime transport and selection values at
the public boundary, keeps opaque dependency failures out of errors and
evidence, preserves every accepted portable tool name, closes materialized
sessions when lifecycle preparation fails, and bounds Project Index runtime
delivery and ingestion. -
Make portable application entrypoints verifiable in both source and staged npm
packages, remove package-wide Node engine restrictions where the primary graph
is portable, and include the Next integration in TypeScript release staging.The
@use-crux/airoot no longer downloads HTTPS transcription input
implicitly. Portable callers must provide materialized audio; Node callers can
importtranscribeorcreateAiSdkTranscribefrom the new
@use-crux/ai/transcription/nodesubpath to retain the bounded, DNS-pinned
download behavior. Portable data-URL transcription no longer relies on the
NodeBufferglobal.Unify observability and host-lifecycle async scoping on Core's canonical
carrier so no-AsyncLocalStorage runtimes retain synchronous fallback behavior
while unsafe asynchronous ambient host scopes fail closed.Add portable deployment identity and privacy-safe Project Index manifest
contracts to Core. The build-time Indexer now projects and verifies the same
deterministic artifact internally.Carry immutable deployment identity through observability graph records,
suspend/resume propagation, and local run detail.@use-crux/otelnow exports a portable
Resource-attribute mapper, maps lightweight identity per span, and projects
DefinitionRefs through bounded attributes and events.Advance observability to schema v4 with explicit operation-family identity.
Root runs now own anoperationId; independently durable nested Flow, named
defer, and Convex swarm work opens causally linked child runs while ordinary
pipeline, parallel, consensus, delegate, generation, and host continuations
remain spans or fresh segments. Local Runs projects one row per operation with
aggregate child/topology health, child-before-root shells, family-atomic
retention, and deletion tombstones. Older observability storage resets in
place because family membership cannot be reconstructed from trace IDs. Run
lookup and deletion now require an operation or member-run ID; W3C trace IDs
remain correlation data and never select an operation implicitly.Add daemon-free
crux checkwith deterministic JSON and explicit CI exit
codes.crux lintnow uses the same one-shot Project Index service and embedded
worker pipeline by default while retaining its no-gate compatibility behavior
and an explicit--serverpath.Add daemon-free
crux manifestartifact generation and verified, idempotent
crux catalog import. Local observability now resolves runtime definition
references only against the exact immutable deployment manifest named by a run
and labels current-checkout comparisons separately.
Definition fingerprints now use normalized project-relative source identity so
identical checkouts produce the same manifest ID; static, semantic, and Go
snapshot cache epochs invalidate root-dependent historical fingerprints.Add deterministic
crux cataloglist, show, status, and explain projections
with compiler provenance, safe source paths, Health/Eval/runtime joins, and
truthful partial or unknown state. The betacrux indexlist/show paths now
delegate to Catalog while category keywords and explicit reindex remain.
Durable definition evidence now retains canonical extractor and resolved
extension provenance, and Catalog explanations name every actual contributor
without changing the public evidence shape or phase producer identity.
Durable relation, source-reference, and diagnostic evidence now retains the
same exact extractor contributors across worker, cache, and restart boundaries.Add opinionated
withCruxlifecycle boundaries for Cloudflare Workers and
Next.js while retaining their low-level adapters. Workers and Next now compose
deferred work with contained, bounded post-response observability drains;
createCruxConvex().run()owns the corresponding bounded terminal drain and
preserves deployment identity across durable continuation boundaries.
Rejected promises returned by advisory drain reporters are contained without
delaying or replacing handler results or host-owned drain work.
Rename the Next Runtime artifact build plugin towithCruxBuild, reserving
withCruxfor framework lifecycle boundaries without a compatibility alias.
Add explicitconfig({ host })retention bindings for Node, Next.js,
Cloudflare Workers, and Vercel. Config-only ambient defer uses an ephemeral
invocation per call; failed or cancelled scopes now record and skip inline
callbacks instead of running them.
Remove defer completion classes and lifetime factories in favor of the scope
kernel's host bindings. Serverless and Node wrappers now enqueue retained work
through the root gate. Move the WorkerswithCruxlifecycle boundary from
Core's deleted/observability/workerssubpath to...
Crux 0.5.1-nightly.20260718141902.shaefbed7f
Automated nightly build from main at efbed7f. Install from npm with: npm install @use-crux/local@nightly
Crux 0.5.1-nightly.20260714200218.shaf5d69bf
Automated nightly build from main at f5d69bf. Install from npm with: npm install @use-crux/local@nightly
Crux v0.5.0
Highlights
-
Promote
@use-crux/core/observability,@use-crux/otel, and the local Go observability read model to stable beta, replacing process-local reliability assumptions with an explicit multi-invocation contract. See ADR 0002 for the full rationale.Cut the graph record wire/storage contract over to schema v2 only (
runIdfor the logical operation,traceIdfor distributed correlation, andsegmentId/segmentSeqfor one physical process/isolate/invocation). There is no v1 compatibility window: on first startup against the new schema, the local Go backend transactionally discards pre-v2 observability rows, which carry no truthful execution-segment identity, and rebuilds automatically. Every other local table is untouched and no manual.cruxdeletion is required.Add explicit lifecycle ownership for suspend/resume:
run.suspend({ reason })ends the current segment and returns a serializableCruxPropagationCarrier, andobserve.resumeRun(carrier, { reason })opens a fresh segment on the same logical run and emitsrun:resumebefore any child record.observe.withContext()remains context-only and can no longer be mistaken for a resume/suspend/end mechanism. Flow suspension and Convex swarm turns now use this shape instead of persisting a captured context and calling an implicit end.Make delivery lossless and per-record. The transport now inspects an indexed disposition (
accepted/rejected, with aretryableflag) for every sent record instead of trustingresponse.ok; a malformed or partial receipt retries every unaccounted-for record.recordIdidentifies immutable content: an exact duplicate is accepted idempotently, and a conflicting payload under the same id is rejected and diagnosed rather than silently overwriting the original.Add a framework-neutral host lifecycle port (context/defer/deadline) with first-party bindings: Node (
withNodeObservableInvocation), generic serverless (withObservableInvocation), Cloudflare Workers (withWorkersObservableInvocationfrom the new@use-crux/core/observability/workerssubpath, usingExecutionContext.waitUntilwith nonodejs_compatrequirement), and Convex (createCruxConvex()/action/internalAction/agent/swarm wrappers, bound automatically). Every wrapper reports a structuredObservabilityFlushResult(status,delivered,rejected,remaining,deadlineExceeded) instead of a boolean; passonDrainto inspect it. The Convex default flush bound drops from 20 seconds to a fixed 3-second window, since Convex exposes no per-invocation deadline API — existing callers relying on the old window should inspectonDrainor pass an explicit timeout.Remove the stream-finalizer grace timer. Only a stream's own terminal signal (drain, early return, or throw) ends its span, immediately, with stream-derived metrics; a late or never-arriving provider completion attaches as a linked
usage.observedevent/artifact and can never reopen the span or change its recorded duration/status.Build a real active OTel execution bridge in
@use-crux/otel:withTelemetry()now activates the SDK span around the actual instrumented callback (trace.getActiveSpan()resolves correctly inside real work, nested spans parent correctly), mapsrun:suspend/run:resumecorrectly instead of crashing the subscriber on those record types, and starts a fresh root span sharing the originaltraceIdon resume rather than reopening a stale one. Add W3Ctraceparent/tracestateinject/extract helpers and an explicitbaggageAttributeAllowlist(nothing copied by default).observe.flush()/observe.shutdown()now also force-flush the installed telemetry manager's exporter/processor work, bounded by the host lifecycle port above.Add one revisioned Go Runs read model (
/api/observability/runs/page,/api/observability/runs/delta) that joins observability and Quality server-side through an explicit correlation field, bumping a monotonic revision per affected run inside the same ingest transaction it publishes after commit. The page envelope is the sole Runs list HTTP surface; web DevTools, Global Search, and local TUI/CLI clients all consume it instead of a separate bare-array route. Fix a duplicate-recordIdconflict path that previously let a second, different payload overwrite immutable raw content, and fix a Quality/observability correlation bug that could key an unrelated run's feedback/score data onto the wrong run'straceId/runIdcollision.Move DevTools Runs and run detail onto that one read model: delete the client-side merge of a Quality-terminal row list and a separately-fetched observability-running row list, add truthful
suspended/incomplete/conflictedstatus andunknown/healthy/degradeddelivery-health rendering, and gate WebSocket invalidation on the published revision so a reconnect performs a bounded catch-up instead of an unconditional refetch or stale cache.Attach bounded
DefinitionRef[]evidence to observability records so every directly-observed Project Index definition kind joins directly to its canonical definition without stack or name guessing: prompt, context, tool, agent, flow, retriever, blackboard, and composition, plus routing (router/split/retry/cascade/fallback), skill, guardrail, constraint, task, workspace, memory, and the retrievalrag.recipe/rag.rerankerfamilies. A closedDirectlyObservedKind → DefinitionRefRolemap is checked against the coverage manifest at compile time, so a new directly-observed kind cannot ship without a canonical ref. Anonymous or non-authored spans omit the ref rather than guess. Composition APIs already require an authoredid; the random per-executioncompositionIdremains a separate execution identity.Extend that join to canonical runtime contributors and executed children: knowledge bases, tool policies, flow steps, parallel branches, recipe steps, and authored scorers now attach their own role-specific refs when the runtime genuinely holds their authored identity. Other structural children use explicitly parent-derived Catalog activity—“parent ran; this child is not independently observed”—while static-only kinds remain truthful zero-runtime states. No identity is inferred from a display name.
Make recipe reranking authored-id-required so
rag.rerankerruntime evidence is truthful and collision-free:rerank()now takes a required, namedengine(there is no anonymous default-model judge path), andjudgeReranker()requires aname. Build the engine withjudgeReranker({ name, model })or an adapterreranker()and pass it torerank({ engine }). The engine'snameis the canonicalrag.reranker:<name>identity.Project those references transactionally into a rebuildable local runtime-activity overlay and add revision-aware Runs filtering by canonical definition id. The overlay follows run deletion and retention, reuses the existing observability revision stream, and never stores a denormalized Project Index snapshot.
Normalize completed generation outcomes across
@use-crux/openai,@use-crux/anthropic,@use-crux/google, and@use-crux/aiinto closedCruxFinishReasonandCruxProviderError/CruxAdapterErrorshapes (kind/ namespacedcode/retryable/ optional redactedmessage). Stream completion failures surface instead of silent missing metadata; completed tool calls are assembled for bothgenerate()andstream(); progressive tool-call argument deltas are not exposed. Abort and budget timeouts classify asaborted/timeout.retryableis classification only — SDK clients keep their own network retries.Finish Catalog Observability sections and View Runs for every definition kind via the coverage manifest, add Run Detail → Catalog links for all
DefinitionRefs (including unresolved since-deleted ids), and share one delivery-health presentation (unknown/healthy/degraded) with plain-language status copy forsuspended/incomplete/conflicted. Quality signal capture follows nestedtriggeredchild runs so flow step matchers are not falsely uncaptured under aneval.casecell.Keep Catalog activity truthful for runtime-observed primitives that do not yet carry authored definition identity. Deferred work, media operations, and ingest sources remain visible in Runs and Run Detail, while their per-definition Catalog sections explicitly report that runtime evidence is not joined and never fabricate activity counts or View Runs links.
See ADR 0003 for the durable definition↔runtime join and adapter-outcome decision record.
-
Stabilize model routing around
router(),split(),retry(),fallback(), andcascade()wrappers with routing receipts, generate/stream support boundaries, and updated adapter docs.Breaking routing API changes: router
.with()and.select()are removed in favor of call-siteroutingandrouteoptions; variadicfallback(a, b, opts)is replaced byfallback([models], opts);_meta.router/_meta.cascade/_meta.fallbackare replaced byresult.routing; native OpenAI, Anthropic, Google, and Convex model options now type-reject routing wrappers instead of accepting unsupported values.Extend Project Index routing facts, static extraction, native semantic parity, relation policies, and index lints to cover split routes, retry targets, array-form fallback, call-profile model targets, and RouteArgs callback source refs.
Surface canonical routing receipts in local devtools run detail and Project Index views, including router defaults, split buckets, retry/fallback attempts, cascade budgets, and receipt-backed Turn Decision Report chips.
Project Index now shows required
RouteArgscontext types and literal route call-profile parameters. Run Detail renders receipt TTFT, bounded attempt errors, and cascade tier note/budget from the same canonicalrouting.reportpreview.Run Detail now accepts the...
Crux v0.4.0
Highlights
-
Introduce the Retrieval & RAG stable beta public API spine at
@use-crux/core/retrieval, includingknowledgeBase, namedretrievalRecipe, typed retrieval steps, canonicalRetrieveRequest, schema-derived metadata filters, recipe traces, and grounding/tool integration types.Wire
knowledgeBaselifecycle methods to the existing indexing, corpus, indexed-knowledge, storage, and retriever primitives. Knowledge bases can now index, reindex, remove sources, create namespace-scoped handles, retrieve through store-backed indexes, and inspect lifecycle/storage capability metadata.Implement the named single-retriever
retrievalReciperuntime. Recipes now execute typed steps, expose.retrieveWithTrace()and.asRetriever(), capture failed-step traces, run fanout with bounded concurrency, keep score history in structured hit provenance, support recipe-level and per-step models, emit recipe/step observability spans, and replace the old internal pipeline/stage modules.Add federated
retrievalRecipesources. The built-in retrieve step now accepts multiple retrievers or weighted source entries, runs source/query retrieval concurrently, fuses cross-source hits with structured per-source provenance, supportsfailandskip-with-warningsource failure policies, and records per-source retrieve attribution in recipe traces.Add session-backed grounding and typed retrieval tool payloads. Grounded citation validation now accounts for both injected and tool-discovered hits without parsing tool strings or closing over mutable hit arrays, retrieval tools return lean structured
crux.retrieval.hitspayloads with model-facing renderers, andgetSourcecan read discovered session hits or active store-backed indexed chunks with explicit visibility.Add Retrieval/RAG storage conformance coverage and Convex profile mirroring. Core now exposes a vector-store conformance suite that verifies namespace filtering, delete and sparse/hybrid capability claims, and indexed-knowledge hydration diagnostics; hydration misses now fail with
RetrievalRunError("hydration_miss")instead of silently returning empty results.@use-crux/convex/retrievalmirrors the core retrieval API with Convex runtime storage defaults forknowledgeBase()and store-backedretriever().Add provider-agnostic RAG evaluation metrics to the Quality system.
scorers.rag.*now includes deterministic recall@k, MRR, expected source coverage, context precision, citation validity, and trace-shape snapshot scorers, andevaluate()can run retrieval recipes directly or throughtarget.recipe(). New retriever spans emit the betaretrieval.retrieveobservability primitive.Document the stable beta Retrieval/RAG surface around knowledge bases, retrievers, recipes, grounding sessions, typed retrieval tools, and Quality-based RAG evaluation.
knowledgeBase().grounding(),knowledgeBase().recipe(), andretrievalRecipe().asGrounding()now delegate to the functional retriever/recipe/grounding runtime paths.Add the shared reranking contract and adapter bindings for the beta recipe surface. Core now exports
RerankerandjudgeReranker(),rerank()accepts custom engines,@use-crux/aibinds native AI SDK reranking, and the Anthropic, OpenAI, and Google adapters expose matchingretrievalModel()and judge-backedreranker()factories on their adapter instances. Devtools and Project Index now understand beta retrieval recipe/step primitives while keeping historical pipeline/stage compatibility.Promote
reranker()to an index-visible RAG primitive. Static, semantic, native, and local Project Index paths now emitrag.rerankerdefinitions,rag.recipe.step.uses_rerankerrelations fromrerank({ engine })recipe steps, and a cache epoch migration for the updated static output. The experimental indexer authoring API also exposes ordered object-or-helper config readers so mixed recipe step arrays keep authored order. Devtools renders rerankers as first-class catalog nodes, shows authored recipe steps and step dependencies in the recipe hero, and the built-inrag.recipe_step_unresolved_targetlint surfaces recipe step dependencies that cannot be resolved to indexed retrievers, scorers, or rerankers. -
Add atomic
RecordStore.create()support and use it for task creation so concurrent duplicate task IDs fail withDuplicateTaskIdError. Record adapters now need to implement the conditional insert primitive; Convex component refs include a matchinginsertmutation. -
Remove the old direct flow executor surface from
@use-crux/core;flow()handles are now the only public flow authoring API.Flow input is now inferred from the handler's second parameter. Input-bearing handles expose
run(input, options?), no-input handles exposerun(options?), and suspended flows resume throughresume(flowId, options?).Flows can now declare local typed signal maps with
flow(name, { signals }, handler). Signal schemas type bothflow.suspend('name')andhandle.signal(flowId, 'name', payload), andnoPayload()declares notification-only signals.Declared signal schemas now validate payloads before
handle.signal()writes to persistence and again whenflow.suspend()delivers a stored signal during resume.Invalid declared signal payloads now throw
InvalidSignalPayloadError, allowing callers to distinguish payload contract failures from flow lifecycle control errors.Resumed flows now persist terminal lifecycle metadata when they complete, cancel, or expire. Terminal snapshots are retained for inspection and listing, but
completed,cancelled, andexpiredsnapshots cannot be resumed again.Delivered flow signals are now consumed after validation and replayed from the flow snapshot for earlier suspend points, preventing stale pending signals from satisfying later waits.
The Project Index now records local flow signal names and emits lint findings for duplicate literal
flow.suspend()names and literal suspend names missing from a local signal map.Flow step labels are now enforced as durable replay identities. Duplicate labels throw at runtime, the Project Index records ordered step label metadata, and linting reports duplicate literal
flow.step()labels.Flow lifecycle control errors thrown inside
flow.step()now bypass step retry and fallback handling, preserving suspend, cancel, and expire outcomes.Persisted flow input, step outputs, signal payloads, and terminal snapshot metadata are now validated as JSON-serializable before flow state is written.
Convex flow actions now start and resume through the accepted core
run(input)andresume(flowId)handle APIs. Convex flows can also declare local signal maps, and.signal()validates declared payload schemas before writing a pending signal or scheduling the resume action.Refresh OTel package README wording to describe
flow().run()spans. -
Harden Memory namespace handling and capture scheduling: dynamic proposal operations now resolve from input, synchronous tool collection throws clear errors for async namespaces or async block tools, and
memory({ capture: { mode } })is available withprocessingkept as a deprecated alias.Align Memory store adapters with the beta
RecordStorecontract:@use-crux/corenow exposes a reusable store conformance helper for adapter tests, deprecated privatememory/typesstore aliases point toRecordStore, and the Upstash adapter supports page-shaped Convex component lists with decoded filtering and hydrated vector search metadata.Add the canonical Storage Beta type surface at
@use-crux/core/storage, includingRecordStore,RecordEntry,RecordPage,RecordWriteOptions, exact scalar filters, discriminated vector queries,{ records, vectors, blobs }bundles, and typedStorageErrorcodes.Harden the in-memory Storage Beta adapters: record stores now validate JSON and TTL inputs, apply lazy TTL and exact null-aware filters, vector stores validate dense/sparse queries and pre-filter metadata correctly, blob stores expose
head/delete lifecycle behavior, and@use-crux/core/storage/testing/vitestprovides reusable record/vector/blob conformance suites.Move core workspace, indexing, retrieval, indexed knowledge, embedding cache, and semantic cache consumers onto Storage Beta
records/vectors/blobsconfiguration, with vector-backed search requiring pre-filter-capable vector stores.Expose Convex and Upstash Storage Beta adapters: Convex now provides
convexRecordStore, dense-onlyconvexVectorStore,convexStorage, and a full-lifecycle workspace blob store; Upstash now provides a SCAN-backed RedisRecordStoreand a stricter VectorVectorStorethat validates filters, wraps backend errors, and reports conservative capabilities by default.Harden Memory capture and proposal review: adapter-bound memory capture now preserves settled tool results and errors when available, proposal approve/reject/edit operations are pending-only to prevent duplicate writes, and proposal write observations include flattened source metadata.
Make Memory rendering predictable under token pressure:
budget.maxTokensis now enforced for memory contexts and individual blocks, and extractive memory blocks support explicit list/recent and semantic render strategies.Expose Memory beta behavior in observability and Project Index surfaces: budgeted memory rendering now emits inspectable
memory.readobservations, static memory extraction records capture mode, budgets, render strategies, and retention metadata, and devtools memory details can show indexed episodic retention policy.Expose Storage Beta in Project Index facts: static extraction now records record/vector/blob store definitions, storage bundles, scoped storage, storage dependencies on retrievers/workspaces, and matching Rust/Oxc native parity.
Resolve Storage Beta Project Index facts se...
Crux v0.3.0
Highlights
-
Deepen the loop-owned execution boundary into a single gateway-closed
LoopRuntimePort, replacing the per-callclientthreading of the oldExecutorSpec/SdkLoopDialectseam.@use-crux/core:- Replace
ExecutorSpecwithLoopRuntimePort(id,describeModel,mapSettings,runTextLoop,runStructuredAttempt,runStream,replayStream). The port is already bound to its SDK client, so each run method takes only anExecutorRequest— there is no per-callclientargument. bind()now returns the client-dependentBoundLoopRuntime(renamed fromBoundLoopOwnedRuntime), which core assembles withid/describeModel/mapSettingsinto the port.- Rename
executorAdapter(spec)(client)toloopRuntimeAdapter(port). - Testing:
fakeExecutor→fakeLoopRuntime(returns{ runtime, calls });executorSpecConformance→loopRuntimePortConformance(harnessprepare()returns{ runtime, model }).
@use-crux/ai:- Add
createAiSdkLoopRuntime(gateway): LoopRuntimePort<LanguageModel>and theAiSdkLoopRuntimetype — the adapter fromSdkGatewayto the core port.aiSdkProviderRuntimeandcreateCruxAi({ gateway })are unchanged.
defineProviderRuntime({ ownership: 'loop-owned', loop })authoring is unchanged except thatloop.bind()now returnsrunTextLoop/runStructuredAttempt/runStream(wasrun/attemptStructured/stream). - Replace
-
Complete the profile-backed
convexAgent()lifecycle around the Convex Agent method surface.- Align thread continuation with Convex Agent: call
continueThread(ctx, target)first, then pass Crux promptinputtothread.generateText(),thread.streamText(),thread.generateObject(), orthread.streamObject(). - Add profile-backed
generateObject()andstreamObject()support, injecting resolved Crux prompt state and prompt output schemas through the same lifecycle/driver boundary as text generation. - Derive public generation args/options/results from upstream Convex Agent method types while omitting Crux-owned
system,prompt,messages, andtools. - Add the
cruxconfig namespace for Crux-owned lifecycle controls:crux.prepare,crux.runtime.store,crux.runtime.namespace,crux.observe,crux.persistence, and advancedcrux.driver. Existing top-levelprepare,store, andnamespaceremain as deprecated compatibility aliases. - Move Crux-only prompt resolution to
agent.crux.resolve()with directagent.resolve()kept as a deprecated compatibility alias. - Deepen the Convex store document contract with a substitutable
ComponentDocumentPort, normalizedConvexStoreDocumentComponent, andcreateInMemoryConvexStoreDocumentComponent()for server/React boundary tests.
- Align thread continuation with Convex Agent: call
-
Add the public observability event spine APIs:
subscribeObservability()for in-process graph-record subscribers andCRUX_OBSERVABILITY_CHANNEL/CruxObservabilityChannelMessagefor Node diagnostics-channel consumers.Remove the legacy runtime instrumentation hook bus.
withTelemetry()now subscribes to the canonical graph-record stream by default, andcreateOtelRecordSubscriber()remains available for custom OTel wiring.Migrate AI agent, Convex swarm/compaction, and ingest parser instrumentation to canonical graph records so they continue emitting observability after the hook bus removal.
TelemetryOptions.recordContentis removed; use the coreobservability.recordInputs/recordOutputspolicy instead.Add observability capture policy controls:
config({ observability: { recordInputs, recordOutputs } }). Disabled input/output artifacts are emitted as reference records with size/hash metadata and no preview.Generation and streaming span-end records now carry
gen.*performance metrics, and@use-crux/otelmaps them to exportedgen_ai.client.*attribute constants.Restore the documented default
withTelemetry()behavior: when no lightweight exporter is configured,@use-crux/otelnow uses the globally registered OpenTelemetry tracer instead of silently dropping spans. -
Deepen the core prompt-resolution pipeline behind one private pass primitive and complete the resolver-port seam.
- Introduce
createPromptResolverPlan(config, ports)— the single private pass primitive.compilePrompt()is now a thin boundary that validates the config, binds ports, and projectsresolve()/inspect()over the plan's onerun(opts, mode)call, so the two projections can never drift across ordering, gating, skills, budget, settings, or inspection. - Add a
TokenizerPort({ count(text) }): every token count the pipeline reports (system parts, prompt text, dropped contexts) now flows through it, so a deterministic counter pins token-budget behavior without depending on the production chars/4 estimate. - Broaden the
skillsport to own registry fetch plus skill-index generation and activation-session creation — the resolution pass no longer imports the skill module directly. - Add
createResolverFakes(): a one-call bundle of deterministic in-memory ports (observability, skills, cache, clock, tokenizer, policy, diagnostics, instrumentation), each also exposed as a named handle for assertions. NewstaticTokenizer()fake. compilePrompt()now returns aPromptResolutionPipeline;CompiledPromptremains as a deprecated alias. New public exports:PromptResolutionPipeline,TokenizerPort,staticTokenizer,createResolverFakes,ResolverFakes,ResolverFakesOptions.- Internal-only refactor of the resolution internals (split port contracts in
resolver/ports.tsfrom their production adapters inresolver/default-ports.ts). No change to theprompt().resolve()/prompt().inspect()runtime behavior or to resolved prompt args.
- Introduce
-
Add
defineSingleTurnProviderBundle()for provider packages that compile single-turn SDK wire hooks into the standard Crux provider runtime and helper factories. -
Stabilize Plan & Tasks task-list state handling: duplicate IDs, removed tasks, discarded lists, terminal transitions, pending/cancelled status derivation, and stale counter repair now resolve through typed lifecycle errors and row-derived state.
Cut over the experimental Plans & Tasks API to the canonical
plan(),tasks(), andtask()surface. Plan and task handles are command handles withget()/list()reads, existing entities are bound withplan.ref()andtasks.ref(), creation tools live atplan.tool()andtasks.tool()with safecreated()accessors, and the oldtasklist, top-level agent/tool factories, and first-match task-list lookup exports are removed from public entrypoints.Add typed task definitions for
tasks({ items }): keyedtask()specs now infer literal task IDs for reads, lifecycle methods, and workers, infer schema-backedcomplete()result payloads, validate completed results at runtime, and reject non-JSON plan/task metadata, list metadata filters, and task results before persistence.Tighten the final beta contract with root-level task lifecycle error exports, schema-input completion typing for transforming result schemas, JSON guard coverage for dropped object properties, and consistent plan-list metadata filtering.
Align React and devtools with the canonical beta surface: React hooks now expose
usePlan()anduseTasks()with ID-or-handle inputs and no publicuseTaskList()alias, while local/devtools plan details project canonical task activity with core task statuses and separate progress messages.Rewrite the public Plans & Tasks docs around the final beta API, including
plan(),tasks(),task(), handle methods, dynamic vs defined ledgers, status derivation, lifecycle errors, React hooks, and guidance on when to useflow()or an external durable runner. -
Deepen Google CachedContent into a single
GoogleCachedContentLifecycle.createGoogle({ cachedContent })now resolves one lifecycle that owns prefix detection, cache keying/reuse, SDK cache operations, and fallback policy, returning a request-ready config patch that bothgenerate()andstream()merge.- Configure the built-in lifecycle with
GoogleCacheConfig(defaultTtlSeconds,maxEntries,onError: 'fallback' | 'throw', or a customGoogleCachedContentCachePort), passfalseto disable, or pass a fully customGoogleCachedContentLifecycle. - Invalid TTL/config values are rejected (per-call TTL overrides fall back to the default; bad
defaultTtlSeconds/maxEntriesthrow a clear error). - New exports:
GoogleCacheConfig,GoogleCacheName,GoogleCachedContentCachePort,GoogleCachedContentErrorMode,GoogleCachedContentLifecycle,GoogleCachedContentOption,GoogleCachedContentPlan,GoogleCachedContentPrepareArgs.
- Configure the built-in lifecycle with
Fixes
-
Refresh npm-facing package documentation and homepage metadata so package pages point users to cruxjs.dev and the core package README presents a concise onboarding path.
Allow
@use-crux/googleconsumers to use either@google/genai1.x or 2.x.Document the single-turn provider bundle authoring path in adapter package READMEs.
-
Add the public observability event spine APIs:
subscribeObservability()for in-process graph-record subscribers andCRUX_OBSERVABILITY_CHANNEL/CruxObservabilityChannelMessagefor Node diagnostics-channel consumers.Remove the legacy runtime instrumentation hook bus.
withTelemetry()now subscribes to the canonical graph-record stream by default, andcreateOtelRecordSubscriber()remains available for custom OTel wiring.Migrate AI agent, Convex swarm/compaction, and ingest parser instrumentation to canonical graph records so they continue emitting observability after the hook bus removal.
TelemetryOptions.recordContentis removed; use the coreobservability.recordInputs/recordOutputspolicy instead.Add observability capture policy controls:
config({ observability: { recordInputs, recordOutputs } }). Disabled input/output art...
Crux v0.2.0
Highlights
-
Prepare the first npm release under the
@use-cruxpackage scope.Document the native AST beta parity gate, release checklist, and
experimental.indexer.nativeAst
troubleshooting guidance.Fix
make localso the current-platform Rust/Oxc worker binary is replaced atomically when an old
worker process is still running.