From 807ce2480fc11f781c84ebcc6f648a4f60a75ac4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 18 Aug 2026 22:46:01 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=A6=8B=20New=20version=20release?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../usage-provenance-and-response-id.md | 34 ------------------ .../src/SmooAI.SmoothOperator.Core.csproj | 2 +- go/version.go | 2 +- python/core/pyproject.toml | 2 +- python/core/uv.lock | 2 +- rust/smooth-operator-core/Cargo.toml | 2 +- rust/smooth-operator-temporal/Cargo.toml | 2 +- typescript/core/CHANGELOG.md | 35 +++++++++++++++++++ typescript/core/package.json | 2 +- typescript/temporal/CHANGELOG.md | 7 ++++ typescript/temporal/package.json | 2 +- 11 files changed, 50 insertions(+), 42 deletions(-) delete mode 100644 .changeset/usage-provenance-and-response-id.md diff --git a/.changeset/usage-provenance-and-response-id.md b/.changeset/usage-provenance-and-response-id.md deleted file mode 100644 index a14ce83..0000000 --- a/.changeset/usage-provenance-and-response-id.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -'@smooai/smooth-operator-core': minor ---- - -Carry cost/usage provenance and the gateway response id out of the engine, so nothing downstream can -publish a fabricated number as a measurement. - -`collect_stream` invents a usage struct whenever a response carries no usage chunk — which LiteLLM -does for every `smooth-*` alias — hardcoding `prompt_tokens = 0` and estimating `completion_tokens` -as `content.len() / 4`. The estimate is kept, because budget enforcement needs something to multiply, -but it is now flagged: `LlmResponse.usage_estimated`, aggregated onto `AgentEvent::Completed` as -`usage_estimated`. This is what let production record `input_tokens = 0` on every streamed turn -beside an output count that only ever tracked the reply's length. The old comment there claimed the -estimate would "produce a real cost number against ModelPricing"; it does not, and it now says so. - -`AgentEvent::Completed` also gains `cost_estimated` — true once any call in the run was priced from -the local `ModelPricing` table instead of the gateway's own figure. That table cannot price aliased -routes and returns the free tier for anything it does not recognise, so a tainted total may be a wild -under-count while looking exact. Cost and usage provenance are tracked separately on purpose: the -gateway reports cost on an HTTP header and usage on an SSE chunk, so either can be authoritative -while the other is a guess. - -Finally, the gateway's response id (`chatcmpl-…`, or `msg_…` on the Anthropic-native path) is now -captured off both the streaming and non-streaming paths and surfaced as `LlmResponse.response_id` and -`AgentEvent::Completed.response_id`. It was previously discarded at deserialization. It is the join -key to `LiteLLM_SpendLogs.request_id`, whose row carries the gateway's authoritative dollars **and** -its real prompt/completion counts — the only trustworthy source for either while the flags above can -be set. - -All three fields cross the Temporal activity boundary via `ModelCallOutput`, so a durable replay -cannot silently launder an estimate back into a measurement. `smooth-operator-temporal`'s core -requirement moves 1.8 -> 1.9 accordingly. - -Note for consumers matching exhaustively on `StreamEvent`: this adds a `ResponseId` variant. diff --git a/dotnet/core/src/SmooAI.SmoothOperator.Core.csproj b/dotnet/core/src/SmooAI.SmoothOperator.Core.csproj index 6c81f32..a881854 100644 --- a/dotnet/core/src/SmooAI.SmoothOperator.Core.csproj +++ b/dotnet/core/src/SmooAI.SmoothOperator.Core.csproj @@ -15,7 +15,7 @@ SmooAI.SmoothOperator.Core - 1.9.0 + 1.10.0 SmooAI SmooAI Native C# implementation of the smooth-operator agent engine — the in-process, Microsoft.Extensions.AI-based sibling of the Rust smooai-smooth-operator-core. Drive an agentic tool-calling loop over any IChatClient; author tools from ordinary C# methods with AIFunctionFactory. Learns from Microsoft Agent Framework idioms. diff --git a/go/version.go b/go/version.go index 3e9aef6..7794314 100644 --- a/go/version.go +++ b/go/version.go @@ -5,4 +5,4 @@ package e2e // language artifacts. The real Go "publish" is a git tag (go/v); this // constant is the anchor that scripts/sync-versions.mjs keeps in sync with the // canonical npm version on every changeset release. -const Version = "1.9.0" +const Version = "1.10.0" diff --git a/python/core/pyproject.toml b/python/core/pyproject.toml index 31fdd8f..e45ffd4 100644 --- a/python/core/pyproject.toml +++ b/python/core/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "smooai-smooth-operator-core" -version = "1.9.0" +version = "1.10.0" description = "Native Python implementation of the smooth-operator agent engine — an in-process, OpenAI-compatible agentic tool-calling loop with knowledge grounding. The Python sibling of the Rust reference engine and the C# core." readme = "README.md" license = { text = "MIT" } diff --git a/python/core/uv.lock b/python/core/uv.lock index 200bfa8..05c595b 100644 --- a/python/core/uv.lock +++ b/python/core/uv.lock @@ -415,7 +415,7 @@ wheels = [ [[package]] name = "smooai-smooth-operator-core" -version = "1.9.0" +version = "1.10.0" source = { editable = "." } dependencies = [ { name = "openai" }, diff --git a/rust/smooth-operator-core/Cargo.toml b/rust/smooth-operator-core/Cargo.toml index 207e54e..a95d4cf 100644 --- a/rust/smooth-operator-core/Cargo.toml +++ b/rust/smooth-operator-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "smooai-smooth-operator-core" -version = "1.9.0" +version = "1.10.0" edition = "2021" license = "MIT" repository = "https://github.com/SmooAI/smooth-operator-core" diff --git a/rust/smooth-operator-temporal/Cargo.toml b/rust/smooth-operator-temporal/Cargo.toml index 213048b..5719f1f 100644 --- a/rust/smooth-operator-temporal/Cargo.toml +++ b/rust/smooth-operator-temporal/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "smooai-smooth-operator-temporal" -version = "1.9.0" +version = "1.10.0" edition = "2021" description = "Optional Temporal-backed durable execution backend for the smooth-operator agent engine (ADR-030)." license = "MIT" diff --git a/typescript/core/CHANGELOG.md b/typescript/core/CHANGELOG.md index 06f7c3a..a6e7e66 100644 --- a/typescript/core/CHANGELOG.md +++ b/typescript/core/CHANGELOG.md @@ -1,5 +1,40 @@ # @smooai/smooth-operator-core +## 1.10.0 + +### Minor Changes + +- 418d996: Carry cost/usage provenance and the gateway response id out of the engine, so nothing downstream can + publish a fabricated number as a measurement. + + `collect_stream` invents a usage struct whenever a response carries no usage chunk — which LiteLLM + does for every `smooth-*` alias — hardcoding `prompt_tokens = 0` and estimating `completion_tokens` + as `content.len() / 4`. The estimate is kept, because budget enforcement needs something to multiply, + but it is now flagged: `LlmResponse.usage_estimated`, aggregated onto `AgentEvent::Completed` as + `usage_estimated`. This is what let production record `input_tokens = 0` on every streamed turn + beside an output count that only ever tracked the reply's length. The old comment there claimed the + estimate would "produce a real cost number against ModelPricing"; it does not, and it now says so. + + `AgentEvent::Completed` also gains `cost_estimated` — true once any call in the run was priced from + the local `ModelPricing` table instead of the gateway's own figure. That table cannot price aliased + routes and returns the free tier for anything it does not recognise, so a tainted total may be a wild + under-count while looking exact. Cost and usage provenance are tracked separately on purpose: the + gateway reports cost on an HTTP header and usage on an SSE chunk, so either can be authoritative + while the other is a guess. + + Finally, the gateway's response id (`chatcmpl-…`, or `msg_…` on the Anthropic-native path) is now + captured off both the streaming and non-streaming paths and surfaced as `LlmResponse.response_id` and + `AgentEvent::Completed.response_id`. It was previously discarded at deserialization. It is the join + key to `LiteLLM_SpendLogs.request_id`, whose row carries the gateway's authoritative dollars **and** + its real prompt/completion counts — the only trustworthy source for either while the flags above can + be set. + + All three fields cross the Temporal activity boundary via `ModelCallOutput`, so a durable replay + cannot silently launder an estimate back into a measurement. `smooth-operator-temporal`'s core + requirement moves 1.8 -> 1.9 accordingly. + + Note for consumers matching exhaustively on `StreamEvent`: this adds a `ResponseId` variant. + ## 1.9.0 ### Minor Changes diff --git a/typescript/core/package.json b/typescript/core/package.json index 764b17c..2073eb6 100644 --- a/typescript/core/package.json +++ b/typescript/core/package.json @@ -1,6 +1,6 @@ { "name": "@smooai/smooth-operator-core", - "version": "1.9.0", + "version": "1.10.0", "description": "Native TypeScript implementation of the smooth-operator agent engine — an in-process, OpenAI-compatible agentic tool-calling loop with knowledge grounding. The TypeScript sibling of the Rust reference engine, the C# core, and the Python core.", "type": "module", "license": "MIT", diff --git a/typescript/temporal/CHANGELOG.md b/typescript/temporal/CHANGELOG.md index b8132a6..d13d263 100644 --- a/typescript/temporal/CHANGELOG.md +++ b/typescript/temporal/CHANGELOG.md @@ -1,5 +1,12 @@ # @smooai/smooth-operator-temporal +## 1.9.3 + +### Patch Changes + +- Updated dependencies [418d996] + - @smooai/smooth-operator-core@1.10.0 + ## 1.9.2 ### Patch Changes diff --git a/typescript/temporal/package.json b/typescript/temporal/package.json index d8dcf74..4138f18 100644 --- a/typescript/temporal/package.json +++ b/typescript/temporal/package.json @@ -1,6 +1,6 @@ { "name": "@smooai/smooth-operator-temporal", - "version": "1.9.2", + "version": "1.9.3", "description": "Optional Temporal-backed durable execution backend for the smooth-operator agent engine (ADR-030). The TypeScript sibling of the Rust `smooth-operator-temporal` crate — an agent turn runs as a Temporal workflow whose model call and tool invocations are activities, driving the same `driveTurn` loop as the in-process executor.", "type": "module", "license": "MIT",