From 33ebd7c22fd46f48bbcda8b06723d747e452e2ff Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 18 Aug 2026 21:59:43 +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 --- .changeset/otel-org-scope-and-turn-cost.md | 11 ----------- ...mooAI.SmoothOperator.Server.AspNetCore.csproj | 2 +- .../SmooAI.SmoothOperator.Server.Postgres.csproj | 2 +- .../src/SmooAI.SmoothOperator.Server.csproj | 2 +- examples/web-chat/CHANGELOG.md | 7 +++++++ examples/web-chat/package.json | 2 +- go/version.go | 2 +- python/pyproject.toml | 2 +- python/server/pyproject.toml | 2 +- rust/Cargo.lock | 16 ++++++++-------- rust/Cargo.toml | 2 +- rust/adapters/backplane-nats/Cargo.toml | 2 +- rust/adapters/backplane-redis/Cargo.toml | 2 +- rust/adapters/dynamodb/Cargo.toml | 4 ++-- rust/adapters/in-memory/Cargo.toml | 2 +- rust/adapters/postgres/Cargo.toml | 4 ++-- rust/ingestion/Cargo.toml | 2 +- rust/smooth-operator-server/Cargo.toml | 14 +++++++------- rust/smooth-operator/Cargo.toml | 2 +- typescript/CHANGELOG.md | 12 ++++++++++++ typescript/package.json | 2 +- 21 files changed, 52 insertions(+), 44 deletions(-) delete mode 100644 .changeset/otel-org-scope-and-turn-cost.md diff --git a/.changeset/otel-org-scope-and-turn-cost.md b/.changeset/otel-org-scope-and-turn-cost.md deleted file mode 100644 index ca61e4aa..00000000 --- a/.changeset/otel-org-scope-and-turn-cost.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@smooai/smooth-operator': patch ---- - -Fix multi-tenant org scoping in `handle_send_message`, and make LLM turn spans carry cost and tool spans self-identifying. - -**Org scoping (#470).** `handle_send_message` bound `org_id` twice: once correctly from the conversation (used to resolve the per-org gateway key) and again ~120 lines later as `SEED_ORG_ID`, shadowing it. Everything downstream of the second binding — the org persona override and the host tool provider's scope — saw `reference-org` on a multi-tenant host, for every tenant. Because the gateway key came from the *first* binding, per-org billing and per-org LLM keys stayed correct, which is why the split went unnoticed. Now reuses the derived org and falls back to the seed org only when it is empty, so the single-org reference/local flavor is unchanged. - -**Turn cost (#471).** The gateway's authoritative per-response cost was already parsed by `smooai-smooth-operator-core` and carried to `TurnUsage.cost_usd`, but nothing recorded it on the span, so `gen_ai.usage.cost_usd` was never emitted and consumers showed "cost not measured". The turn span now records it. A non-positive or non-finite value is dropped rather than written as `0` — a gateway `0` means the model is *unpriced*, not free, and recording it as a real cost would silently under-bill. - -**Self-identifying tool spans (#471).** Tool spans carried neither `gen_ai.system` nor `gen_ai.operation.name`, and OTLP consumers that gate on `gen_ai.system` therefore discarded every tool span ever emitted. They now carry `gen_ai.system`, `gen_ai.operation.name`, `gen_ai.conversation.id` and `smooai.org_id`, so a tool span is both ingestable and joinable to its conversation. Fixed at both emission sites — `runner::run_streaming_turn` and `KnowledgeChatRuntime::run_turn` — which had the identical gap. diff --git a/dotnet/server/aspnetcore/SmooAI.SmoothOperator.Server.AspNetCore.csproj b/dotnet/server/aspnetcore/SmooAI.SmoothOperator.Server.AspNetCore.csproj index 21436a28..7fa8cd3d 100644 --- a/dotnet/server/aspnetcore/SmooAI.SmoothOperator.Server.AspNetCore.csproj +++ b/dotnet/server/aspnetcore/SmooAI.SmoothOperator.Server.AspNetCore.csproj @@ -15,7 +15,7 @@ attribute. (Keep the element-form version out of comments: the sync regex replaces the first element-form match in the file.) --> SmooAI.SmoothOperator.Server.AspNetCore - 1.52.2 + 1.52.3 SmooAI ai;agent;llm;chat;smooth-operator;server;aspnetcore;websocket;smooai MIT diff --git a/dotnet/server/postgres/src/SmooAI.SmoothOperator.Server.Postgres.csproj b/dotnet/server/postgres/src/SmooAI.SmoothOperator.Server.Postgres.csproj index c8cc61c4..4152734a 100644 --- a/dotnet/server/postgres/src/SmooAI.SmoothOperator.Server.Postgres.csproj +++ b/dotnet/server/postgres/src/SmooAI.SmoothOperator.Server.Postgres.csproj @@ -15,7 +15,7 @@ attribute. (Keep the element-form version out of comments: the sync regex replaces the first element-form match in the file.) --> SmooAI.SmoothOperator.Server.Postgres - 1.52.2 + 1.52.3 SmooAI ai;agent;llm;chat;smooth-operator;server;postgres;pgvector;smooai MIT diff --git a/dotnet/server/src/SmooAI.SmoothOperator.Server.csproj b/dotnet/server/src/SmooAI.SmoothOperator.Server.csproj index fd18fa6b..c83b000d 100644 --- a/dotnet/server/src/SmooAI.SmoothOperator.Server.csproj +++ b/dotnet/server/src/SmooAI.SmoothOperator.Server.csproj @@ -14,7 +14,7 @@ scripts/sync-versions.mjs (do NOT confuse with the SmooAI.SmoothOperator.Core PackageReference version below, which tracks the separately-published engine). --> SmooAI.SmoothOperator.Server - 1.52.2 + 1.52.3 SmooAI ai;agent;llm;chat;smooth-operator;server;websocket;smooai MIT diff --git a/examples/web-chat/CHANGELOG.md b/examples/web-chat/CHANGELOG.md index 400e03d6..82898c73 100644 --- a/examples/web-chat/CHANGELOG.md +++ b/examples/web-chat/CHANGELOG.md @@ -1,5 +1,12 @@ # @smooai/smooth-operator-web-chat-example +## 0.0.91 + +### Patch Changes + +- Updated dependencies [aa9af9e] + - @smooai/smooth-operator@1.52.3 + ## 0.0.90 ### Patch Changes diff --git a/examples/web-chat/package.json b/examples/web-chat/package.json index a476cc9a..593e7406 100644 --- a/examples/web-chat/package.json +++ b/examples/web-chat/package.json @@ -1,6 +1,6 @@ { "name": "@smooai/smooth-operator-web-chat-example", - "version": "0.0.90", + "version": "0.0.91", "private": true, "description": "A smooth-web-like Vite + React chat client that drives a running smooth-operator server over its WebSocket protocol — token streaming, inline tool-call/result blocks, a conversation sidebar, and oldest-first history, all on top of the published @smooai/smooth-operator SDK.", "type": "module", diff --git a/go/version.go b/go/version.go index 255b38e2..799d1fea 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.52.2" +const Version = "1.52.3" diff --git a/python/pyproject.toml b/python/pyproject.toml index 5c8bc59f..3fd63471 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "smooai-smooth-operator" -version = "1.52.2" +version = "1.52.3" description = "Python protocol types and native async WebSocket client for the smooth-operator protocol. Generated from the language-neutral JSON Schemas in spec/." readme = "README.md" license = { text = "MIT" } diff --git a/python/server/pyproject.toml b/python/server/pyproject.toml index b625f4fb..57945893 100644 --- a/python/server/pyproject.toml +++ b/python/server/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "smooai-smooth-operator-server" -version = "1.52.2" +version = "1.52.3" description = "Native async WebSocket server for the smooth-operator protocol — parity with the Rust and C# reference servers, consuming the in-process smooai-smooth-operator-core engine." readme = "README.md" license = { text = "MIT" } diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 529b4c0e..e344ba21 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -4099,7 +4099,7 @@ checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" [[package]] name = "smooai-smooth-operator" -version = "1.52.2" +version = "1.52.3" dependencies = [ "anyhow", "async-trait", @@ -4133,7 +4133,7 @@ dependencies = [ [[package]] name = "smooai-smooth-operator-adapter-backplane-nats" -version = "1.52.2" +version = "1.52.3" dependencies = [ "anyhow", "async-nats", @@ -4149,7 +4149,7 @@ dependencies = [ [[package]] name = "smooai-smooth-operator-adapter-backplane-redis" -version = "1.52.2" +version = "1.52.3" dependencies = [ "anyhow", "async-trait", @@ -4165,7 +4165,7 @@ dependencies = [ [[package]] name = "smooai-smooth-operator-adapter-dynamodb" -version = "1.52.2" +version = "1.52.3" dependencies = [ "anyhow", "async-trait", @@ -4186,7 +4186,7 @@ dependencies = [ [[package]] name = "smooai-smooth-operator-adapter-memory" -version = "1.52.2" +version = "1.52.3" dependencies = [ "anyhow", "async-trait", @@ -4199,7 +4199,7 @@ dependencies = [ [[package]] name = "smooai-smooth-operator-adapter-postgres" -version = "1.52.2" +version = "1.52.3" dependencies = [ "anyhow", "async-trait", @@ -4290,7 +4290,7 @@ dependencies = [ [[package]] name = "smooai-smooth-operator-ingestion" -version = "1.52.2" +version = "1.52.3" dependencies = [ "anyhow", "async-trait", @@ -4337,7 +4337,7 @@ dependencies = [ [[package]] name = "smooai-smooth-operator-server" -version = "1.52.2" +version = "1.52.3" dependencies = [ "anyhow", "async-trait", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 4ace9c78..e5e6326e 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -40,7 +40,7 @@ smooai-smooth-operator-core = "1.8.0" # Intra-workspace dep on the reference lib carries its version so the adapters / # ingestion / server that depend on it are publishable (path = local dev, # version = the crates.io requirement). -smooth-operator = { package = "smooai-smooth-operator", path = "smooth-operator", version = "1.52.2" } +smooth-operator = { package = "smooai-smooth-operator", path = "smooth-operator", version = "1.52.3" } async-trait = "0.1" anyhow = "1" diff --git a/rust/adapters/backplane-nats/Cargo.toml b/rust/adapters/backplane-nats/Cargo.toml index 2ac5f9fa..aa8e423f 100644 --- a/rust/adapters/backplane-nats/Cargo.toml +++ b/rust/adapters/backplane-nats/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "smooai-smooth-operator-adapter-backplane-nats" -version = "1.52.2" +version = "1.52.3" edition.workspace = true license.workspace = true repository.workspace = true diff --git a/rust/adapters/backplane-redis/Cargo.toml b/rust/adapters/backplane-redis/Cargo.toml index 5c6a466a..ca4b80eb 100644 --- a/rust/adapters/backplane-redis/Cargo.toml +++ b/rust/adapters/backplane-redis/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "smooai-smooth-operator-adapter-backplane-redis" -version = "1.52.2" +version = "1.52.3" edition.workspace = true license.workspace = true repository.workspace = true diff --git a/rust/adapters/dynamodb/Cargo.toml b/rust/adapters/dynamodb/Cargo.toml index 9f2b1ec1..fa6ae231 100644 --- a/rust/adapters/dynamodb/Cargo.toml +++ b/rust/adapters/dynamodb/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "smooai-smooth-operator-adapter-dynamodb" -version = "1.52.2" +version = "1.52.3" edition.workspace = true license.workspace = true repository.workspace = true @@ -19,7 +19,7 @@ s3-vectors = ["dep:aws-sdk-s3vectors", "dep:aws-smithy-types"] smooth-operator = { workspace = true } smooai-smooth-operator-core = { workspace = true } # IndexingStore / IndexingRun for the persistent admin indexing-runs store. -smooai-smooth-operator-ingestion = { path = "../../ingestion", version = "1.52.2" } +smooai-smooth-operator-ingestion = { path = "../../ingestion", version = "1.52.3" } async-trait = { workspace = true } anyhow = { workspace = true } chrono = { workspace = true } diff --git a/rust/adapters/in-memory/Cargo.toml b/rust/adapters/in-memory/Cargo.toml index 040b9e23..addfcd64 100644 --- a/rust/adapters/in-memory/Cargo.toml +++ b/rust/adapters/in-memory/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "smooai-smooth-operator-adapter-memory" -version = "1.52.2" +version = "1.52.3" edition.workspace = true license.workspace = true repository.workspace = true diff --git a/rust/adapters/postgres/Cargo.toml b/rust/adapters/postgres/Cargo.toml index 4119e43c..e1dcbad8 100644 --- a/rust/adapters/postgres/Cargo.toml +++ b/rust/adapters/postgres/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "smooai-smooth-operator-adapter-postgres" -version = "1.52.2" +version = "1.52.3" edition.workspace = true license.workspace = true repository.workspace = true @@ -15,7 +15,7 @@ smooth-operator = { workspace = true } # `postgres` feature pulls in PostgresCheckpointStore (sync r2d2 path). smooai-smooth-operator-core = { workspace = true, features = ["postgres"] } # IndexingStore / IndexingRun for the persistent admin indexing-runs store. -smooai-smooth-operator-ingestion = { path = "../../ingestion", version = "1.52.2" } +smooai-smooth-operator-ingestion = { path = "../../ingestion", version = "1.52.3" } async-trait = { workspace = true } anyhow = { workspace = true } chrono = { workspace = true } diff --git a/rust/ingestion/Cargo.toml b/rust/ingestion/Cargo.toml index c59b0a0c..bc34491e 100644 --- a/rust/ingestion/Cargo.toml +++ b/rust/ingestion/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "smooai-smooth-operator-ingestion" -version = "1.52.2" +version = "1.52.3" edition.workspace = true license.workspace = true repository.workspace = true diff --git a/rust/smooth-operator-server/Cargo.toml b/rust/smooth-operator-server/Cargo.toml index 7dea9b5c..f1580cc0 100644 --- a/rust/smooth-operator-server/Cargo.toml +++ b/rust/smooth-operator-server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "smooai-smooth-operator-server" -version = "1.52.2" +version = "1.52.3" edition.workspace = true license.workspace = true repository.workspace = true @@ -35,22 +35,22 @@ smooth-operator = { workspace = true } smooai-smooth-operator-core = { workspace = true } # In-memory storage + backplane — ALWAYS included. The local-flavor default and # the lean (`--no-default-features`) build run entirely on these. -smooai-smooth-operator-adapter-memory = { path = "../adapters/in-memory", version = "1.52.2" } +smooai-smooth-operator-adapter-memory = { path = "../adapters/in-memory", version = "1.52.3" } # Persistent storage + admin-store backends, selected at runtime to match the # configured storage backend (Postgres / DynamoDB; default in-memory). Optional: # gated behind the `postgres` / `dynamodb` features so a lean local/embed build # can exclude tokio-postgres / the AWS SDK. The `postgres` crate also provides the # gateway-backed embedder/reranker, so the `postgres` feature additionally enables # the semantic-retrieval path in `embedder.rs` / `reranker.rs`. -smooai-smooth-operator-adapter-postgres = { path = "../adapters/postgres", version = "1.52.2", optional = true } -smooai-smooth-operator-adapter-dynamodb = { path = "../adapters/dynamodb", version = "1.52.2", optional = true } +smooai-smooth-operator-adapter-postgres = { path = "../adapters/postgres", version = "1.52.3", optional = true } +smooai-smooth-operator-adapter-dynamodb = { path = "../adapters/dynamodb", version = "1.52.3", optional = true } # Distributed Backplane backends for horizontal scale-out, selected at runtime # via SMOOTH_AGENT_BACKPLANE (default in-memory / single-process). Optional: gated # behind the `redis` / `nats` features so a lean build excludes their drivers. -smooai-smooth-operator-adapter-backplane-redis = { path = "../adapters/backplane-redis", version = "1.52.2", optional = true } -smooai-smooth-operator-adapter-backplane-nats = { path = "../adapters/backplane-nats", version = "1.52.2", optional = true } +smooai-smooth-operator-adapter-backplane-redis = { path = "../adapters/backplane-redis", version = "1.52.3", optional = true } +smooai-smooth-operator-adapter-backplane-nats = { path = "../adapters/backplane-nats", version = "1.52.3", optional = true } # Admin API surfaces indexing-run status via the ingestion crate's IndexingStore. -smooai-smooth-operator-ingestion = { path = "../ingestion", version = "1.52.2" } +smooai-smooth-operator-ingestion = { path = "../ingestion", version = "1.52.3" } async-trait = { workspace = true } anyhow = { workspace = true } diff --git a/rust/smooth-operator/Cargo.toml b/rust/smooth-operator/Cargo.toml index 6421ff30..96306c1e 100644 --- a/rust/smooth-operator/Cargo.toml +++ b/rust/smooth-operator/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "smooai-smooth-operator" -version = "1.52.2" +version = "1.52.3" edition.workspace = true license.workspace = true repository.workspace = true diff --git a/typescript/CHANGELOG.md b/typescript/CHANGELOG.md index d5d9440e..060074a2 100644 --- a/typescript/CHANGELOG.md +++ b/typescript/CHANGELOG.md @@ -1,5 +1,17 @@ # @smooai/smooth-operator +## 1.52.3 + +### Patch Changes + +- aa9af9e: Fix multi-tenant org scoping in `handle_send_message`, and make LLM turn spans carry cost and tool spans self-identifying. + + **Org scoping (#470).** `handle_send_message` bound `org_id` twice: once correctly from the conversation (used to resolve the per-org gateway key) and again ~120 lines later as `SEED_ORG_ID`, shadowing it. Everything downstream of the second binding — the org persona override and the host tool provider's scope — saw `reference-org` on a multi-tenant host, for every tenant. Because the gateway key came from the _first_ binding, per-org billing and per-org LLM keys stayed correct, which is why the split went unnoticed. Now reuses the derived org and falls back to the seed org only when it is empty, so the single-org reference/local flavor is unchanged. + + **Turn cost (#471).** The gateway's authoritative per-response cost was already parsed by `smooai-smooth-operator-core` and carried to `TurnUsage.cost_usd`, but nothing recorded it on the span, so `gen_ai.usage.cost_usd` was never emitted and consumers showed "cost not measured". The turn span now records it. A non-positive or non-finite value is dropped rather than written as `0` — a gateway `0` means the model is _unpriced_, not free, and recording it as a real cost would silently under-bill. + + **Self-identifying tool spans (#471).** Tool spans carried neither `gen_ai.system` nor `gen_ai.operation.name`, and OTLP consumers that gate on `gen_ai.system` therefore discarded every tool span ever emitted. They now carry `gen_ai.system`, `gen_ai.operation.name`, `gen_ai.conversation.id` and `smooai.org_id`, so a tool span is both ingestable and joinable to its conversation. Fixed at both emission sites — `runner::run_streaming_turn` and `KnowledgeChatRuntime::run_turn` — which had the identical gap. + ## 1.52.2 ### Patch Changes diff --git a/typescript/package.json b/typescript/package.json index f23796e5..91fab558 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "@smooai/smooth-operator", - "version": "1.52.2", + "version": "1.52.3", "description": "TypeScript SDK for the smooth-operator WebSocket protocol: the native client (`.`), React bindings (`./react`), and the embeddable web-component chat widget (`./widget`). Generated from the language-neutral JSON Schemas in spec/.", "license": "MIT", "type": "module",