> ## Documentation Index
> Fetch the complete documentation index at: https://honcho.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Changelog

Welcome to the Honcho changelog! This section documents all notable changes to the Honcho API and SDKs.

<Accordion title="How to Read This Changelog">
  Each release is documented with:

  * **Added**: New features and capabilities
  * **Changed**: Modifications to existing functionality
  * **Deprecated**: Features that will be removed in future versions
  * **Removed**: Features that have been removed
  * **Fixed**: Bug fixes and corrections
  * **Security**: Security-related improvements

  ## Version Format

  Honcho follows [Semantic Versioning](https://semver.org/):

  * **MAJOR** version for incompatible API changes
  * **MINOR** version for backwards-compatible functionality additions
  * **PATCH** version for backwards-compatible bug fixes
</Accordion>

### Honcho API and SDK Changelogs

<Tabs>
  <Tab title="Honcho API">
    <Update label="v3.0.9 (Current)">
      ### Changed

      * Connection acquisition is now a single attempt with no server-side retry, on a vanilla `AsyncSession`. A new `DB_CONNECT_TIMEOUT_SECONDS` (default 2s) bounds the attempt so a saturated or unreachable pooler fails fast instead of holding a client connection open to re-knock. A saturated DB now surfaces to the caller — the API returns an error and the deriver backs off and retries on a later poll — which lets the pooler drain rather than amplifying saturation.

      ### Added

      * Deriver poll jitter so instances that start together don't poll in lockstep: `DERIVER_POLLING_STARTUP_JITTER_SECONDS` (random delay before the first poll, default 30s) and `DERIVER_POLLING_JITTER_RATIO` (±fraction applied to every poll sleep, default 0.5). Both disable at `0.0`; the underlying backoff schedule is unchanged.

      ### Removed

      * Reverted the connection-checkout retry and `HonchoAsyncSession` custom session introduced in 3.0.8. Removed the `DB_CONNECTION_RETRY_ENABLED` / `DB_CONNECTION_RETRY_MAX_DELAY_SECONDS` / `DB_CONNECTION_RETRY_BACKOFF_INITIAL_SECONDS` / `DB_CONNECTION_RETRY_BACKOFF_MAX_SECONDS` settings, the `db_connection_acquisitions{outcome=...}` Prometheus counter, and the `db.pool.acquire` Sentry span. Alerting built on `db_connection_acquisitions` should migrate to `db_pool_connections` / `db_queries_in_flight`.
    </Update>

    <Update label="v3.0.8">
      ### Added

      * Connection-checkout retry with bounded exponential backoff (tenacity) on `get_db`/`tracked_db`: transient transaction-pooler (Supavisor) rejections — SQLAlchemy `TimeoutError` and `OperationalError` — now retry with backoff instead of surfacing as 500s under client-connection saturation. Gated by
        `DB_CONNECTION_RETRY_ENABLED` with configurable delay/backoff knobs; \~10s default budget (#758)
      * `HonchoAsyncSession` — a lazy `AsyncSession` that checks out its pooled connection (with retry) on the first DB-touching call rather than at construction. Request handlers doing non-DB work (embedding, file, LLM) before their first query no longer pin a pooler connection across it. Only the checkout is retried;
        the statement still runs exactly once, so writes are never duplicated (#758)
      * Adaptive deriver queue polling: the poll interval backs off when the queue is idle or erroring (base → max, doubling each cycle) and snaps back to base the moment work is claimed, cutting steady-state query load against the DB. Gated by `DERIVER_POLLING_BACKOFF_ENABLED` with configurable max/multiplier (#758)
      * New Prometheus `db_pool_connections` gauge (checked\_out / checked\_in / size / overflow), labeled `api`|`deriver`, registered in both the API lifespan and the deriver metrics server (#758)
      * New Prometheus `db_connection_acquisitions{outcome=ok|retried|exhausted}` counter — the alertable early-warning signal that connection checkouts are retrying through pooler rejection, before requests start failing (#758)
      * New Prometheus `db_queries_in_flight` gauge — statements actually executing on the wire (via SQLAlchemy cursor-execute events). Paired with `checked_out`, the gap reveals connections held but parked (the "idle in transaction during an external call" antipattern). Gated on `METRICS.ENABLED` for zero overhead when
        off (#758)
      * Explicit `SqlalchemyIntegration` in both the API and deriver Sentry inits; connection acquisition wrapped in a `db.pool.acquire` span with live pool stats captured on retry exhaustion (#758)

      ### Changed

      * Default `POOL_TIMEOUT` lowered to 5s, with validation that it stays under the connection-retry budget when a pooled (non-null) `POOL_CLASS` is configured; `config.toml.example` and the v2/v3 configuration docs updated to match (#758)
      * `HonchoAsyncSession` wraps every DB-touching session method (execute / scalar / scalars / flush / merge / refresh / commit / get / get\_one / stream / stream\_scalars / delete) so the lazy-checkout-with-retry guarantee has no holes; the acquired flag resets on `close()`/`reset()` so a reused session re-acquires on
        next use (#758)

      ### Fixed

      * Roll the session back on a retryable checkout failure before retrying — a failed autobegin could otherwise leave it pending-rollback, making the next connection attempt raise instead of cleanly re-checking-out (#758)
      * Guard `DBPoolCollector.collect()` so a pool-read/import hiccup can't raise and abort the entire `/metrics` scrape (Prometheus drops all metrics if any collector raises) (#758)
      * Clamp the pool overflow gauge to ≥ 0 (it could report negative before the pool fills) (#758)
      * Removed a double-sleep in the deriver idle poll so the backoff cap is a true cap rather than 2× (#758)
    </Update>

    <Update label="v3.0.7">
      ### Added

      * New `src/llm/` package as the single owner of provider runtime: clients, backends, history adapters, tool loop, request builder, credentials, and caching policy (#459)
      * New cloudevent `LLMCallCompletedEvent` (`llm.call.completed`) fires once per provider hit with full cost-attribution context: transport/provider\_label, model, token counts with cache breakdown, finish\_reason, outcome, retry/fallback state, duration, tool-call shape, streaming flag, and agent correlation (`run_id` + iteration) (#637)
      * `RepresentationCompletedEvent` now carries `total_input_tokens` for full-trace cost attribution; per-emitter `honcho_version` injection; deterministic per-`run_id` high-volume sampler via `TelemetrySettings.HIGH_VOLUME_SAMPLE_RATE` (#637)
      * Deriver custom instructions: per-workspace/peer guidance threaded into the deriver prompt with a `MAX_CUSTOM_INSTRUCTIONS_TOKENS` budget (default 2000); deriver `MAX_INPUT_TOKENS` raised 23000 → 25000 (#609)
      * Configurable embedding dimensions: `EMBEDDING_MODEL_CONFIG__DIMENSIONS_MODE` (`auto`/`always`/`never`) controls whether OpenAI `dimensions=` is forwarded (#678)
      * New `honcho-cli` package — Python CLI for inspecting and managing peers, sessions, and configuration against a Honcho deployment (#424)
      * `HONCHO_API_URL` env var support in the MCP Worker for self-hosted deployments (#575)
      * API ID `max_length` increased from 100 to 512 across `WorkspaceCreate`, `PeerCreate`, and `SessionCreate` to align with the DB schema (#684)
      * `AttemptPlan` dataclass pins per-retry provider selection across stream-final retries so streaming doesn't bounce back to primary after the tool loop has settled on fallback (#459)
      * Gemini JSON-schema sanitizer for `function_declarations` — strips keywords Gemini's validator rejects while preserving semantics for other backends (#459)

      ### Changed

      * All LLM orchestration moved out of `src/utils/clients.py` into `src/llm/` with modules split by responsibility (#459)
      * Default `ModelConfig` factories (deriver, summary, dreamer specialists, dialectic levels) normalized with no extra parameters set by default; operators add transport/thinking overrides explicitly (#459)
      * OpenAI reasoning-model routing widened to cover `gpt-5.x` and `o1/o3/o4` — these models receive `max_completion_tokens` instead of `max_tokens` (#459)
      * Peer card prompts reframed as stable identity markers; induction specialist now opts out of peer card writes so only deduction touches the card (#686)
      * Vector store queries no longer fetch embedding vectors — only document metadata is returned, reducing payload size and DB load (pgvector, lancedb, turbopuffer) (#682)
      * Langfuse trace metadata now includes `namespace`, `model`, and `provider` so traces can be filtered by deployment slice (#565)
      * Deriver: model-aware tokenizer (replaces the previously hardcoded encoding) and explicit guard on empty message content (#647)
      * Dialectic level defaults now merge correctly with per-level overrides (#656)
      * Default dialectic tool choice switched to `auto` (#630)
      * Vector sync given a substantial retry budget to tolerate transient embedding provider outages (#604)
      * `AgentToolConclusionsDeletedEvent` payload now carries `levels` (#612)
      * Turbopuffer: `InternalServerError` caught and surfaced as a warning rather than a hard failure; vector store sync errors downgraded to warnings (#561)

      ### Fixed

      * `reverse` query parameter is now honored on the v3 workspace list, peer list, workspace-scoped session list, and peer-scoped session list. Honcho SDKs at 2.1.0+ were already sending `reverse=true` for these routes but the server silently ignored it. Ties on `created_at` now fall back to the internal nanoid `id` for stable ordering across pages (#685)
      * LLM client factories now receive `base_url` from `LLMSettings` for default providers — operators pointing at OpenAI-compatible proxies via `LLM__OPENAI_BASE_URL` were previously ignored on the default path (#643, fixes #641)
      * Internal N+1 query in dialectic agent tool execution — collapsed per-iteration DB lookups into a single fetch (#652)
      * Dreamer threshold and time-guard semantics: count filter now includes only `documents.level == 'explicit'` (was inflating threshold via dreamer-created levels and creating a feedback loop); `last_dream_at` write relocated from enqueue to process so duplicate enqueues or failed runs no longer reset the 8-hour time guard (#573)
      * Deriver: blank observations are filtered out before embedding (previously triggered noisy embedding calls and persisted empty rows) (#615)
      * Surprisal module: filter format corrected from `{"level": levels}` to `{"level": {"in": levels}}` — the prior call silently returned 0 results and made the entire Surprisal phase of the Dream cycle a no-op (#581, fixes #559)
      * Removed hardcoded `stop_sequences` override from Deriver `ModelConfig` (was clobbering operator-configured stop sequences) (#587)
      * Embedding client: `embed()` now wraps single-string input in an array, restoring compatibility with OpenAI-compatible third-party providers that reject scalar input (#586)
      * Docker Compose: deriver service startup gated on the API service healthcheck — prevents races where the deriver starts before the API has run migrations (#689)
      * Docker image: `HEALTHCHECK` directive removed from the shared base image; service-level health checks now belong in each service's own configuration (#530)
      * Removed strict parameter validation for thinking params on Anthropic and OpenAI transports — was rejecting valid per-transport configs (#686)
      * Stream-final retries pin to the `AttemptPlan` that succeeded rather than re-running provider selection through the outer `current_attempt` ContextVar (#459)
      * Gemini `cached_content` reuse keys now include `system_instruction` and `tool_config` so cache hits don't cross configurations (#459)
      * CrewAI example updated for the latest CrewAI protocol (#631)

      ### Removed

      * `src/utils/clients.py` deleted; its responsibilities are split across `src/llm/registry.py`, `src/llm/credentials.py`, and the backend-specific modules (#459)
      * `HEALTHCHECK` directive from the shared Docker image (#530)
    </Update>

    <Update label="v3.0.6">
      ### Changed

      * Tightened transaction scopes across search, agent tools, queue manager, and webhook delivery to minimize DB connection hold time during external operations (#525)
      * Search operations refactored to two-phase pattern — external work (embeddings, LLM calls) completes before opening a transaction (#525)
      * Agent tool executor performs external operations before acquiring DB sessions (#525)
      * Queue manager transaction scope reduced to only the critical section (#525)
      * Webhook delivery no longer holds a DB session parameter (#525)

      ### Fixed

      * Session leakage in non-session-scoped dialectic chat calls (#526)

      ### Added

      * Health check endpoint (`/health`) for container orchestration and load balancer probes (#510)
    </Update>

    <Update label="v3.0.5">
      ### Fixed

      * explicit rollback on all transactions to force connection closed
    </Update>

    <Update label="v3.0.4">
      ### Added

      * JSONB metadata validation enforces 100 key limit and max depth of 5 (#419)

      ### Changed

      * Schemas refactored from single `schemas.py` into `schemas/api.py`, `schemas/configuration.py`, and `schemas/internal.py` with backwards-compatible re-exports (#419)

      ### Fixed

      * Missing `deleted_at` filter on `RepresentationManager._query_documents_recent()` and `._query_documents_most_derived()` allowed soft-deleted documents to leak into the deriver's working representation (#456)
      * `CleanupStaleItemsCompletedEvent` emitted spuriously when no queue item was actually deleted (#454)
      * Empty JSON file uploads caused unhandled errors; now returns normalized error responses (#434)
      * Memory leak: `_observation_locks` switched to `WeakValueDictionary` to prevent unbounded growth (#419)
      * SQL injection in `dependencies.py`: parameterized `set_config` calls to prevent injection via request context (#419)
      * NUL byte crashes: string inputs (message content, queries, peer cards) now stripped at schema level (#419)
      * Filter recursion depth capped at 5 to prevent stack overflow (#419)
      * Dedup-skipped observations now correctly reflected in created counts (#477)
      * External vector store support for message search — routes queries through configured external vector store with oversampling and
        deduplication to handle chunked embeddings (#479)
      * Dialectic agent no longer holds a DB connection during LLM calls — embeddings are pre-computed before tool execution, DB sessions isolated in `extract_preferences`, `query_documents` no longer accepts a DB session parameter (#477)
    </Update>

    <Update label="v3.0.3">
      ### Added

      * Consolidated session context into a single DB session with 40/60 token budget allocation between summary and messages
      * Observation validation via `ObservationInput` Pydantic schema with partial-success support and batch embedding with per-observation fallback
      * Peer card hard cap of 40 facts with case-insensitive deduplication and whitespace normalization
      * Safe integer coercion (`_safe_int`) for all LLM tool inputs to handle non-integer values like `"Infinity"`
      * Embedding pre-computation and reuse across multiple search calls in dialectic and representation flows
      * Peer existence validation in dialectic chat endpoints — raises ResourceNotFoundException instead of silently failing
      * Logging filter to suppress noisy `GET /metrics` access logs
      * Oolong long-context aggregation benchmark (synth and real variants, 1K–4M token context windows)
      * MolecularBench fact quality evaluation (ambiguity, decontextuality, minimality scoring)
      * CoverageBench information recall evaluation (gold fact extraction, coverage matching, QA verification)
      * LoCoMo summary-as-context baseline evaluation
      * Webhook delivery tests, dependency lifecycle tests, queue cleanup tests, summarizer fallback tests
      * Parallel test execution via pytest-xdist with worker-specific databases
      * `test_reasoning_levels.py` script for LOCOM dataset testing across reasoning levels

      ### Changed

      * Workspace deletion is now async — returns 202 Accepted, validates no active sessions (409 Conflict), cascade-deletes in background
      * Redis caching layer now stores plain-dict instead of ORM objects, with v2-prefixed keys, storage, resilient `safe_cache_set`/`safe_cache_delete` helpers, and deferred post-commit cache invalidation
      * All `get_or_create_*` CRUD operations now use savepoints (`db.begin_nested()`) instead of commit/rollback for race condition prevention
      * Reconciler vector sync uses direct ORM mutation instead of batch parameterized UPDATE statements
      * Summarizer enforces hard word limit in prompt and creates fallback text for empty summaries with `summary_tokens = 0`
      * Blocked Gemini responses (SAFETY, RECITATION, PROHIBITED\_CONTENT, BLOCKLIST) now raise `LLMError` to trigger retry/backup-provider logic
      * Gemini client explicitly sets `max_output_tokens` from `max_tokens` parameter
      * All deriver and metrics collector logging replaced with structured `logging.getLogger(__name__)` calls
      * Dreamer specialist prompts updated to enforce durable-facts-only peer cards with max 40 entries and deduplication
      * `GetOrCreateResult` changed from `NamedTuple` to `dataclass` with `async post_commit()` method
      * FastAPI upgraded from 0.111.0 to 0.131.0; added pyarrow dependency
      * Queue status filtering to only show user-facing tasks (representation, summary, dream); excludes internal infrastructure tasks

      ### Fixed

      * JWT timestamp bug — `JWTParams.t` was evaluated once at class definition time instead of per-instance
      * Session cache invalidation on deletion was missing
      * `get_peer_card()` now properly propagates `ResourceNotFoundException` instead of swallowing it
      * `set_peer_card()` ensures peer exists via `get_or_create_peers()` before updating
      * Backup provider failover with proper tool input type safety
      * Removed `setup_admin_jwt()` from server startup
      * Sentry coroutine detection switched from `asyncio.iscoroutinefunction` to `inspect.iscoroutinefunction`

      ### Removed

      * `explicit.py` and `obex.py` benchmarks replaced by coverage.py and molecular.py
      * Claude Code review automation workflow (`.github/workflows/claude.yml`)
      * Coverage reporting from default pytest configuration
    </Update>

    <Update label="v3.0.2">
      ### Added

      * Documentation for reasoning\_level and Claude Code plugin

      ### Changed

      * Gave dreaming sub-agents better prompting around peer card creation, tweaked overall prompts

      ### Fixed

      * Added message-search fallback for memory search tool, necessary in fresh sessions
      * Made FLUSH\_ENABLED a config value
      * Removed N+1 query in search\_messages
    </Update>

    <Update label="v3.0.1">
      ### Fixed

      * Token counting in Explicit Agent Loop
      * Backwards compatibility of queue items
    </Update>

    <Update label="v3.0.0">
      ### Added

      * Agentic Dreamer for intelligent memory consolidation using LLM agents
      * Agentic Dialectic for query answering using LLM agents with tool use
      * Reasoning levels configuration for dialectic (`minimal`, `low`, `medium`, `high`, `max`)
      * Prometheus token tracking for deriver and dialectic operations
      * n8n integration
      * Cloud Events for auditable telemetry
      * External Vector Store support for turbopuffer and lancedb with reconciliation flow

      ### Changed

      * API route renaming for consistency
      * Dreamer and dialectic now respect peer card configuration settings
      * Observations renamed to Conclusions across API and SDKs
      * Deriver to buffer representation tasks to normalize workloads
      * Local Representation tasks to create singular QueueItems
      * getContext endpoint to use `search_query` rather than force `last_user_message`

      ### Fixed

      * Dream scheduling bugs
      * Summary creation when start\_message\_id > end\_message\_id
      * Cashews upgrade to prevent NoScriptError
      * Memory leak in `accumulate_metric` call

      ### Removed

      * Peer card configuration from message configuration; peer cards no longer created/updated in deriver process
    </Update>

    <Update label="v2.5.1">
      ### Fixed

      * Backwards compatibility for `message_ids` field in documents to handle legacy tuple format
    </Update>

    <Update label="v2.5.0">
      ### Added

      * Message level configurations
      * CRUD operations for observations
      * Comprehensive test cases for harness
      * Peer level get\_context
      * Set Peer Card Method
      * Manual dreaming trigger endpoint

      ### Changed

      * Configurations to support more flags for fine-grained control of the deriver, peer cards, summaries, etc.
      * Working Representations to support more fine-grained parameters

      ### Fixed

      * File uploads to match `MessageCreate` structure
      * Cache invalidation strategy
    </Update>

    <Update label="v2.4.3">
      ### Added

      * Redis caching to improve DB IO
      * Backup LLM provider to avoid failures when a provider is down

      ### Changed

      * QueueItems to use standardized columns
      * Improved Deduplication logic for Representation Tasks
      * More finegrained metrics for representation, summary, and peer card tasks
      * DB constraint to follow standard naming conventions
    </Update>

    <Update label="v2.4.2">
      ### Fixed

      * Langfuse tracing to have readable waterfalls
      * Alembic Migrations to match models.py
      * message\_in\_seq correctly included in webhook payload

      ### Changed

      * Alembic to always use a session pooler
      * Statement timeout during alembic operations to 5 min
    </Update>

    <Update label="v2.4.1">
      ### Added

      * Alembic migration validation test suite

      ### Fixed

      * Alembic migrations to batch changes
      * Batch message creation sequence number

      ### Changed

      * Logging infrastructure to remove noisy messages
      * Sentry integration is centralized
    </Update>

    <Update label="v2.4.0">
      ### Added

      * Unified `Representation` class
      * vllm client support
      * Periodic queue cleanup logic
      * WIP Dreaming Feature
      * LongMemEval to Test Bench
      * Prometheus Client for better Metrics
      * Performance metrics instrumentation
      * Error reporting to deriver
      * Workspace Delete Method
      * Multi-db option in test harness

      ### Changed

      * Working Representations are Queried on the fly rather than cached in metadata
      * EmbeddingStore to RepresentationFactory
      * Summary Response Model to use public\_id of message for cutoff
      * Semantic across codebase to reference resources based on `observer` and `observed`
      * Prompts for Deriver & Dialectic to reference peer\_id and add examples
      * `Get Context` route returns peer card and representation in addition to messages and summaries
      * Refactoring logger.info calls to logger.debug where applicable

      ### Fixed

      * Gemini client to use async methods
    </Update>

    <Update label="v2.3.3">
      ### Changed

      * Deriver Rollup Queue processes interleaved messages for more context

      ### Fixed

      * Dialectic Streaming to follow SSE conventions
      * Sentry tracing in the deriver
    </Update>

    <Update label="v2.3.2">
      ### Added

      * Get peer cards endpoint (`GET /v2/peers/{peer_id}/card`) for retrieving targeted peer context information

      ### Changed

      * Replaced Mirascope dependency with small client implementation for better control
      * Optimized deriver performance by using joins on messages table instead of storing token count in queue payload
      * Database scope optimization for various operations
      * Batch representation task processing for \~10x speed improvement in practice

      ### Fixed

      * Separated clean and claim work units in queue manager to prevent race conditions
      * Skip locked ActiveQueueSession rows on delete operations
      * Langfuse SDK integration updates for compatibility
      * Added configurable maximum message size to prevent token overflow in deriver
      * Various minor bugfixes
    </Update>

    <Update label="v2.3.1">
      ### Fixed

      * Added max message count to deriver in order to not overflow token limits
    </Update>

    <Update label="v2.3.0">
      ### Added

      * `getSummaries` endpoint to get all available summaries for a session directly
      * Peer Card feature to improve context for deriver and dialectic

      ### Changed

      * Session Peer limit to be based on observers instead, renamed config value to
        `SESSION_OBSERVERS_LIMIT`
      * `Messages` can take a custom timestamp for the `created_at` field, defaulting
        to the current time
      * `get_context` endpoint returns detailed `Summary` object rather than just
        summary content
      * Working representations use a FIFO queue structure to maintain facts rather
        than a full rewrite
      * Optimized deriver enqueue by prefetching message sequence numbers (eliminates N+1 queries)

      ### Fixed

      * Deriver uses `get_context` internally to prevent context window limit errors
      * Embedding store will truncate context when querying documents to prevent embedding
        token limit errors
      * Queue manager to schedule work based on available works rather than total
        number of workers
      * Queue manager to use atomic db transactions rather than long lived transaction
        for the worker lifecycle
      * Timestamp formats unified to ISO 8601 across the codebase
      * Internal get\_context method's cutoff value is exclusive now
    </Update>

    <Update label="v2.2.0">
      ### Added

      * Arbitrary filters now available on all search endpoints
      * Search combines full-text and semantic using reciprocal rank fusion
      * Webhook support (currently only supports queue\_empty and test events, more to come)
      * Small test harness and custom test format for evaluating Honcho output quality
      * Added MCP server and documentation for it

      ### Changed

      * Search has 10 results by default, max 100 results
      * Queue structure generalized to handle more event types
      * Summarizer now exhaustive by default and tuned for performance

      ### Fixed

      * Resolve race condition for peers that leave a session while sending messages
      * Added explicit rollback to solve integrity error in queue
      * Re-introduced Sentry tracing to deriver
      * Better integrity logic in get\_or\_create API methods
    </Update>

    <Update label="v2.1.2">
      ### Fixed

      * Summarizer module to ignore empty summaries and pass appropriate one to get\_context
      * Structured Outputs calls with OpenAI provider to pass strict=True to Pydantic Schema
    </Update>

    <Update label="v2.1.1">
      ### Added

      * Test harness for custom Honcho evaluations
      * Better support for session and peer aware dialectic queries
      * Langfuse settings
      * Added recent history to dialectic prompt, dynamic based on new context window size setting

      ### Fixed

      * Summary queue logic
      * Formatting of logs
      * Filtering by session
      * Peer targeting in queries

      ### Changed

      * Made query expansion in dialectic off by default
      * Overhauled logging
      * Refactor summarization for performance and code clarity
      * Refactor queue payloads for clarity
    </Update>

    <Update label="v2.1.0">
      ### Added

      * File uploads
      * Brand new "ROTE" deriver system
      * Updated dialectic system
      * Local working representations
      * Better logging for deriver/dialectic
      * Deriver Queue Status no longer has redundant data

      ### Fixed

      * Document insertion
      * Session-scoped and peer-targeted dialectic queries work now
      * Minor bugs

      ### Removed

      * Peer-level messages

      ### Changed

      * Dialectic chat endpoint takes a single query
      * Rearranged configuration values (LLM, Deriver, Dialectic, History->Summary)
    </Update>

    <Update label="v2.0.5">
      ### Fixed

      * Groq API client to use the Async library
    </Update>

    <Update label="v2.0.4">
      ### Fixed

      * Migration/provision scripts did not have correct database connection arguments, causing timeouts
    </Update>

    <Update label="v2.0.3">
      ### Fixed

      * Bug that causes runtime error when Sentry flags are enabled
    </Update>

    <Update label="v2.0.2">
      ### Fixed

      * Database initialization was misconfigured and led to provision\_db script failing: switch to consistent working configuration with transaction pooler
    </Update>

    <Update label="v2.0.1">
      ### Added

      * Ergonomic SDKs for Python and TypeScript (uses Stainless underneath)
      * Deriver Queue Status endpoint
      * Complex arbitrary filters on workspace/session/peer/message
      * Message embedding table for full semantic search

      ### Changed

      * Overhauled documentation
      * BasedPyright typing for entire project
      * Resource filtering expanded to include logical operators

      ### Fixed

      * Various bugs
      * Use new config arrangement everywhere
      * Remove hardcoded responses
    </Update>

    <Update label="v2.0.0">
      ### Added

      * Ability to get a peer's working representation
      * Metadata to all data primitives (Workspaces, Peers, Sessions, Messages)
      * Internal metadata to store Honcho's state no longer exposed in API
      * Batch message operations and enhanced message querying with token and message count limits
      * Search and summary functionalities scoped by workspace, peer, and session
      * Session context retrieval with summaries and token allocatio
      * HNSW Index for Documents Table
      * Centralized Configuration via Environment Variables or config.toml file

      ### Changed

      * New architecture centered around the concept of a "peer" replaces the former
        "app"/"user"/"session" paradigm
      * Workspaces replace "apps" as top-level namespace
      * Peers replace "users"
      * Sessions no longer nested beneath peers and no longer limited to a single
        user-assistant model. A session exists independently of any one peer and
        peers can be added to and removed from sessions.
      * Dialectic API is now part of the Peer, not the Session
      * Dialectic API now allows queries to be scoped to a session or "targeted"
        to a fellow peer
      * Database schema migrated to adopt workspace/peer/session naming and structure
      * Authentication and JWT scopes updated to workspace/peer/session hierarchy
      * Queue processing now works on 'work units' instead of sessions
      * Message token counting updated with tiktoken integration and fallback heuristic
      * Queue and message processing updated to handle sender/target and task types for multi-peer scenarios

      ### Fixed

      * Improved error handling and validation for batch message operations and metadata
      * Database Sessions to be more atomic to reduce idle in transaction time

      ### Removed

      * Metamessages removed in favor of metadata
      * Collections and Documents no longer exposed in the API, solely internal
      * Obsolete tests for apps, users, collections, documents, and metamessages

      ***
    </Update>

    <Update label="v1.1.0">
      ### Added

      * Normalize resources to remove joins and increase query performance
      * Query tracing for debugging

      ### Changed

      * `/list` endpoints to not require a request body
      * `metamessage_type` to `label` with backwards compatibility
      * Database Provisioning to rely on alembic
      * Database Session Manager to explicitly rollback transactions before closing
        the connection

      ### Fixed

      * Alembic Migrations to include initial database migrations
      * Sentry Middleware to not report Honcho Exceptions
    </Update>

    <Update label="v1.0.0">
      ### Added

      * JWT based API authentication
      * Configurable logging
      * Consolidated LLM Inference via `ModelClient` class
      * Dynamic logging configurable via environment variables

      ### Changed

      * Deriver & Dialectic API to use Hybrid Memory Architecture
      * Metamessages are not strictly tied to a message
      * Database provisioning is a separate script instead of happening on startup
      * Consolidated `session/chat` and `session/chat/stream` endpoints
    </Update>

    ## Previous Releases

    For a complete history of all releases, see our [GitHub Releases](https://github.com/plastic-labs/honcho/tags) page.
  </Tab>

  <Tab title="Python SDK">
    [Python SDK](https://pypi.org/project/honcho-ai/)

    <Update label="v2.1.2 (Current)">
      ### Added

      * `page`, `size`, and `reverse` pagination parameters on `Honcho.workspaces()` and `HonchoAio.workspaces()`, closing the gap from 2.1.0 which added these to other list methods but not to `workspaces()`. Honoring `reverse` on the workspace/peer/session list routes also requires a Honcho server with the matching API fix; older servers silently ignore the parameter.
      * `peers` parameter on `Honcho.session()` and `HonchoAio.session()` — attach peers to a session at creation time instead of needing a follow-up `session.add_peers()` call. Accepts the same shapes as `Session.add_peers` (peer ID string, `Peer` object, list of either, or tuples with `SessionPeerConfig`).

      ### Changed

      * `WorkspaceCreateParams`, `PeerCreateParams`, and `SessionCreateParams` now accept IDs up to 512 characters (was 100), matching the server-side schema change in Honcho v3.0.7.
    </Update>

    <Update label="v2.1.1">
      ### Fixed

      * Broadened HTTP retry logic to cover `httpx.NetworkError` and `httpx.RemoteProtocolError` in addition to `httpx.TimeoutException` and `httpx.ConnectError`, improving resilience against transient network failures
    </Update>

    <Update label="v2.1.0">
      ### Added

      * `created_at` property on `Peer` and `Session` objects
      * `is_active` property on `Session` objects
      * `get_message(message_id)` method on `Session` (sync and async) to fetch a single message by ID
      * `page`, `size`, and `reverse` pagination parameters on all list methods

      ### Changed

      * **Breaking**: `peer()` and `session()` now always make a get-or-create API call — no more lazy initialization
      * Response configuration models now tolerate unknown fields from newer servers for forward compatibility

      ### Fixed

      * Sync and async `Session.get_metadata()`, `get_configuration()`, and `refresh()` now refresh cached `created_at` and `is_active` values along with metadata and configuration
      * `honcho.__version__` now derives from package metadata, with a source-checkout fallback, so it stays aligned with released package versions
    </Update>

    <Update label="v2.0.2">
      ### Changed

      * All input models now reject unknown fields via strict Pydantic validation (`extra="forbid"`). Previously, misspelled or extraneous fields were silently ignored. Now a `ValidationError` is raised with the unrecognized field name.
    </Update>

    <Update label="v2.0.1">
      ### Added

      * `set_peer_card` method

      ### Changed

      * `card` is now `get_card` with `card` kept for backwards compatibility and marked as deprecated
    </Update>

    <Update label="v2.0.0">
      ### Added

      * `ConclusionScope` object for CRUD operations on conclusions (renamed from observations)
      * Representation configuration support

      ### Changed

      * Observations renamed to Conclusions across the SDK
      * Major SDK refactoring and cleanup
      * Simplified method signatures throughout
      * Representation endpoints now return `string` instead of old Representation object

      ### Removed

      * Standalone types module (now uses honcho-core types)
      * Representation object
    </Update>

    <Update label="v1.6.0">
      ### Added

      * metadata and configuration fields to Workspace, Peer, Session, and Message objects
      * Session Clone methods
      * Peer level get\_context method
      * `ObservationScope` object to perform CRUD operations on observations
      * Representation object for WorkingRepresentations

      ### Changed

      * methods that take IDs, can all optionally take an object of the same type
    </Update>

    <Update label="v1.5.0">
      ### Added

      * Delete workspace method

      ### Changed

      * message\_id of `Summary` model is a string nanoid
      * Get Context can return Peer Card & Peer Representation
    </Update>

    <Update label="v1.4.1">
      ### Added

      * Get Peer Card method
      * Update Message metadata method
      * Session level deriver status methods
      * Delete session message

      ### Fixed

      * Dialectic Stream returns Iterators
      * Type warnings

      ### Changed

      * Pagination class to match core implementation
    </Update>

    <Update label="v1.4.0">
      ### Added

      * getSummaries API returning structured summaries
      * Webhook support

      ### Changed

      * Messages can take an optional `created_at` value, defaulting to the current
        time (UTC ISO 8601)
    </Update>

    <Update label="v1.2.2">
      ### Added

      * Filter parameter to various endpoints
    </Update>

    <Update label="v1.2.1">
      ### Fixed

      * Honcho util import paths
    </Update>

    <Update label="v1.2.0">
      ### Added

      * Get/poll deriver queue status endpoints added to workspace
      * Added endpoint to upload files as messages

      ### Removed

      * Removed peer messages in accordance with Honcho 2.1.0

      ### Changed

      * Updated chat endpoint to use singular `query` in accordance with Honcho 2.1.0
    </Update>

    <Update label="v1.1.0">
      ### Fixed

      * Properly handle AsyncClient
    </Update>
  </Tab>

  <Tab title="TypeScript SDK">
    [TypeScript SDK](https://www.npmjs.com/package/@honcho-ai/sdk)

    <Update label="v2.1.2 (Current)">
      ### Added

      * `peers` option on `Honcho.session()` — attach peers to a session at creation time instead of needing a follow-up `session.addPeers()` call. Accepts the same `PeerAddition` shape as `session.addPeers()` (peer ID strings, `Peer` objects, arrays of either, or a record with per-peer `observe_me`/`observe_others` config).

      ### Changed

      * ID validation in `validation.ts` now accepts workspace, peer, and session IDs up to 512 characters (was 100), matching the server-side schema change in Honcho v3.0.7.

      ### Fixed

      * `Honcho.workspaces()` now actually forwards the `reverse` option to the server. The 2.1.0 changelog listed `workspaces()` among the list methods that gained `reverse`, but `client.ts` was missing the field on the params type and request builder, so the option was silently dropped. Honoring `reverse` on the workspace/peer/session list routes also requires a Honcho server with the matching API fix; older servers silently ignore the parameter.
    </Update>

    <Update label="v2.1.1">
      ### Fixed

      * Broadened fetch error retry logic to catch all `TypeError` network failures (connection resets, DNS errors, etc.) instead of only those with `'fetch'` in the message, improving resilience across runtimes (Node, Bun, browsers)
    </Update>

    <Update label="v2.1.0">
      ### Added

      * `createdAt` property on `Peer` and `Session` wrapper objects
      * `isActive` property on `Session` wrapper objects
      * `getMessage(messageId)` method on `Session` to fetch a single message by ID
      * `Peer.representation()`, `Session.representation()`, and `Session.context()` now accept `Message` objects for `searchQuery`
      * `page`, `size`, and `reverse` pagination controls on all list methods

      ### Changed

      * **Breaking**: `searchQuery` removed from top-level `context()` options — use `representationOptions.searchQuery` instead:
        ```typescript theme={null}
        // Before (v2.0.x)
        await session.context({ searchQuery: "..." });
        // After (v2.1.0)
        await session.context({ representationOptions: { searchQuery: "..." } });
        ```
      * List methods (`peers()`, `sessions()`, `messages()`, `workspaces()`) support both the new options object and the legacy raw-filter form
      * Representation search options now accept strings and content-like objects, including `Message` instances, while rejecting whitespace-only or invalid runtime inputs
      * **Breaking**: `peer()` and `session()` now always make a get-or-create API call — no more lazy initialization. If you relied on constructing SDK objects without triggering a network request, note that every `peer()` and `session()` call now hits the API:
        ```typescript theme={null}
        // Before (v2.0.x) — no API call
        const session = honcho.session("my-session");
        // After (v2.1.0) — makes a get-or-create API call
        const session = await honcho.session("my-session");
        ```
      * Response configuration models now tolerate unknown fields from newer servers for forward compatibility
      * Moved `@types/node` from `dependencies` to `devDependencies`

      ### Fixed

      * `uploadFile()` now rejects unsupported top-level binary/object inputs and only validates inputs the serializer can actually upload
      * `uploadFile()` now serializes message configuration using API field names, matching `addMessages()`
      * Session fetch methods now refresh cached `createdAt` and `isActive` values alongside metadata and configuration
    </Update>

    <Update label="v2.0.2">
      ### Changed

      * Client constructor now rejects unknown options via `.strict()` Zod validation. Previously, misspelled options (e.g., `baseUrl` instead of `baseURL`) were silently ignored, causing the SDK to fall back to defaults. Now a `ZodError` is thrown with the unrecognized key name.
      * All input schemas now use `.strict()` validation to reject unknown fields.
      * `FileUploadSchema.configuration` now uses `MessageConfigurationSchema` instead of open record type.

      ### Fixed

      * README example used `baseUrl` instead of `baseURL`.
    </Update>

    <Update label="v2.0.1">
      ### Added

      * `setPeerCard` method

      ### Changed

      * `card` is now `getCard` with `card` kept for backwards compatibility and marked as deprecated
    </Update>

    <Update label="v2.0.0">
      ### Added

      * `ConclusionScope` object for CRUD operations on conclusions (renamed from observations)
      * Representation configuration support

      ### Changed

      * Observations renamed to Conclusions across the SDK
      * Major SDK refactoring and cleanup
      * Simplified method signatures throughout
      * Representation endpoints now return `string` instead of old Representation object

      ### Fixed

      * Pagination `this` binding issue

      ### Removed

      * Representation object
      * Stainless "core" SDK -- this SDK is now standalone
    </Update>

    <Update label="v1.6.0">
      ### Added

      * metadata and configuration fields to Workspace, Peer, Session, and Message objects
      * Session Clone methods
      * Peer level get\_context method
      * `ObservationScope` object to perform CRUD operations on observations
      * Representation object for WorkingRepresentations

      ### Changed

      * methods that take IDs, can all optionally take an object of the same type
    </Update>

    <Update label="v1.5.0">
      ### Added

      * Delete workspace method

      ### Changed

      * message\_id of `Summary` model is a string nanoid
      * Get Context can return Peer Card & Peer Representation
    </Update>

    <Update label="v1.4.1">
      ### Added

      * Get Peer Card method
      * Update Message metadata method
      * Session level deriver status methods
      * Delete session message

      ### Fixed

      * Dialectic Stream returns Iterators
      * Type warnings

      ### Changed

      * Pagination class to match core implementation
    </Update>

    <Update label="v1.4.0">
      ### Added

      * getSummaries API returning structured summaries
      * Webhook support

      ### Changed

      * Messages can take an optional `created_at` value, defaulting to the current
        time (UTC ISO 8601)
    </Update>

    <Update label="v1.2.1">
      ### Added

      * linting via Biome
      * Adding filter parameter to various endpoints

      ### Fixed

      * Order of parameters in `getSessions` endpoint
    </Update>

    <Update label="v1.2.0">
      ### Added

      * Get/poll deriver queue status endpoints added to workspace
      * Added endpoint to upload files as messages

      ### Removed

      * Removed peer messages in accordance with Honcho 2.1.0

      ### Changed

      * Updated chat endpoint to use singular `query` in accordance with Honcho 2.1.0
    </Update>

    <Update label="v1.1.0">
      ### Fixed

      * Create default workspace on Honcho client instantiation
      * Simplified Honcho client import path
    </Update>
  </Tab>
</Tabs>

## Getting Help

If you encounter issues using the Honcho API or its SDKs:

1. Open an issue on [GitHub](https://github.com/plastic-labs/honcho/issues)
2. Join our [Discord community](http://discord.gg/honcho) for support
