Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 0 additions & 47 deletions .changeset/cancel-is-terminal-and-dotnet-turn-timeout.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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.) -->
<PackageId>SmooAI.SmoothOperator.Server.AspNetCore</PackageId>
<Version>1.57.1</Version>
<Version>1.57.2</Version>
<Authors>SmooAI</Authors>
<PackageTags>ai;agent;llm;chat;smooth-operator;server;aspnetcore;websocket;smooai</PackageTags>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.) -->
<PackageId>SmooAI.SmoothOperator.Server.Postgres</PackageId>
<Version>1.57.1</Version>
<Version>1.57.2</Version>
<Authors>SmooAI</Authors>
<PackageTags>ai;agent;llm;chat;smooth-operator;server;postgres;pgvector;smooai</PackageTags>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
Expand Down
2 changes: 1 addition & 1 deletion dotnet/server/src/SmooAI.SmoothOperator.Server.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -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). -->
<PackageId>SmooAI.SmoothOperator.Server</PackageId>
<Version>1.57.1</Version>
<Version>1.57.2</Version>
<Authors>SmooAI</Authors>
<PackageTags>ai;agent;llm;chat;smooth-operator;server;websocket;smooai</PackageTags>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
Expand Down
7 changes: 7 additions & 0 deletions examples/web-chat/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# @smooai/smooth-operator-web-chat-example

## 0.0.112

### Patch Changes

- Updated dependencies [72b35b6]
- @smooai/smooth-operator@1.57.2

## 0.0.111

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion examples/web-chat/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@smooai/smooth-operator-web-chat-example",
"version": "0.0.111",
"version": "0.0.112",
"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",
Expand Down
2 changes: 1 addition & 1 deletion go/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ package e2e
// language artifacts. The real Go "publish" is a git tag (go/v<Version>); 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.57.1"
const Version = "1.57.2"
2 changes: 1 addition & 1 deletion python/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "smooai-smooth-operator"
version = "1.57.1"
version = "1.57.2"
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" }
Expand Down
2 changes: 1 addition & 1 deletion python/server/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "smooai-smooth-operator-server"
version = "1.57.1"
version = "1.57.2"
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" }
Expand Down
16 changes: 8 additions & 8 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ smooai-smooth-operator-core = "1.10.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.57.1" }
smooth-operator = { package = "smooai-smooth-operator", path = "smooth-operator", version = "1.57.2" }

