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. - Fixed — a docstring-less tool wrongly warned a deploy would undo its dashboard wording.
- 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.
- The best-open-source-LLMOps page answers the audit question in shorter, plainer sentences.
- The FAQ and the open-source LLMOps comparison page are rewritten in shorter, plainer sentences.
- The comparison matrix reads as plain sentences, and every licence row is worded the same way.
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/[email protected]andpip 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/[email protected]andpip 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.