mirror of
https://github.com/turnstonelabs/turnstone.git
synced 2026-08-12 23:12:23 -06:00
docs: enrich CHANGELOG and add Contributors section for 1.4.0
Audit pass against the actual commit messages between v1.3.0 and v1.4.0 turned up several substantive items the initial CHANGELOG under-described or omitted entirely. Fix-forward expansion plus a Contributors section recognizing external contributors. Added detail / coverage: - New "Server compatibility layer for local model servers" entry — the vLLM / llama.cpp profiles + admin UI fields shipped in #352 alongside the capabilities passthrough; previously buried under one bullet. - Per-call plan/task model selection split into three sub-bullets (backend split, runtime configurability without restart via ConfigStore admin tab, per-call override) — three PRs that build on each other deserve to be discoverable independently. - Opus 4.7 entry expanded with 1M ctx / 128K output, the new thinking_display capability field, xhigh effort level, and admin dropdown updates. - Dashboard composer note: tab-bar `+` modal also gained the paperclip + chip strip + first-message field. - Slack adapter: explicit "session recovery via persisted recoverable route keys" — ops-relevant promise for restart behaviour. - pgbouncer swap: helm chart link + ports updates noted. - Provider capabilities entry: defensive shallow-copy + chat_template deep-merge follow-ups. New Fixed entries: - Cross-user attachment-fetch hardening (get_attachment_content scopes by user_id). - Attachment-list DoS guard on /v1/api/send. - Bounded LRU for upload locks. - 3.12 CI deadlock root-cause writeup (asyncio.Lock vs Starlette TestClient loop teardown). New SDK entry: - PlanResolvedEvent type + guard, dispatched cross-client when one client resolves a plan so others dismiss in sync. New Operational subsection: - vendor-js workflow now auto-downloads hls.js for future Renovate bumps so they're merge-ready without manual file fetches. Contributors: - Recognise @daoxley (Slack adapter, #355) and @pizzaandcheese (pgbouncer swap, #353) — the two external contributors with meaningful net-new work in this release — plus the Renovate bot. - Pointer to channel-attachment ingest as the headline 1.4.1 feature for would-be contributors.
This commit is contained in:
+123
-18
@@ -52,11 +52,13 @@ existing 1.3.x database. Both are additive; no data loss. See
|
||||
SDKs auto-generate `ws_id` client-side so cluster-routed callers can
|
||||
bind the body to the owning node before it lands. (#362)
|
||||
- **Slack channel adapter** (Socket Mode) — mirrors the Discord adapter:
|
||||
per-user channel sessions via configurable slash command, DM routing,
|
||||
SSE event consumption, tool approval buttons (with per-user owner
|
||||
enforcement), plan-review approve / request-changes modal,
|
||||
notification reply routing back into the workstream, session recovery
|
||||
after restart. Install with `pip install 'turnstone[slack]'`. (#355)
|
||||
per-user channel sessions via configurable slash command, DM routing
|
||||
without slash command, SSE event consumption, tool approval buttons
|
||||
with per-user owner enforcement, plan-review approve / request-changes
|
||||
modal, notification reply routing back into the workstream, and
|
||||
session recovery after restart via persisted recoverable route keys
|
||||
(the bot re-subscribes to existing Slack-routed workstreams when it
|
||||
comes back). Install with `pip install 'turnstone[slack]'`. (#355)
|
||||
- **Console admin UX support for Slack** — channel-link modal offers
|
||||
Slack alongside Discord; skill notify-on-complete forms expose a
|
||||
per-row channel-type dropdown (and no longer hardcode `discord`);
|
||||
@@ -64,16 +66,59 @@ existing 1.3.x database. Both are additive; no data loss. See
|
||||
theme-aware tokens (`--discord` / `--slack`) so light theme passes
|
||||
WCAG AA. (#365)
|
||||
- **Per-call plan/task model selection** — `plan_model` and `task_model`
|
||||
are now distinct from the conversation model and from each other, with
|
||||
configurable reasoning effort per agent. `ConfigStore` admin tab in
|
||||
the console UI lets operators set defaults; per-call overrides
|
||||
available via the `plan_agent` / `task_agent` tools. (#360, #361)
|
||||
are now distinct from the conversation model and from each other,
|
||||
with configurable reasoning effort per agent. Three layers:
|
||||
- **Backend split** (`#54dd557`) — `ModelRegistry` gains `plan_model`,
|
||||
`task_model`, `plan_effort`, `task_effort`; per-kind overrides win
|
||||
over the legacy `agent_model`, which still works as the single-knob
|
||||
fallback. `resolve_agent_alias(kind)` and `resolve_agent_effort(kind)`
|
||||
centralise resolution. Loader validates effort against
|
||||
`{none, minimal, low, medium, high, xhigh, max}` with warn+drop on
|
||||
typos.
|
||||
- **Runtime configurability** (`#360`) — `ConfigStore` admin tab in
|
||||
the console UI lets operators switch alias and reasoning effort per
|
||||
agent **without restarting**. `INHERIT_EMPTY_LABEL_KEYS` shows
|
||||
`(inherit)` for empty effort selections — distinct from the literal
|
||||
`none` choice which actually disables reasoning. Routing overrides
|
||||
apply on `/v1/api/_internal/config-reload` (admin saves), and
|
||||
`model-reload` short-circuits when nothing changed so no in-flight
|
||||
clients churn.
|
||||
- **Per-call override** (`#361`) — the calling LLM can pass
|
||||
`model="<alias>"` to `plan_agent` or `task_agent` to override the
|
||||
operator-configured per-kind model for that one invocation. Tool
|
||||
descriptions list the live registered aliases (refreshed when the
|
||||
operator hits "sync to nodes"), so the LLM always sees current
|
||||
options. Bad aliases return a corrective error dict listing the
|
||||
available choices. No whitelist — cost control is intentionally
|
||||
ceded to the model. Plan-retry path reuses the alias so coaching
|
||||
reflects real model behaviour. (#360, #361)
|
||||
- **Provider capability passthrough** — resolved per-model capabilities
|
||||
(vision support, reasoning support, native web search, etc.) flow
|
||||
through to provider clients so feature gating no longer relies on
|
||||
string matching. Server companion published in the same change. (#352)
|
||||
- **Claude Opus 4.7 support** — provider capabilities, tokenizer
|
||||
awareness, and adaptive thinking semantics. (#357 — also in 1.3.1)
|
||||
(vision, reasoning, native web search, thinking_mode, token_param,
|
||||
etc.) flow through to provider clients via a new `capabilities`
|
||||
parameter on `create_streaming` / `create_completion`, so feature
|
||||
gating no longer relies on string matching and admin-UI / config.toml
|
||||
overrides actually reach the provider. Defensive shallow-copy in
|
||||
`_finalize_extra_body` so callers reusing the same dict across models
|
||||
are safe; deep-merge of `chat_template_kwargs` so operators can
|
||||
extend instead of silently overwriting. (#352)
|
||||
- **Server compatibility layer for local model servers** — vLLM and
|
||||
llama.cpp profiles suggest the right thinking mode and per-server
|
||||
workarounds (`skip_special_tokens` for vLLM, `reasoning_format` for
|
||||
llama.cpp) during model detection. Admin UI gains structured fields
|
||||
for server type, thinking mode, and extra body params, hidden for
|
||||
non-local providers (openai/anthropic/google). New `thinking_param`
|
||||
text field surfaces the alias name (default `enable_thinking`;
|
||||
Granite/DeepSeek use `thinking`). Verified end-to-end against real
|
||||
vLLM (Gemma 4 31B) and llama.cpp (Gemma 4 E4B) servers. (#352)
|
||||
- **Claude Opus 4.7 support** — `claude-opus-4-7` capability entry
|
||||
(1M ctx, 128K output, adaptive thinking, `supports_temperature=False`,
|
||||
`thinking_display=summarized`). New `ModelCapabilities.thinking_display`
|
||||
field — Opus 4.7 omits thinking by default but always sends summarized
|
||||
blocks back through the provider boundary. Adds `xhigh` effort level
|
||||
to the global mapping and to Opus 4.7's `effort_levels`; admin-console
|
||||
skill-template dropdowns gained `xhigh` and `max` options. Reasoning
|
||||
effort label capitalization aligned across all console dropdowns.
|
||||
(#357 — also in 1.3.1)
|
||||
- **Dashboard composer refactor** — unified single-flow create from the
|
||||
per-node dashboard. Multi-line textarea + collapsible Options panel
|
||||
(model / judge / skill) + paperclip + drag-drop / paste-image + chip
|
||||
@@ -84,7 +129,9 @@ existing 1.3.x database. Both are additive; no data loss. See
|
||||
separate modal. Options panel state persists in `localStorage`;
|
||||
active non-default selections render as an inline summary chip beside
|
||||
the Options button; drag-over shows an explicit "Drop to attach"
|
||||
overlay. (#362, #366)
|
||||
overlay. The tab-bar `+` new-workstream modal also gained a paperclip
|
||||
+ chip strip + first-message field so the same flow is reachable from
|
||||
both entry points. (#362, #366)
|
||||
- **Workstream attachments — orphan reservation sweep** — periodic
|
||||
background sweep clears `reserved_for_msg_id` on rows whose
|
||||
`reserved_at` exceeds a 1-hour threshold, self-healing reservations
|
||||
@@ -116,9 +163,11 @@ existing 1.3.x database. Both are additive; no data loss. See
|
||||
show a `…and N more (preview truncated)` suffix. (#365)
|
||||
- **PostgreSQL deployment image** swapped from `bitnami/pgbouncer` to
|
||||
`edoburu/pgbouncer` to track upstream releases and reduce image size.
|
||||
No config changes required for typical deployments; review your helm
|
||||
values if you depend on `bitnami`-specific environment variable
|
||||
conventions. (#353)
|
||||
Environment variables remapped to the edoburu naming, ports updated
|
||||
to match documented expectations, and the Kubernetes Helm Chart link
|
||||
in the deployment docs now points at the same container. Review
|
||||
your helm values if you depend on `bitnami`-specific environment
|
||||
variable conventions. (#353)
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -149,6 +198,28 @@ existing 1.3.x database. Both are additive; no data loss. See
|
||||
`.scope-slack` first shipped with raw hex that failed WCAG AA on
|
||||
light theme (1.8:1 / 2.4:1). Theme-aware `--discord` / `--slack`
|
||||
tokens with proper light variants now pass. (#365)
|
||||
- **Cross-user attachment fetch hardening** — `get_attachment_content`
|
||||
now scopes the row by `user_id` in addition to `ws_id`, so an
|
||||
unowned workstream can't be a vector for cross-user blob fetches via
|
||||
attachment-id guessing. (#356)
|
||||
- **Attachment-list DoS guard** — `/v1/api/send` rejects
|
||||
`attachment_ids` lists longer than the per-(ws, user) pending cap
|
||||
with a 400, preventing hostile clients from blowing up the storage
|
||||
`IN (...)` clause. (#356)
|
||||
- **Bounded LRU for upload locks** — the per-(ws, user) attachment
|
||||
upload-lock map now evicts the oldest unlocked entries past a soft
|
||||
cap, so the in-process map can't grow unbounded on long-running
|
||||
nodes. (#356)
|
||||
- **3.12 CI deadlock on attachment uploads** — the upload-lock was
|
||||
initially an `asyncio.Lock`, but Starlette's `TestClient` runs each
|
||||
request on a fresh anyio task / event loop, so the cached lock's
|
||||
`_waiters` bound to the first loop and a later request would block
|
||||
on a Future from a closed loop (silent deadlock). Switched to
|
||||
`threading.Lock` — loop-agnostic, and the critical section is one
|
||||
COUNT + one INSERT. Same root cause is reproducible against any
|
||||
Starlette TestClient harness on Python ≥ 3.10; 3.12 surfaces it
|
||||
more often. Production users on a single event loop weren't
|
||||
affected, but the test environment was. (#356)
|
||||
|
||||
### Security
|
||||
|
||||
@@ -194,6 +265,40 @@ Python + TypeScript clients gained:
|
||||
- Refusal of `attachments + target_node` combination at the SDK
|
||||
boundary (the multipart routing layer doesn't honor `target_node`,
|
||||
so silently picking the wrong node is now an explicit error)
|
||||
- `PlanResolvedEvent` SSE event with type guard, dispatched when one
|
||||
client (e.g. mobile) resolves a plan so other connected clients can
|
||||
dismiss their plan-approval modal in sync. Available in both the
|
||||
Python and TypeScript SDKs. (#87a9af1)
|
||||
|
||||
### Operational
|
||||
|
||||
- **CI vendor-asset auto-download covers `hls.js`** — the
|
||||
`vendor-js.yml` workflow previously only iterated katex/hljs/mermaid,
|
||||
so Renovate bumps for `hls.js` failed the wheel-completeness check
|
||||
and required manual file downloads. Detection loop now includes
|
||||
`hls`, so future Renovate bumps are merge-ready without intervention.
|
||||
(#354)
|
||||
|
||||
### Contributors
|
||||
|
||||
Thanks to the people who made this release happen — especially the
|
||||
external contributors who picked up substantial pieces of work:
|
||||
|
||||
- **[@daoxley](https://github.com/daoxley)** — designed and shipped
|
||||
the Slack channel adapter (Socket Mode bot, per-user sessions,
|
||||
approvals, plan-review, notification routing). Major new feature
|
||||
surface in #355.
|
||||
- **[@pizzaandcheese](https://github.com/pizzaandcheese)** — replaced
|
||||
the deprecated bitnami pgbouncer image with the edoburu image,
|
||||
remapped environment variables, ports, and helm chart references.
|
||||
Operationally important for anyone running our reference Postgres
|
||||
deployment (#353).
|
||||
- Renovate kept dependencies and the JS vendor tree current via
|
||||
several automated bumps.
|
||||
|
||||
If you're interested in contributing, channel-attachment ingest from
|
||||
Discord + Slack is the headline 1.4.1 feature and a solid place to
|
||||
start — see the open issues on GitHub or open one to scope a piece.
|
||||
|
||||
## [1.3.1]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user