Changelog
What shipped, a week at a time. AcruxCore deploys continuously, so these are weekly summaries rather than numbered releases — the SDKs are the exception and follow semver.
Each major change gets its own heading and up to three bullets, one line each. Minor changes are a single line, no heading.
The two SDKs keep their own release notes, including migration steps for breaking changes:
@acruxcoreai/sdk on npm and
acruxcore on PyPI.
Beta
AcruxCore is in beta and pre-1.0. Breaking changes still happen; when one does, it is called out in the week it ships and in the SDK release notes.
Week of 7 September 2026
Major
The whole team's audit trail, in the dashboard
- Team → Audit trail lists every recorded action — keys, members, gateway, secrets, prompts, tools.
- Filter by area, by a single event, and by who did it; the filters are in the URL, so a view is shareable.
- Owner and admin only; a Bearer key cannot read it, because the trail records what people did. Reference →
One filter bar, on every screen that picks traffic
- Type
tag:,prompt:,input:,meta.<key>:and the rest into a single box; each becomes a chip. - The same bar is on Traces, Feedback, and a dataset's Add example → From feedback.
- Suggestions come from your team's own tags, metadata keys and prompt names. Reference →
Saved views
- Name a filter set and it is one click for the whole team, on Traces or Feedback.
- Any member can rename or delete a view; the filters are stored exactly as you set them. Reference →
Add every row a filter selects, not just the page
- Add all N matching in From feedback builds from criteria instead of ticked boxes.
- It reaches rows on pages you never opened, and says when more matched than one request takes. Reference →
Find a trace by what was actually said
qnow searches the captured request and response, not only names and attributes.q_innarrows a search toinput,outputornamewhen a word appears on both sides.- Payload text is searchable wherever payload capture was on for the trace. Reference →
Filter by prompt, and filter the feedback feed
prompt_idmatches every version of a prompt, so you no longer need the version id.- The feedback feed takes the full trace filter set plus
rating,source,label,has_comment. - One filter vocabulary now covers traces, feedback and dataset building. Reference →
Build a dataset from criteria instead of a hand-picked list
- Both
from-feedbackendpoints accept afilterin place offeedback_ids. - "Every thumbs-down with a comment on the checkout prompt" is one request.
- The response reports
matched, so a selection capped at 100 rows is visible. Reference →
Curate a dataset after you build it
- Add example now has a From feedback tab — pull real rows into a dataset that already exists.
- A row brings its captured variables, its comment as criteria, and its session history.
- A row already in the dataset is reported as skipped, never added twice. Reference →
Edit criteria, drop a row, delete a dataset
- The criteria cell edits in place, so a rubric inherited from a complaint can be reworded.
- Every example row has a remove control, and a dataset can be deleted from either screen.
- Both ask for confirmation first; past experiment runs keep their reports either way.
Choose the model and the instructions that optimize a prompt
- Optimizer model picks which model writes the rewrites, not just what they run on.
- Optimizer prompt swaps the built-in instructions for your own, format still enforced.
- An unregistered optimizer model is now rejected up front instead of failing mid-run. Reference →
Trace a LangChain or LangGraph agent, in Python or Node
- New tutorial builds a two-tool research agent in both languages, traced end to end over OTLP. Tutorial →
- One instrumentor covers chain, tool and LLM spans; adding
openaidouble-counts every call. instrument: ['langchain']ships in Node SDK 0.12.0; Python has had it since 0.11.0.
Evaluate a run your own app rendered
- Send
variablesbesideprompt_version_idand they are stored on the span, not discarded. - A stored prompt with no placeholders can now produce dataset examples from real traffic.
- Those messages are never re-rendered — you rendered them, so the values are lineage only. Reference →
Team API keys now appear in the audit trail
- Fixed — minting or revoking a team-scoped key wrote no audit event, so the trail missed it.
- Both events now name the member who acted and mark the key as team-scoped. Reference →
Minor
- The team audit endpoint takes
event(a comma-separated list) andactorId; both narrowtotal. - A new
/teams/:id/audit/actorslists everyone in the trail, removed members included. - A member role change or removal now reports the affected member's address, not just their id.
- The Team page previews the five newest recorded actions, with a link to the full trail.
- A sixth feature page, Audit, covers what the trail records, the filters, and the roles.
- New guide walks the trail from the Team page to a filtered URL you can paste into a ticket. Guide →
- Core concepts names the split: a trace is traffic your app made, an audit event is a change.
- The home page's round-trip now opens on the trace and closes on the audit trail.
- The compare page's audit-log and RBAC rows now link the guides behind them.
- Fixed — the compare page and the comparison post said five competitors; there are six.
- The nine-platform comparison gains an audit-trail row, and says which two we never checked.
- The docs home and the project README now name Audit among the building blocks.
- The best-open-source-LLMOps page marks best-for, limitations and licence with a coloured icon.
- The comparison matrix marks each verdict with a glyph and shades the AcruxCore column.
- The FAQ's comparison answer now names the audit trail as the row no paid plan gates.
- Fixed — the FAQ said the comparison matrix weighs nine criteria; it weighs ten.
- The security page covers roles and the trail: what it records, and what it keeps out.
- The roles guide says role changes are recorded, and which roles can read the trail.
- Dataset examples show a Prompt column naming the prompt version the row was captured from.
- A dataset row with no variables now shows the prompt's own last message instead of a dash.
- Long variable values in a dataset row clip to one line each, with Show all to read them.
- Feedback rows now name the team member who posted them, not just "Developer".
- Fixed — feedback skipped when building a dataset blamed payload capture even when it was on.
- Fixed — the real reason is now named: a call that sent raw messages has no variables to replay.
- Row delete and edit controls use proper icons and stay visible, instead of a hover-only ✕.
- The dataset page's Optimize button and dialog now say they optimize a prompt, not the dataset.
- Fixed — deleting a dataset logged a 404 in the browser console on the way out.
- Fixed — optimize used a fixed model name a team may never have registered.
- The model picker scrolls past seven models and shows a selected count, instead of growing.
- The models field now says one set of rewrites is tested on every model picked, not one each.
- Fixed — a dialog taller than the window put its own buttons out of reach; it scrolls now.
- Fixed — two appends of the same feedback row at once could file it into a dataset twice.
- Feature pages now explain fallbacks, OTel ingestion, bindings and the optimizer.
- Fixed — the evaluation page's curl sample dropped every id from its URLs.
- Fixed — that sample passed
version_ids: ["v7","v8"]; the API takes version UUIDs. - Tracing is no longer gateway-only on the page; the OpenTelemetry path is named.
- The docs site now publishes
/llms.txt, a summary index of every page for AI crawlers. - A new FAQ page answers how AcruxCore compares, and where it does not fit.
- A new best open-source LLMOps platforms page compares seven.
- Each entry says what that platform is best for, where it falls short, and when it was checked.
- The main site now publishes
/llms.txttoo, and both sites name the AI crawlers they allow. - The home page gained an at-a-glance block: category, licence, deployment, SDKs, price, audit trail.
- Both
/llms.txtfiles and the home page's structured data now state what the audit trail records. - The FAQ answers which platforms log who changed what, and what an audit log costs.
- A new FAQ answer separates a trace from an audit event: traffic sent versus a change made.
- The category page's seventh question asks who changed what, and whether it needs a paid plan.
- The API reference now documents the team-wide audit trail, for owners and admins. Reference →
- The gateway page names the native providers and the compatible connections.
- Each feature page carries a real product screenshot and a first action of its own.
- The homepage names the step it was missing: score a fix before promoting it.
- The homepage lists evaluation and spend guardrails among the reasons to switch.
- Fixed — sitemap
lastmoddates trailed one commit behind the content they describe. - Sitemap dates now track every file a page renders, not only its own component.
- Fixed — the "no eligible rows" error now names each real reason and how many rows hit it.
- A skipped feedback row now says what is missing in a few words, and never points at a setting.
- A tag or model shown on a span is now a link that opens the trace list filtered to it.
- Filtering a list resets the page and clears any selection, instead of leaving both stale.
- Fixed — a span's input and output showed as one long escaped line; nested JSON is decoded now.
- Fixed — "Expand" on a payload removed the height cap and pushed the page away; it scrolls now.
- Fixed — long attribute and metadata values were cut off with nothing to click; they expand now.
- Fixed — a run cell's output was shown as quoted, escaped text instead of what the model wrote.
- The dataset examples table says what a row is in a plain line above the table.
- Both tutorial scripts and a runnable Python notebook ship with the output of a real run.
- The notebook demonstrates a failing tool: the agent answers confidently, and gets it wrong.
- Fixed — the
traces.ingest()link in both SDK references jumped nowhere. - New landing-page overview video: one prompt from versioned template to promoted fix.
- Fixed — a week in this changelog showed a duplicated entry and a stray heading.
- The compare page, the README and the nine-platform post gain a prompt-optimizer row.
- Fixed — the comparison post said no competitor automates a prompt rewrite; two do.
- Each feature page now names its capability in the title, the heading and the page summary.
- The six feature pages link each other by capability, not by a one-word label.
- Fixed — search previews cut every marketing page's description off halfway through.
Week of 31 August 2026
Major
Upstream rate limits answer 429 with the provider's own reason
- Provider 429s now answer
429 PROVIDER_RATE_LIMITED, not an opaque502 PROVIDER_ERROR. - The provider's own reason and its
Retry-Aftercome through, so quota and pace differ. Reference → - Streaming requests answer the same way, as JSON, before any bytes are written.
Start a dataset from the dashboard, without waiting for feedback
- New dataset on Evaluations → Datasets creates an empty dataset — no traffic needed.
- Add example writes one row by hand: named variable fields, or raw JSON for other types. Guide →
Evaluation runs and experiments can be deleted
DELETE /api/v1/runs/:idremoves a run and its cells; the Runs tab has a Delete action.DELETE /api/v1/experiments/:idremoves an experiment and every run under it. Reference →- Both answer
409 RUN_IN_FLIGHTwhile a run is still queued or running.
Report your own spans without waiting for the network
traces.ingest(..., wait=false)buffers the trace and returns a usable trace id at once.- Measured at the call site: 6.5ms awaited, 0.017ms buffered, on a local API. Node · Python
- New
traces.flush()drains the buffer; both SDKs, both unchanged by default.
Minor
- Fixed — the feedback summary grouped by prompt version showed a raw id, not a name.
- Feedback summary buckets now carry
labelandpromptIdalongside the unchangedkey. Reference → - Sessions can be searched by id from the page itself, not only by editing the URL.
- Fixed — the Evaluations → Runs tab was headed "Datasets" and described the wrong page.
- Fixed — a custom provider base URL dropped every upstream response header.
Week of 17 August 2026
Major
Traces are named by what ran, not by a timestamp
- Traces sent over OTLP now take their root span's name instead of the time they started.
- A trailing run id is trimmed, so two runs of the same crew share one searchable name.
- A tool loop that joins an existing trace no longer renames it to
runToolLoop. Guide →
Name a trace as a fallback, without overwriting a name it already has
- New
x-trace-name-if-unsetheader (and bodytrace.nameIfUnset) on gateway completions. - It names a new trace, and is ignored on one that already has a real name.
x-trace-nameis unchanged: still an instruction, still overwrites. Reference →
A chat() call with a trace option no longer counts itself twice
- Fixed — passing
tracetogateway.chat()reported a secondllmspan per call. - Span counts, per-trace token totals and per-run call counts were all wrong, silently.
tracenow also carries the name, trace id and session id throughchat(), as on the loop. Reference →
A provider's 400 now names the rule you broke
- The gateway forwards the provider's own message for a 400, 404, 413 or 422.
- A strict-mode
response_formaterror names the exact property, not just "status 400". - 401, 403, 429 and every 5xx stay summarised — those describe the connection, not your request. Reference →
OpenAI's cached prompt tokens are now billed at the cached rate
- A repeated prompt prefix that OpenAI serves from cache is charged at half the input rate.
usage.cached_tokensis returned on the gateway response, as a subset ofprompt_tokens.- Costs in traces, budgets and usage were overstated for any repeated system prompt.
Both SDKs released as 0.10.0
npm i @acruxcoreai/sdk@0.10.0andpip install -U acruxcorecarryclient_tools.- New
prompts.list_aliases()/listAliases()reads which version an alias points at. - Python
async with AcruxCore()now closes its HTTP connection pool on the way out. Guide →
Run a prompt's client tools without writing a dispatcher
- Both SDKs take
client_tools/clientTools: tool name to the function that runs it. - Nothing is written to the catalog, so the tool's definition and its binding's pin stay put.
- A missing implementation stops the run before the first model call, naming the tool. Guide →
Connect a tool to a prompt by choosing its alias
- Bind a catalog tool to a prompt in one write — no version to commit, no alias to promote.
- Give one prompt alias its own tools: a different build of one, or none at all.
- Breaking:
POST /prompts/:id/versionsno longer acceptstools— bind the tool instead. Guide →
See what a render will really call
render()returnstoolResolutions: the tool alias followed, its version, and the binding.sourcereadsaliaswhen the prompt alias has its own binding,defaultwhen inherited. Reference →
See when a tool's code changed
- New
GET /api/v1/tools/:id/audittrail: version commits, code-sync pushes, and binding changes. Reference →
Evaluation rules: real models, real filters, custom judge prompts
- Judge model is now a required dropdown — no more silent fallback to an unregistered model.
- Match filter's model, prompt+alias, and tags fields are now dropdowns, not free text.
- Use one of your own Prompts as the judge's grading template instead of the built-in one. Guide →
Run a prompt's tools in two lines
gateway.runPromptWithTools(rendered)takes a render result and fills in the rest.- Model, messages, bound tools and prompt lineage all come from the render, not the call site.
- A binding pinned to an exact tool version now travels as a pin, not as its alias. Guide →
A tool-using agent can stream its answer
stream: trueon the tool loop yields typed events:content,tool_call,tool_result,done.- Same trace as an unstreamed run — one
llmspan per round, tool spans nested under it. - Both SDKs, and on
runPromptWithToolstoo. Guide →
Client-side tool loops keep their prompt lineage
- Fixed — SDK loops produced
llmspans with no link back to the prompt version. POST /gateway/chat/completionsnow acceptsprompt_version_idnext to your ownmessages.- Both SDKs send it automatically; a version from another team is rejected, not stamped. Reference →
Both SDKs released as 0.9.0
npm i @acruxcoreai/sdk@0.9.0andpip install -U acruxcorecarry everything above.- Breaking: committing a version no longer takes
tools— bind the tool to the prompt. - Breaking: the
tool-routesendpoints are gone; the binding methods replace them. Guide →
Minor
tool_refsandPOST /tools/resolvenow takeversionto pin one exact tool build.- Fixed — an undecryptable provider credential now returns a clear 409, not an opaque 500.
- Fixed —
group_by=daytrace analytics bucketed days in the server timezone, not UTC. - Fixed — the changelog showed one week as two sections, dated three days apart.
GET /traces/facetsnow also returns distinct resolved models, for filter pickers.- Corrected — comparison posts now reflect AcruxCore's rule-based online evaluation. Reference →
- New tutorial: a travel planner that picks between three tools, or calls none at all. Tutorial →
- Nine screenshots across the tutorials and guides now show the current alias-keyed Tools tab.
- Fixed — Python tabs in five tutorials called Node method names and Node argument shapes.
- Fixed — the Python/Node tabs for scripting gateway setup called two methods no SDK has.
- Fixed — the API reference's
datasets.createFromFeedbackexample named a method that does not exist. - Fixed — the trace-tagging guide still used the flat
get_trace()/getTrace()removed in SDK 0.7.0. - Four tutorials now ship a runnable
setup_prompt.pyfor the prompt-and-tool setup step. - Fixed — a malformed JSON body now returns 400
INVALID_JSON, not 500, so clients stop retrying it. - Fixed — an oversized body returns 413 and an unsupported
Content-Encodingreturns 415. - The travel-planner tutorial now shows every setup step twice: the dashboard click-through and the code.
- Tool parameters: a checkbox now writes
additionalProperties: false, no raw JSON needed. - Fixed — "Back to builder" on a tool version no longer looks dead; it greys out with a reason.
- New guide: where a tool's definition should live, and what changes in traces and deploys. Guide →
- That guide also ships as a runnable notebook, with a preflight check for a brand new account. Guide →
- The travel-planner tutorial now ships as a runnable notebook too, written for a first-timer. Tutorial →
- The Python SDK tool-calling tutorial ships as a runnable notebook, with both setup routes shown. Tutorial →
- Fixed — the New tool dialog implied its description always reaches the model.
- Resolving a tool now says it has no committed version, instead of answering a bare 404. Reference →
- SDK errors now carry the API's own message, so the reason is in the exception you catch.
- Fixed — three tutorials no longer install
langchain-community, which is being sunset. Tutorial → - The Tavily tutorials now use Tavily's own
tavily-pythonSDK instead of a LangChain wrapper. Tutorial → - The no-SDK REST tutorial ships as a runnable notebook, including what unthreaded traces look like. Tutorial →
- The ReAct agent tutorial ships as a runnable notebook, covering who records a span on the BYO path. Tutorial →
- The configurable-agent tutorial ships as a runnable notebook, swapping model and persona by alias. Tutorial →
- The medical-information tutorial ships as a runnable notebook, with a citation check on every answer. Tutorial →
- The supervisor multi-agent tutorial now ships as a runnable notebook, routing traps included. Tutorial →
- The BYO-provider RAG tutorial now ships as a runnable notebook, with a live provider check. Tutorial →
- The CrewAI tracing tutorial now ships as a runnable notebook, with four OTLP wiring traps. Tutorial →
- Fixed — the CrewAI tutorial's install command was missing the
tavily-pythonclient. - The OpenAI Agents SDK tutorial now ships as a runnable notebook, handoff span included. Tutorial →
- Fixed — a CrewAI trace is now named
Crew.kickoff, not once per run id, so names group. Tutorial → - Fixed — an SDK error from your own provider now names the reason, not just the status.
- Fixed — the SDK now says a model is required, rather than letting your provider guess one.
- Fixed — screenshots in every runnable notebook now load in GitHub, nbviewer and Jupyter.
- Runnable notebooks no longer repeat the API-key dialog screenshot; the menu path is enough.
- The tutorials now run on five models across OpenAI, Anthropic, Gemini, Llama and Mistral. Tutorial →
- Fixed — the ReAct agent tutorial said an OpenRouter key would not work; any provider does. Tutorial →
- Fixed — the travel-planner notebook crashed on a model registered without prices.
Week of 10 August 2026
Major
Score live traffic automatically with evaluation rules
- Create a standing rule that judges matching production calls with no run and no click.
- Filter by prompt, model, or tag; sample and cap spend; get alerted below a threshold. Guide →
OTLP trace ingestion
- New
POST /api/v1/traces/otlpaccepts real OpenTelemetry exports over OTLP/HTTP - Works with CrewAI, LangChain, LlamaIndex via
openinference-instrumentation-*— no code change - Reference →
SDK 0.8.0 (Python) — acruxcore.otel helper
acruxcore.otel.register()wires the OTLP pipeline in one call, withinstrument=[...]for CrewAI, LangChain, LlamaIndex, OpenAI, and the OpenAI Agents SDK- New optional extra:
pip install 'acruxcore[otel]' - Guide →
SDK 0.8.0 (Node) — @acruxcoreai/sdk/otel helper
- New subpath export wires the OTLP pipeline in one call, with
instrument: [...]for OpenAI and the OpenAI Agents SDK @opentelemetry/*packages are new optional peer dependencies- Guide →
Minor
- Fixed — OTLP exports with input/output data could fail on retry instead of succeeding.
- Fixed — LLM cost showed blank for provider-dated model ids (e.g.
gpt-4o-mini-2024-07-18). - New tutorials: trace a CrewAI crew and an OpenAI Agents SDK app over OTLP.
- Blog tag and author pages (
/blog/tags,/blog/authors, and their archives) are now markednoindexso they stop competing with the posts they link to in search results. - Corrected — comparison posts now state the gateway's spend caps and rate limits correctly. Reference →
- Compare — a row where a competitor lands in the same place as AcruxCore is now marked "Tie". Reference →
- Compare — the Tool catalog row now records our edge over MLflow's MCP server registry.
- Fixed — the comparison table cut off its last column on wide screens, at any zoom level.
- Repo README now opens with a 35-second demo: prompt, version, tool, a real model call, the trace.
Week of 3 August 2026
Major
SDK trace analytics and sessions bindings
- New
hub.tracesnamespace: analytics, facet discovery, and payload-capture settings. - New
hub.sessionsnamespace lists sessions and reads one session's full trace history. - Feedback summary and the team-wide feedback feed are now reachable via
hub.tracestoo.
SDK 0.6.7 — trace tags and metadata
chat()and the tool loop now accepttags/metadatain trace options, sent as gateway headers.- Both SDK packages now link back to the public GitHub repo.
AcruxCore is now open source
- Source is public at github.com/AcruxCore/AcruxCore.
- Licensed under Elastic License 2.0;
packages/sdkandpackages/sdk-pythonstay MIT. - Contributions welcome — see
CLA.mdin the repo before opening a pull request.
Past evaluation runs are now listed in one place
- A new Runs tab on Evaluations lists every run, newest first, with its score and best variant.
- A run's report is reachable long after the fact — closing the tab no longer loses it.
GET /api/v1/runsreturns the same history, filterable by status, dataset or prompt. Reference →
Evaluations and optimize now use full conversation context
- Feedback on a session now carries its prior turns into the dataset example.
- A run replays that history before the new turn, so candidates see the real context.
- The judge and the optimizer read it too, so scores and rewrites match the conversation.
Optimize and experiments can now pick their baseline alias
- New
aliasfield — targetstaging,dev, or any alias instead ofproduction. - Baseline still defaults to
production, falling back to the latest version if none. - Feedback-built datasets now warn (never block) if examples came from a different prompt.
SDK prompt version lifecycle
- Both SDKs now manage prompts end to end: create, commit, list, diff, and promote versions.
- Export and import move a version between teams or environments as one JSON document.
- Look up every trace a specific prompt version produced, from either SDK.
SDK tool catalog lifecycle
hub.tools/client.toolsgained: create, list, get, update, delete, versions, promote, analytics.- Available in both TypeScript and Python SDKs — see the Tool Catalog guide.
Apache License 2.0
- Permissive, OSI-approved, with nothing gated.
- Fork it, self-host it, or sell what you build; the AcruxCore name and logo stay trademarked.
@acruxcoreai/sdkandacruxcoreship under the MIT license.
SDK 0.7.0 — Resource-based namespace pattern
- Breaking: All flat client methods removed. Use
hub.gateway.chat(),hub.prompts.render(),hub.traces.ingest()etc. instead ofhub.chat(),hub.renderPrompt(),hub.trace(). hub.gateway.stream()is now a standalone method (previouslyhub.chat({stream: true})).hub.gateway.flush()/hub.gateway.close()replacehub.flush()/hub.close().
Evaluations are now scriptable from both SDKs
hub.datasets,hub.experiments,hub.runs, andhub.optimizeexpose 19 methods for the full evaluations domain.- Create datasets, run experiments, poll results, read reports, and promote optimizer candidates without leaving your code.
One-command local self-host
- New
docker-compose.local.ymlbundles Postgres, Redis, API, worker and web in one file. docker compose -f docker-compose.local.yml up --build— no.envto fill in first.
Minor
- Fixed — the trace settings API reference showed the wrong payload-capture default.
- Fixed — six API reference pages showed a stale 401 error message.
POST /datasets/from-feedbacknow accepts at most 100 feedback ids per request.- Fixed — the Python SDK tool-calling tutorial's decorator example had a broken import.
- Tutorial and guide pages now show a short snippet plus a link to the full runnable script.
- Tutorial script links now point to scripts that were actually run and verified.
- New guide — evaluate a prompt with conversation history.
- New guide — view trace analytics.
- New guide — configure trace payload capture.
- New guide — look up the traces a prompt version produced.
- A
LICENSE,TRADEMARK.md, andCLA.mdnow ship at the repo root. - Fixed — the
/sdkpage's Python tutorial links 404'd (wrong docs path). - The
/sdkpage now links five capability guides per language, and its code samples show a decorated tool call and session tracing. - Three SDK guides — chat, tracing, and gateway routing — now show Python code alongside Node's.
- Added — an "Optimize" button on a dataset's page starts a run without rebuilding it.
- Added —
GET /api/v1/healthreports database and Redis reachability for load balancers and uptime monitors. - Terms, Privacy and the site footer now name AcruxCore without a corporate suffix.
- Fixed — routing requests to OpenAI reasoning models (
o1,o3,o4-mini,gpt-5) no longer 400s withUnsupported parameter: 'max_tokens'; the gateway now sendsmax_completion_tokensto OpenAI, whileopenai_compatibleproviders keepmax_tokens. - Fixed — the model-page "Test" button works for reasoning models (
o1,o3,o4-mini,gpt-5); the connectivity ping no longer sends a 1-token cap those models can't meet. - Privacy names AcruxCore as the controller for the hosted service, with a contact address.
- New guide — Product tour: tools, streaming, traces, feedback, and evaluation in one walkthrough.
- Fixed — rendering a prompt with a
{% for %}loop no longer wrongly demands the loop variable as an input. /comparepages now show AcruxCore's real one-command Docker self-host./compare's Self-hosting row now reads "docker compose up" for every column, matching the identical command.- The product name is now one word — "AcruxCore" across the site, docs, and both SDKs.
- SDK 0.7.1 — the rename reaches both packages' metadata; no API or behaviour change.
- The repo README now carries the competitor comparison table, losses and ties included.
- The SDKs page now links the full TypeScript and Python API reference.
- Fixed — marketing pages answered on two addresses;
/pricing/now redirects to/pricing. - Fixed — marketing pages showed the flat client methods SDK 0.7.0 removed.
- 11 blog post titles and 12 descriptions were shortened so search engines stop truncating them.
Week of 27 July 2026
Major
Tracing no longer slows your model calls down
- Spans queue in the background — the model's answer no longer waits on a trace write.
- About 570 ms off every traced call, ten times what the gateway's own routing costs.
- Reading traces right after a call needs
await hub.flush()first — both SDKs at 0.6.5.
Tools are now defined once, in code
- A decorated function is the tool — no create → commit → promote for a code-owned tool.
POST /tools/synccommits only when the spec really changed, and moves the alias. Reference →- Both SDKs at 0.5.0 — breaking: raw tool definitions move to
toolDefs/tool_defs=.
Streamed gateway completions are traced
- A streamed call was billed but wrote no
llmspan, so it was invisible in traces. - Tool spans under a streamed call were orphaned, and now nest where they belong.
- Streaming records the same span a non-streamed call does.
Queued evaluation runs and outbound email could stall forever
- The API and the worker could each reach a different Redis, so neither read the other's work.
- Runs sat at
queued, and invites, verification mail and digests were never sent. - Fixed — restart any run of yours still sitting at
queued.
The judge scored correct answers as failures on feedback-derived criteria
- A feedback comment describes the reply that provoked it, not the answer you want.
- The judge read it as describing the output, so a correct rewrite could still score 0.
- Re-run any optimize or experiment run you judged against feedback criteria.
Optimize runs could fail while the rewrites were fine
- The optimizer's example showed a lone
systemmessage, so candidates dropped the variables. - One bad escape in the model's JSON threw the response away; near-valid JSON is now repaired.
- A rejected candidate is now named with its reason instead of a bare failure.
A team member now holds exactly one role — a breaking API change
- Invites and role updates take
{"role": "editor"}; the array form now returns400. GET /auth/me,/auth/teams,/teams/:id/membersand/invitesreturn arolestring.- Nobody lost access — anyone who held more than one role keeps their highest. Invite a teammate →
You can now use the SDK without our AI gateway
- Bring your own OpenAI-compatible key and base URL; the key never touches our servers.
- Tracing still works — the SDK reports its own spans, streaming and non-streaming. SDK guide →
- Both SDKs at 0.6.0, no breaking changes; an HTTP 429 now retries like a 5xx.
The SDK render cache could send the wrong prompt to the model
- The 60-second cache key left out your variables, so a new question got the first render.
- Variables are now part of the key, and their order does not split an entry.
cacheTtl/cache_ttlof0really disables the cache instead of always serving stale.
response_format support on the gateway
- Pass structured-output requests straight through for OpenAI and Gemini models.
- Anthropic models get the same contract via an internal forced-tool-call translation — no caller-visible difference.
- Both SDKs at 0.6.6 accept
responseFormat/response_formatdirectly, liketools/toolChoice.
Google Analytics, gated behind a cookie-consent banner
- A cookie banner now shows once, site-wide; analytics cookies are set only if you accept.
- One consent choice covers both acruxcore.com and docs.acruxcore.com — no re-prompt.
- Change your choice any time from "Cookie preferences" in the footer.
SDKs now forward trace tags and metadata to the gateway
chat()andrunToolLoop()/run_tool_loop()passtagsandmetadataas gateway headers automatically.runToolLoopalso forwards them asx-span-tags/x-span-metadata, tagging each gateway LLM span. New guide →
Minor
- A "Beta" badge in the landing hero, matching the one the signed-in app already showed.
- A product demo plays on the home page.
- The home page's code panel switches between TypeScript and Python, with a tab to pin one.
- New writing — a hands-on comparison of LangSmith, Langfuse, PromptLayer and AcruxCore.
- Re-measured — how much overhead an LLM gateway adds now benchmarks five paths including bring-your-own-key, on one fresh run.
- A real logo — a crescent and compass rose, across the site, docs, browser tab and previews.
- Tool release notes are separate from the model-facing description.
- Code-owned tool warning in the dashboard before an edit the next deploy will supersede.
- Tool loops route by executor type —
httpruns on the platform,clientruns locally. - Rendering a prompt now returns its version id and number, linking a trace to that version.
chat()can thread manual calls into one trace viatrace: { traceId, sessionId }.- A bring-your-own provider URL is checked for HTTPS — warned once if it is plain
http://. - Hardening — the gateway's token estimate is bounded, so one odd prompt cannot slow others.
- New guide — build a RAG agent without the gateway.
- New guide — improve a prompt from feedback.
- The streaming-trace post now carries the production run that verified the fix.
- The Quickstart's Python tab now uses the
acruxcoreSDK instead of rawrequests. - Core concepts was rewritten around the new tool path.
- Fixed — a signed-in visitor clicking the public site's logo or nav was bounced into the app.
- Fixed — the sign-in page and the signed-in app's sidebar still showed the old placeholder mark.
- Fixed — list bullets stopped rendering on the site's written pages.
- Fixed — a run report's delta badge printed
+66.66666666666667beside a score reading66.7. - Fixed — errors from local development were reported to the monitor alongside production ones.
- Fixed — several site code samples still showed the pre-0.5.0 way of passing a prompt's tools.
- Fixed — the TypeScript SDK's npm package page linked a private source repo that 404s for visitors.
- Fixed — simultaneous tool syncs could create two tools with one name, or fail with a
500. - Fixed — a first sync targeting a custom alias reported success without creating it.
- Fixed — a duplicate tool name now returns
409 TOOL_NAME_TAKEN, not a hidden second tool. - Fixed — accepting the cookie banner on the site did not actually start analytics.
- New Tutorials section — end-to-end agent builds split out from single-feature guides.
- New guide — manage team roles and permissions.
- New guide — scope access with virtual keys.
- New guide — alias and track usage of tools in the catalog.
- New guide — automatic model fallbacks.
- New guide — set spend limits with gateway budgets and rate limits.
- New guide — diff, export, and import your prompt library.
- Evaluate a prompt now frames the baseline comparison as a pre-ship gate.
- New writing — how much latency and spend exact-match gateway caching actually saves.
- New writing — comparing Anthropic, OpenAI, and Gemini request shapes behind one gateway API.
- Fixed — a malformed prompt id in the URL returned a raw
500instead of a clear400. - Fixed — deleting a tool could leave a secret it referenced permanently undeletable.
- New guide — tag and filter traces.
- New tutorial — build a ReAct agent with a real Yahoo Finance news tool.
- New tutorial — build a configurable ReAct agent with real Tavily search.
- New tutorial — build a supervisor multi-agent system with real finance/research/writing subagents.
- New tutorial — build a Medical-Information QA agent demonstrating
response_format.
Week of 20 July 2026
Major
Self-hostable authentication
- Auth moved from Supabase to Better Auth, so no hosted identity provider is needed.
- Existing sessions and sign-in flows are unchanged.
API keys are hashed at rest and shown once
- A key is displayed a single time when created, then stored only as a SHA-256 hash.
- Keys created before this change were removed — they could not be migrated.
Transactional email, event notifications and a weekly usage digest
- Invites, email verification and password resets now send real mail.
- Each team can opt in to event notifications and a weekly usage summary.
- Every message carries a one-click unsubscribe.
Python SDK
acruxcoreon PyPI — async, and at parity with the TypeScript SDK.- Prompt render, gateway chat and streaming, tool loops, traces and feedback.
- Shipped with a text-to-SQL agent guide.
Minor
- Prompt default model — a render no longer repeats the model the prompt was written for.
- Error monitoring across the API, the worker and the dashboard.
- A security hardening pass across the gateway, prompt rendering, membership and traces.
- The public site and docs site were rebuilt for launch, including SEO and footer pages.
- Fixed — a worker start-up race could silently drop the email, eval-run and digest workers.
- Fixed — clicking the in-app logo now opens the landing page instead of doing nothing.
Week of 13 July 2026
Major
One trace per agent run
- A client-side tool loop threads a trace id, so a multi-step run is a single trace.
- The gateway's
llmspans and yourtoolspans appear in one tree. - Previously every model call produced a trace of its own.
Tool calls run in parallel
- When a model asks for several tools at once, the loop dispatches them concurrently.
- Previously they ran one after another.
The SDK gained the core LLM methods
- Chat, streaming and feedback, alongside prompt rendering.
- An agent no longer needs a provider client of its own.
Minor
- Trace payload capture is on by default for new teams, and stays switchable per team.
- The API reference was reorganized by domain and is curl-verified.
- New guide — a tool-calling agent in Python without the SDK.
- New guide — a tool-calling agent in the dashboard, no code.
- New guide — storing prompts and tools via the API.
- Fixed — a tool or trace name with non-ASCII characters could break the gateway request.
This changelog starts on 13 July 2026. Anything before that predates the public beta.