async-trait = "0.1"
anyhow = "1"
Expand Down
2 changes: 1 addition & 1 deletion rust/adapters/backplane-nats/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "smooai-smooth-operator-adapter-backplane-nats"
version = "1.57.1"
version = "1.57.2"
edition.workspace = true
license.workspace = true
repository.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion rust/adapters/backplane-redis/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "smooai-smooth-operator-adapter-backplane-redis"
version = "1.57.1"
version = "1.57.2"
edition.workspace = true
license.workspace = true
repository.workspace = true
Expand Down
4 changes: 2 additions & 2 deletions rust/adapters/dynamodb/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "smooai-smooth-operator-adapter-dynamodb"
version = "1.57.1"
version = "1.57.2"
edition.workspace = true
license.workspace = true
repository.workspace = true
Expand All @@ -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.57.1" }
smooai-smooth-operator-ingestion = { path = "../../ingestion", version = "1.57.2" }
async-trait = { workspace = true }
anyhow = { workspace = true }
chrono = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion rust/adapters/in-memory/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "smooai-smooth-operator-adapter-memory"
version = "1.57.1"
version = "1.57.2"
edition.workspace = true
license.workspace = true
repository.workspace = true
Expand Down
4 changes: 2 additions & 2 deletions rust/adapters/postgres/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "smooai-smooth-operator-adapter-postgres"
version = "1.57.1"
version = "1.57.2"
edition.workspace = true
license.workspace = true
repository.workspace = true
Expand All @@ -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.57.1" }
smooai-smooth-operator-ingestion = { path = "../../ingestion", version = "1.57.2" }
async-trait = { workspace = true }
anyhow = { workspace = true }
chrono = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion rust/ingestion/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "smooai-smooth-operator-ingestion"
version = "1.57.1"
version = "1.57.2"
edition.workspace = true
license.workspace = true
repository.workspace = true
Expand Down
14 changes: 7 additions & 7 deletions rust/smooth-operator-server/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "smooai-smooth-operator-server"
version = "1.57.1"
version = "1.57.2"
edition.workspace = true
license.workspace = true
repository.workspace = true
Expand Down Expand Up @@ -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.57.1" }
smooai-smooth-operator-adapter-memory = { path = "../adapters/in-memory", version = "1.57.2" }
# 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.57.1", optional = true }
smooai-smooth-operator-adapter-dynamodb = { path = "../adapters/dynamodb", version = "1.57.1", optional = true }
smooai-smooth-operator-adapter-postgres = { path = "../adapters/postgres", version = "1.57.2", optional = true }
smooai-smooth-operator-adapter-dynamodb = { path = "../adapters/dynamodb", version = "1.57.2", 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.57.1", optional = true }
smooai-smooth-operator-adapter-backplane-nats = { path = "../adapters/backplane-nats", version = "1.57.1", optional = true }
smooai-smooth-operator-adapter-backplane-redis = { path = "../adapters/backplane-redis", version = "1.57.2", optional = true }
smooai-smooth-operator-adapter-backplane-nats = { path = "../adapters/backplane-nats", version = "1.57.2", optional = true }
# Admin API surfaces indexing-run status via the ingestion crate's IndexingStore.
smooai-smooth-operator-ingestion = { path = "../ingestion", version = "1.57.1" }
smooai-smooth-operator-ingestion = { path = "../ingestion", version = "1.57.2" }

async-trait = { workspace = true }
anyhow = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion rust/smooth-operator/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "smooai-smooth-operator"
version = "1.57.1"
version = "1.57.2"
edition.workspace = true
license.workspace = true
repository.workspace = true
Expand Down
48 changes: 48 additions & 0 deletions typescript/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,53 @@
# @smooai/smooth-operator

## 1.57.2

### Patch Changes

- 72b35b6: fix: make `cancelled` terminal on the servers, and bound a .NET turn on the client

Two terminal states that were not terminal.

**`cancelled` was advisory, not terminal (th-8628bf).** Cancellation is cooperative
everywhere: `JoinHandle::abort()`, `context` cancellation and `CancellationToken` all
take effect at the next yield point, not immediately. A turn that is executing rather
than suspended keeps running β€” and an `await` on an already-completed future does not
yield either β€” so work kept happening after the client had been sent the terminal
`cancelled` (499).

- **Python** was the worst: the Rich Interaction raise tool and the SEP extension host's
`ui/confirm` park both caught `asyncio.CancelledError` alongside their own timeout and
returned normally. asyncio only treats a task as cancelled if the `CancelledError`
propagates out of it, so that _un-cancelled_ the turn: it resumed, ran the next model
call, persisted an assistant reply and emitted an `eventual_response` for a requestId
the client had been told ended at 499. Both sites now re-raise; their own
`TimeoutError` β€” a genuinely different thing β€” still degrades to "no answer".
- **Rust** now drops post-cancel frames at the connection writer, the one point every
frame passes through. Per-emit-site checks could not do this: frames leave a turn from
the runner's stream loop, from inside a raise tool, from the write-confirmation gate
and from the turn tail. The spawned turn also carries a cancelled flag, raised before
the abort and before `cancelled` goes out, that its tail re-reads immediately before
each side effect β€” including the OTP dispatch, which is not a frame and so cannot be
covered by the writer gate.
- **Go** gates the turn's sink once, for the same reason: a raise tool calls `sink()`
straight from inside `Execute`, on the engine's goroutine, with no context check of its
own. `offerOtp` also moved from the connection's context to the turn's, and re-checks
immediately before dispatching β€” a host `OtpService` is under no obligation to honor
the context, and this is a real code to a real person. The outbound persist re-checks
too, because a store may ignore the context (the in-memory one takes it as `_`).

**A .NET turn had no timeout (th-10ff63).** `SmoothAgentClientOptions` exposed only
`RequestTimeout`, with no counterpart to TypeScript's `turnTimeout`, Go's
`DefaultTurnTimeout` or Python's `turn_timeout`. A turn the server accepted but never
terminated hung for the life of the process β€” no error, no diagnostic, and a leaked entry
in the client's turn table. `TurnTimeout` now defaults to the same 120s and faults the
turn with a `TurnTimeoutException`; `Timeout.InfiniteTimeSpan` disables it.

The same file's `_ = _transport.SendAsync(...)` sat inside a try/catch that could never
run: `SendAsync` is async, so a send failure faults the returned task instead of throwing
at the call site, and the discarded task was never observed. The turn was therefore never
aborted and leaked with no error. It is now awaited on a helper that aborts the turn.

## 1.57.1

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion typescript/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@smooai/smooth-operator",
"version": "1.57.1",
"version": "1.57.2",
"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",
Expand Down
Loading