Skip to content

Releases: use-crux/crux

Crux 0.6.1-nightly.20260723060833.shaf056b65

Choose a tag to compare

@github-actions github-actions released this 23 Jul 06:20
f056b65

Automated nightly build from main at f056b65. Install from npm with: npm install @use-crux/local@nightly

Crux 0.6.1-nightly.20260722060311.sha3140e0b

Choose a tag to compare

@github-actions github-actions released this 22 Jul 06:11
3140e0b

Automated nightly build from main at 3140e0b. Install from npm with: npm install @use-crux/local@nightly

Crux v0.6.0

Choose a tag to compare

@github-actions github-actions released this 21 Jul 12:25
99fccca

Highlights

  • Replace the pre-release Quality authoring, execution, CLI, storage, and
    Devtools model with Crux Evals V1. Applications now bind ordinary callable
    production tasks with generate.task() or stream.task(), define inert typed
    Cases and Variants through @use-crux/core/eval, run them with crux eval,
    reuse exact safe evidence automatically, and explicitly accept complete Eval
    run arms as Baselines. The old @use-crux/core/quality exports and
    crux quality commands 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_renderer CLI 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 distinct task_binding_untracked remedy, 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/cloudflare Durable 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/feedback and 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-cost fail 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/mcp package 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/ai root no longer downloads HTTPS transcription input
    implicitly. Portable callers must provide materialized audio; Node callers can
    import transcribe or createAiSdkTranscribe from the new
    @use-crux/ai/transcription/node subpath to retain the bounded, DNS-pinned
    download behavior. Portable data-URL transcription no longer relies on the
    Node Buffer global.

    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/otel now 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 an operationId; 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 check with deterministic JSON and explicit CI exit
    codes. crux lint now uses the same one-shot Project Index service and embedded
    worker pipeline by default while retaining its no-gate compatibility behavior
    and an explicit --server path.

    Add daemon-free crux manifest artifact 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 catalog list, show, status, and explain projections
    with compiler provenance, safe source paths, Health/Eval/runtime joins, and
    truthful partial or unknown state. The beta crux index list/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 withCrux lifecycle 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 to withCruxBuild, reserving
    withCrux for framework lifecycle boundaries without a compatibility alias.
    Add explicit config({ 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 Workers withCrux lifecycle boundary from
    Core's deleted /observability/workers subpath to...

Read more

Crux 0.5.1-nightly.20260718141902.shaefbed7f

Choose a tag to compare

@github-actions github-actions released this 18 Jul 14:26
efbed7f

Automated nightly build from main at efbed7f. Install from npm with: npm install @use-crux/local@nightly

Crux 0.5.1-nightly.20260714200218.shaf5d69bf

Choose a tag to compare

@HenrivantSant HenrivantSant released this 14 Jul 20:17
f5d69bf

Automated nightly build from main at f5d69bf. Install from npm with: npm install @use-crux/local@nightly

Crux v0.5.0

Choose a tag to compare

@github-actions github-actions released this 13 Jul 18:39

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 (runId for the logical operation, traceId for distributed correlation, and segmentId/segmentSeq for 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 .crux deletion is required.

    Add explicit lifecycle ownership for suspend/resume: run.suspend({ reason }) ends the current segment and returns a serializable CruxPropagationCarrier, and observe.resumeRun(carrier, { reason }) opens a fresh segment on the same logical run and emits run:resume before 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 a retryable flag) for every sent record instead of trusting response.ok; a malformed or partial receipt retries every unaccounted-for record. recordId identifies 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 (withWorkersObservableInvocation from the new @use-crux/core/observability/workers subpath, using ExecutionContext.waitUntil with no nodejs_compat requirement), and Convex (createCruxConvex()/action/internalAction/agent/swarm wrappers, bound automatically). Every wrapper reports a structured ObservabilityFlushResult (status, delivered, rejected, remaining, deadlineExceeded) instead of a boolean; pass onDrain to 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 inspect onDrain or 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.observed event/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), maps run:suspend/run:resume correctly instead of crashing the subscriber on those record types, and starts a fresh root span sharing the original traceId on resume rather than reopening a stale one. Add W3C traceparent/tracestate inject/extract helpers and an explicit baggageAttributeAllowlist (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-recordId conflict 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's traceId/runId collision.

    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/conflicted status and unknown/healthy/degraded delivery-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 retrieval rag.recipe/rag.reranker families. A closed DirectlyObservedKind → DefinitionRefRole map 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 authored id; the random per-execution compositionId remains 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.reranker runtime evidence is truthful and collision-free: rerank() now takes a required, named engine (there is no anonymous default-model judge path), and judgeReranker() requires a name. Build the engine with judgeReranker({ name, model }) or an adapter reranker() and pass it to rerank({ engine }). The engine's name is the canonical rag.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/ai into closed CruxFinishReason and CruxProviderError / CruxAdapterError shapes (kind / namespaced code / retryable / optional redacted message). Stream completion failures surface instead of silent missing metadata; completed tool calls are assembled for both generate() and stream(); progressive tool-call argument deltas are not exposed. Abort and budget timeouts classify as aborted / timeout. retryable is 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 for suspended / incomplete / conflicted. Quality signal capture follows nested triggered child runs so flow step matchers are not falsely uncaptured under an eval.case cell.

    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(), and cascade() 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-site routing and route options; variadic fallback(a, b, opts) is replaced by fallback([models], opts); _meta.router / _meta.cascade / _meta.fallback are replaced by result.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 RouteArgs context types and literal route call-profile parameters. Run Detail renders receipt TTFT, bounded attempt errors, and cascade tier note/budget from the same canonical routing.report preview.

    Run Detail now accepts the...

Read more

Crux v0.4.0

Choose a tag to compare

@github-actions github-actions released this 04 Jul 21:02
d9281d7

Highlights

  • Introduce the Retrieval & RAG stable beta public API spine at @use-crux/core/retrieval, including knowledgeBase, named retrievalRecipe, typed retrieval steps, canonical RetrieveRequest, schema-derived metadata filters, recipe traces, and grounding/tool integration types.

    Wire knowledgeBase lifecycle 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 retrievalRecipe runtime. 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 retrievalRecipe sources. 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, supports fail and skip-with-warning source 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.hits payloads with model-facing renderers, and getSource can 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/retrieval mirrors the core retrieval API with Convex runtime storage defaults for knowledgeBase() and store-backed retriever().

    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, and evaluate() can run retrieval recipes directly or through target.recipe(). New retriever spans emit the beta retrieval.retrieve observability 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(), and retrievalRecipe().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 Reranker and judgeReranker(), rerank() accepts custom engines, @use-crux/ai binds native AI SDK reranking, and the Anthropic, OpenAI, and Google adapters expose matching retrievalModel() and judge-backed reranker() 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 emit rag.reranker definitions, rag.recipe.step.uses_reranker relations from rerank({ 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-in rag.recipe_step_unresolved_target lint 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 with DuplicateTaskIdError. Record adapters now need to implement the conditional insert primitive; Convex component refs include a matching insert mutation.

  • 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 expose run(options?), and suspended flows resume through resume(flowId, options?).

    Flows can now declare local typed signal maps with flow(name, { signals }, handler). Signal schemas type both flow.suspend('name') and handle.signal(flowId, 'name', payload), and noPayload() declares notification-only signals.

    Declared signal schemas now validate payloads before handle.signal() writes to persistence and again when flow.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, and expired snapshots 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) and resume(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 with processing kept as a deprecated alias.

    Align Memory store adapters with the beta RecordStore contract: @use-crux/core now exposes a reusable store conformance helper for adapter tests, deprecated private memory/types store aliases point to RecordStore, 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, including RecordStore, RecordEntry, RecordPage, RecordWriteOptions, exact scalar filters, discriminated vector queries, { records, vectors, blobs } bundles, and typed StorageError codes.

    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/vitest provides reusable record/vector/blob conformance suites.

    Move core workspace, indexing, retrieval, indexed knowledge, embedding cache, and semantic cache consumers onto Storage Beta records/vectors/blobs configuration, with vector-backed search requiring pre-filter-capable vector stores.

    Expose Convex and Upstash Storage Beta adapters: Convex now provides convexRecordStore, dense-only convexVectorStore, convexStorage, and a full-lifecycle workspace blob store; Upstash now provides a SCAN-backed Redis RecordStore and a stricter Vector VectorStore that 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.maxTokens is 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.read observations, 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...

Read more

Crux v0.3.0

Choose a tag to compare

@github-actions github-actions released this 29 Jun 18:50
5545464

Highlights

  • Deepen the loop-owned execution boundary into a single gateway-closed LoopRuntimePort, replacing the per-call client threading of the old ExecutorSpec/SdkLoopDialect seam.

    @use-crux/core:

    • Replace ExecutorSpec with LoopRuntimePort (id, describeModel, mapSettings, runTextLoop, runStructuredAttempt, runStream, replayStream). The port is already bound to its SDK client, so each run method takes only an ExecutorRequest — there is no per-call client argument.
    • bind() now returns the client-dependent BoundLoopRuntime (renamed from BoundLoopOwnedRuntime), which core assembles with id/describeModel/mapSettings into the port.
    • Rename executorAdapter(spec)(client) to loopRuntimeAdapter(port).
    • Testing: fakeExecutorfakeLoopRuntime (returns { runtime, calls }); executorSpecConformanceloopRuntimePortConformance (harness prepare() returns { runtime, model }).

    @use-crux/ai:

    • Add createAiSdkLoopRuntime(gateway): LoopRuntimePort<LanguageModel> and the AiSdkLoopRuntime type — the adapter from SdkGateway to the core port. aiSdkProviderRuntime and createCruxAi({ gateway }) are unchanged.

    defineProviderRuntime({ ownership: 'loop-owned', loop }) authoring is unchanged except that loop.bind() now returns runTextLoop/runStructuredAttempt/runStream (was run/attemptStructured/stream).

  • 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 prompt input to thread.generateText(), thread.streamText(), thread.generateObject(), or thread.streamObject().
    • Add profile-backed generateObject() and streamObject() 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, and tools.
    • Add the crux config namespace for Crux-owned lifecycle controls: crux.prepare, crux.runtime.store, crux.runtime.namespace, crux.observe, crux.persistence, and advanced crux.driver. Existing top-level prepare, store, and namespace remain as deprecated compatibility aliases.
    • Move Crux-only prompt resolution to agent.crux.resolve() with direct agent.resolve() kept as a deprecated compatibility alias.
    • Deepen the Convex store document contract with a substitutable ComponentDocumentPort, normalized ConvexStoreDocumentComponent, and createInMemoryConvexStoreDocumentComponent() for server/React boundary tests.
  • Add the public observability event spine APIs: subscribeObservability() for in-process graph-record subscribers and CRUX_OBSERVABILITY_CHANNEL / CruxObservabilityChannelMessage for Node diagnostics-channel consumers.

    Remove the legacy runtime instrumentation hook bus. withTelemetry() now subscribes to the canonical graph-record stream by default, and createOtelRecordSubscriber() 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.recordContent is removed; use the core observability.recordInputs / recordOutputs policy 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/otel maps them to exported gen_ai.client.* attribute constants.

    Restore the documented default withTelemetry() behavior: when no lightweight exporter is configured, @use-crux/otel now 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 projects resolve() / inspect() over the plan's one run(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 skills port 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. New staticTokenizer() fake.
    • compilePrompt() now returns a PromptResolutionPipeline; CompiledPrompt remains 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.ts from their production adapters in resolver/default-ports.ts). No change to the prompt().resolve() / prompt().inspect() runtime behavior or to resolved prompt args.
  • 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(), and task() surface. Plan and task handles are command handles with get()/list() reads, existing entities are bound with plan.ref() and tasks.ref(), creation tools live at plan.tool() and tasks.tool() with safe created() accessors, and the old tasklist, top-level agent/tool factories, and first-match task-list lookup exports are removed from public entrypoints.

    Add typed task definitions for tasks({ items }): keyed task() specs now infer literal task IDs for reads, lifecycle methods, and workers, infer schema-backed complete() 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() and useTasks() with ID-or-handle inputs and no public useTaskList() 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 use flow() 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 both generate() and stream() merge.

    • Configure the built-in lifecycle with GoogleCacheConfig (defaultTtlSeconds, maxEntries, onError: 'fallback' | 'throw', or a custom GoogleCachedContentCachePort), pass false to disable, or pass a fully custom GoogleCachedContentLifecycle.
    • Invalid TTL/config values are rejected (per-call TTL overrides fall back to the default; bad defaultTtlSeconds/maxEntries throw a clear error).
    • New exports: GoogleCacheConfig, GoogleCacheName, GoogleCachedContentCachePort, GoogleCachedContentErrorMode, GoogleCachedContentLifecycle, GoogleCachedContentOption, GoogleCachedContentPlan, GoogleCachedContentPrepareArgs.

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/google consumers to use either @google/genai 1.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 and CRUX_OBSERVABILITY_CHANNEL / CruxObservabilityChannelMessage for Node diagnostics-channel consumers.

    Remove the legacy runtime instrumentation hook bus. withTelemetry() now subscribes to the canonical graph-record stream by default, and createOtelRecordSubscriber() 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.recordContent is removed; use the core observability.recordInputs / recordOutputs policy instead.

    Add observability capture policy controls: config({ observability: { recordInputs, recordOutputs } }). Disabled input/output art...

Read more

Crux v0.2.0

Choose a tag to compare

@github-actions github-actions released this 26 Jun 23:41
88c7b06

Highlights

  • Prepare the first npm release under the @use-crux package scope.

    Document the native AST beta parity gate, release checklist, and experimental.indexer.nativeAst
    troubleshooting guidance.

    Fix make local so the current-platform Rust/Oxc worker binary is replaced atomically when an old
    worker process is still running.