From 1e0f539fe5db493efddd414615307b1f6a8cfff2 Mon Sep 17 00:00:00 2001 From: Rajat Ahuja Date: Fri, 3 Apr 2026 12:20:53 -0400 Subject: [PATCH] feat: retry on more httpx exceptions (#467) * feat: retry on more httpx exceptions * fix: Add retry parity to typescript and update docs * chore: (skills) update skills to match latest state of the sdk * chore: (docs) update stale sdk code * chore: (docs) clean up inconsistencies in docs * chore: Rebuild Package --------- Co-authored-by: Vineeth Voruganti <13438633+VVoruganti@users.noreply.github.com> --- .claude/skills/honcho-integration/SKILL.md | 6 +- .../bot-frameworks/nanobot/session.py | 6 +- .../migrate-honcho-py/DETAILED-CHANGES.md | 129 +++++++++++++++ .../migrate-honcho-py/MIGRATION-CHECKLIST.md | 35 +++- .claude/skills/migrate-honcho-py/SKILL.md | 92 ++++++++++- .../migrate-honcho-ts/DETAILED-CHANGES.md | 149 ++++++++++++++++++ .../migrate-honcho-ts/MIGRATION-CHECKLIST.md | 40 ++++- .claude/skills/migrate-honcho-ts/SKILL.md | 110 ++++++++++++- CONTRIBUTING.md | 4 +- README.md | 2 +- docs/changelog/introduction.mdx | 12 +- docs/v1/contributing/guidelines.mdx | 2 +- docs/v1/guides/honcho-mcp.mdx | 2 +- docs/v2/contributing/guidelines.mdx | 4 +- docs/v2/contributing/self-hosting.mdx | 4 +- .../documentation/introduction/overview.mdx | 2 +- .../reference/guided-tutorial.mdx | 2 +- docs/v2/documentation/reference/platform.mdx | 2 +- docs/v2/integrations/mcp.mdx | 2 +- docs/v3/contributing/guidelines.mdx | 4 +- docs/v3/contributing/self-hosting.mdx | 4 +- .../core-concepts/design-patterns.mdx | 2 +- .../documentation/core-concepts/reasoning.mdx | 2 +- .../advanced/representation-scopes.mdx | 3 +- docs/v3/documentation/reference/platform.mdx | 2 +- docs/v3/documentation/reference/sdk.mdx | 2 +- sdks/python/CHANGELOG.md | 6 + sdks/python/README.md | 39 ++--- sdks/python/pyproject.toml | 2 +- sdks/python/src/honcho/http/async_client.py | 20 ++- sdks/python/src/honcho/http/client.py | 20 ++- sdks/typescript/CHANGELOG.md | 6 + sdks/typescript/README.md | 10 +- sdks/typescript/package.json | 2 +- sdks/typescript/src/http/client.ts | 20 +-- uv.lock | 2 +- 36 files changed, 649 insertions(+), 102 deletions(-) diff --git a/.claude/skills/honcho-integration/SKILL.md b/.claude/skills/honcho-integration/SKILL.md index 9cdd978f..68f436d1 100644 --- a/.claude/skills/honcho-integration/SKILL.md +++ b/.claude/skills/honcho-integration/SKILL.md @@ -139,8 +139,8 @@ response = peer.chat("What does this user prefer?") # Async usage (FastAPI, Starlette) from honcho import Honcho honcho = Honcho(workspace_id="my-app", api_key=os.environ["HONCHO_API_KEY"]) -peer = honcho.aio.peer("user-123") -response = await peer.chat("What does this user prefer?") +peer = await honcho.aio.peer("user-123") +response = await peer.aio.chat("What does this user prefer?") ``` Match the client to the framework — check whether the codebase uses `async def` handlers or sync `def` handlers and choose accordingly. The rest of this skill shows sync Python examples; swap to `.aio` equivalents for async codebases. @@ -188,7 +188,7 @@ Create peers for **every entity** in your business logic - users AND AI assistan **Python:** ```python -from honcho import PeerConfig +from honcho.api_types import PeerConfig # Human users user = honcho.peer("user-123") diff --git a/.claude/skills/honcho-integration/references/bot-frameworks/nanobot/session.py b/.claude/skills/honcho-integration/references/bot-frameworks/nanobot/session.py index 2e4b3e43..b5ebc081 100644 --- a/.claude/skills/honcho-integration/references/bot-frameworks/nanobot/session.py +++ b/.claude/skills/honcho-integration/references/bot-frameworks/nanobot/session.py @@ -13,7 +13,7 @@ from nanobot.honcho.client import get_honcho_client if TYPE_CHECKING: from honcho import Honcho - from honcho.session import SessionPeerConfig + from honcho.api_types import SessionPeerConfig @dataclass @@ -101,7 +101,7 @@ class HonchoSessionManager: """ Get or create a Honcho peer. - Peers are lazy -- no API call until first use. + As of v2.1.0, peer() always makes a get-or-create API call. Observation settings are controlled per-session via SessionPeerConfig. Args: @@ -138,7 +138,7 @@ class HonchoSessionManager: session = self.honcho.session(session_id) # Configure peer observation settings - from honcho.session import SessionPeerConfig + from honcho.api_types import SessionPeerConfig user_config = SessionPeerConfig(observe_me=True, observe_others=True) ai_config = SessionPeerConfig(observe_me=False, observe_others=True) diff --git a/.claude/skills/migrate-honcho-py/DETAILED-CHANGES.md b/.claude/skills/migrate-honcho-py/DETAILED-CHANGES.md index 624cdd7a..74e93a4b 100644 --- a/.claude/skills/migrate-honcho-py/DETAILED-CHANGES.md +++ b/.claude/skills/migrate-honcho-py/DETAILED-CHANGES.md @@ -476,3 +476,132 @@ from honcho.api_types import SessionPeerConfig ``` **Note:** `MessageCreateParam` (singular) is now `MessageCreateParams` (plural). + +--- + +## 14. Card Method Deprecation and set_card (v2.0.1) + +### Before (v2.0.0) + +```python +card: list[str] | None = peer.card() +``` + +### After (v2.0.1+) + +```python +# get_card() is the preferred method +card: list[str] | None = peer.get_card() + +# card() still works but emits a deprecation warning +card = peer.card() # Deprecated + +# New: set_card() +updated = peer.set_card(["Fact 1", "Fact 2"]) +updated = peer.set_card(["Fact 1"], target="other-peer") + +# Async variants +card = await peer.aio.get_card() +await peer.aio.set_card(["Fact 1"]) +``` + +--- + +## 15. Strict Input Validation (v2.0.2) + +All Pydantic input models now use `extra="forbid"`, raising `ValidationError` for unknown fields. + +```python +from honcho.api_types import PeerConfig + +# This now raises ValidationError instead of silently ignoring the typo +PeerConfig(observe_mee=True) # ValidationError: extra fields not permitted +``` + +--- + +## 16. peer() and session() Always Make API Calls (v2.1.0) + +### Before (v2.0.x) + +```python +# Without options: lazy object, no API call +peer = client.peer("user-123") +# peer.created_at was None + +# With options: made API call +peer = client.peer("user-123", metadata={"key": "value"}) +``` + +### After (v2.1.0+) + +```python +# Always makes a get-or-create API call +peer = client.peer("user-123") +# peer.created_at is now always populated + +# Async +peer = await client.aio.peer("user-123") +``` + +All Peer/Session objects now have `created_at` populated immediately after construction. + +--- + +## 17. New Properties: created_at, is_active (v2.1.0) + +```python +# Peer +peer = client.peer("user-123") +print(peer.created_at) # datetime | None + +# Session +session = client.session("sess-1") +print(session.created_at) # datetime | None +print(session.is_active) # bool | None + +# These are refreshed by get_metadata(), get_configuration(), and refresh() +peer.refresh() +session.refresh() +``` + +--- + +## 18. get_message() on Session (v2.1.0) + +```python +# Fetch a single message by ID +msg = session.get_message("msg-abc123") +print(msg.content, msg.created_at) + +# Async +msg = await session.aio.get_message("msg-abc123") +``` + +--- + +## 19. Pagination Parameters (v2.1.0) + +All list methods now accept `page`, `size`, and `reverse`: + +```python +# Defaults: page=1, size=50, reverse=False +peers_page = client.peers(page=2, size=25, reverse=True) + +# Returns SyncPage / AsyncPage with: +print(peers_page.total) # Total items +print(peers_page.pages) # Total pages +print(peers_page.has_next_page()) + +# Works on: +# client.peers(), client.sessions() +# peer.sessions() +# session.messages() +# scope.list() +``` + +--- + +## 20. Broader HTTP Retry Logic (v2.1.1) + +The SDK now catches `httpx.NetworkError` and `httpx.RemoteProtocolError` for retry in addition to `httpx.TimeoutException` and `httpx.ConnectError`. This is transparent — no code changes needed. diff --git a/.claude/skills/migrate-honcho-py/MIGRATION-CHECKLIST.md b/.claude/skills/migrate-honcho-py/MIGRATION-CHECKLIST.md index 5a2d01ff..ef3254da 100644 --- a/.claude/skills/migrate-honcho-py/MIGRATION-CHECKLIST.md +++ b/.claude/skills/migrate-honcho-py/MIGRATION-CHECKLIST.md @@ -4,7 +4,7 @@ Use this checklist to track migration progress. Copy into your working notes and ## Dependencies -- [ ] Update `honcho` package to v2.0.0 +- [ ] Update `honcho` package to v2.1.1 - [ ] Remove any `honcho-core` imports ## Async Architecture Changes @@ -113,6 +113,39 @@ Use this checklist to track migration progress. Copy into your working notes and - `UnprocessableEntityError`, `RateLimitError`, `ServerError` - `TimeoutError`, `ConnectionError` +## Card Method Updates (v2.0.1) + +- [ ] Replace `peer.card()` with `peer.get_card()` (card() is deprecated) +- [ ] Use `peer.set_card(list[str])` if setting peer cards + +## Strict Validation (v2.0.2) + +- [ ] Verify no input models pass unknown/misspelled fields (now raises `ValidationError`) +- [ ] Check for typos in `PeerConfig`, `SessionConfiguration`, `WorkspaceConfiguration` fields + +## peer() / session() API Call Change (v2.1.0) + +- [ ] Update code that relied on lazy `peer()` / `session()` — they now always make API calls +- [ ] Add `await` if using async and previously didn't need it for lazy construction + +## New Properties (v2.1.0) + +- [ ] Use `peer.created_at` / `session.created_at` where creation time is needed +- [ ] Use `session.is_active` where session active status is needed + +## New Methods (v2.1.0) + +- [ ] Use `session.get_message(message_id)` to fetch single messages by ID + +## Pagination Parameters (v2.1.0) + +- [ ] Add `page`, `size`, `reverse` parameters to list calls where needed: + - [ ] `client.peers()` + - [ ] `client.sessions()` + - [ ] `peer.sessions()` + - [ ] `session.messages()` + - [ ] `scope.list()` + ## Final Verification - [ ] Run type checker (mypy/pyright) with no errors diff --git a/.claude/skills/migrate-honcho-py/SKILL.md b/.claude/skills/migrate-honcho-py/SKILL.md index de9c87f3..c9f8320e 100644 --- a/.claude/skills/migrate-honcho-py/SKILL.md +++ b/.claude/skills/migrate-honcho-py/SKILL.md @@ -1,13 +1,13 @@ --- name: migrate-honcho -description: Migrates Honcho Python SDK code from v1.6.0 to v2.0.0. Use when upgrading honcho package, fixing breaking changes after upgrade, or when errors mention AsyncHoncho, observations, Representation class, .core property, or get_config methods. +description: Migrates Honcho Python SDK code from v1.6.0 to v2.1.1. Use when upgrading honcho package, fixing breaking changes after upgrade, or when errors mention AsyncHoncho, observations, Representation class, .core property, or get_config methods. --- -# Honcho Python SDK Migration (v1.6.0 → v2.0.0) +# Honcho Python SDK Migration (v1.6.0 → v2.1.1) ## Overview -This skill migrates code from `honcho` Python SDK v1.6.0 to v2.0.0 (required for Honcho 3.0.0+). +This skill migrates code from `honcho` Python SDK v1.6.0 to v2.1.1 (required for Honcho 3.0.0+). **Key breaking changes:** @@ -184,18 +184,92 @@ updated = client.update_message(message=msg, metadata={"key": "value"}, session= updated = session.update_message(message=msg, metadata={"key": "value"}) ``` -### 10. Update card() return type +### 10. Update card() return type and method name ```python # Before card: str = peer.card() # Returns str -# After -card: list[str] | None = peer.card() # Returns list[str] | None +# After (v2.0.0+) +card: list[str] | None = peer.get_card() # Returns list[str] | None if card: print("\n".join(card)) + +# peer.card() still works but is deprecated — use get_card() + +# New in v2.0.1: set_card() +peer.set_card(["Prefers dark mode", "Located in US"]) ``` +### 11. Strict input validation (v2.0.2+) + +All input models now reject unknown fields via `extra="forbid"` Pydantic validation. Previously, misspelled or extraneous fields were silently ignored. + +```python +# Before (v2.0.1 and earlier) — silently ignored +peer = client.peer("user-1", configuration=PeerConfig(observe_mee=True)) # typo silently ignored + +# After (v2.0.2+) — raises ValidationError +peer = client.peer("user-1", configuration=PeerConfig(observe_mee=True)) # ValidationError! +``` + +### 12. peer() and session() always make API calls (v2.1.0+) + +**Breaking**: `peer()` and `session()` now always make a get-or-create API call. Previously, calling without metadata/configuration returned a lazy object with no API call. + +```python +# Before (v2.0.x) — no API call without options +peer = client.peer("user-123") # Lazy, no network request + +# After (v2.1.0+) — always hits the API +peer = client.peer("user-123") # Makes POST to /peers (get-or-create) + +# Async +peer = await client.aio.peer("user-123") # Also always hits API +``` + +### 13. New properties and methods (v2.1.0+) + +```python +# created_at on Peer and Session +peer = client.peer("user-123") +print(peer.created_at) # datetime | None + +session = client.session("sess-1") +print(session.created_at) # datetime | None + +# is_active on Session +print(session.is_active) # bool | None + +# get_message() on Session +msg = session.get_message("msg-id") +# Async: msg = await session.aio.get_message("msg-id") +``` + +### 14. Pagination parameters on list methods (v2.1.0+) + +All list methods now accept `page`, `size`, and `reverse` parameters: + +```python +# Before (v2.0.x) — only filters +peers_page = client.peers(filters={"metadata": {"role": "admin"}}) + +# After (v2.1.0+) — pagination controls +peers_page = client.peers( + filters={"metadata": {"role": "admin"}}, + page=2, + size=25, + reverse=True +) + +# Works on: client.peers(), client.sessions(), peer.sessions(), +# session.messages(), scope.list() +``` + +### 15. Broader HTTP retry logic (v2.1.1+) + +The SDK now retries on `httpx.TimeoutException`, `httpx.NetworkError`, and `httpx.RemoteProtocolError` (previously only `httpx.TimeoutException` and `httpx.ConnectError`). These are mapped to the SDK's `TimeoutError` and `ConnectionError` respectively. No code changes needed — this is transparent. + ## Quick Reference Table | v1.6.0 | v2.0.0 | @@ -222,6 +296,8 @@ if card: | `.get_peer_config()` | `.get_peer_configuration()` | | `.set_peer_config()` | `.set_peer_configuration()` | | `client.update_message()` | `session.update_message()` | +| `peer.card()` | `peer.get_card()` *(card() deprecated)* | +| *(new)* | `peer.set_card(list[str])` | | `chat(stream=True)` | `chat_stream()` | | `include_most_derived=` | `include_most_frequent=` | | `max_observations=` | `max_conclusions=` | @@ -230,6 +306,10 @@ if card: | `PeerContext` | `PeerContextResponse` | | `DeriverStatus` | `QueueStatusResponse` | | `client.core` | *(removed)* | +| *(new v2.1.0)* | `peer.created_at` / `session.created_at` | +| *(new v2.1.0)* | `session.is_active` | +| *(new v2.1.0)* | `session.get_message(id)` | +| *(new v2.1.0)* | `page=`, `size=`, `reverse=` on list methods | ## Detailed Reference diff --git a/.claude/skills/migrate-honcho-ts/DETAILED-CHANGES.md b/.claude/skills/migrate-honcho-ts/DETAILED-CHANGES.md index 76273d34..9133756e 100644 --- a/.claude/skills/migrate-honcho-ts/DETAILED-CHANGES.md +++ b/.claude/skills/migrate-honcho-ts/DETAILED-CHANGES.md @@ -432,3 +432,152 @@ interface SummaryData { tokenCount: number } ``` + +--- + +## Post-v2.0.0 Changes + +--- + +## Card Method Deprecation and setCard (v2.0.1) + +### Before (v2.0.0) + +```typescript +const card = await peer.card(target) // string[] | null +``` + +### After (v2.0.1+) + +```typescript +// getCard() is the preferred method +const card = await peer.getCard(target) // string[] | null + +// card() still works but is deprecated +const card = await peer.card(target) // Deprecated + +// New: setCard() +const updated = await peer.setCard(['Fact 1', 'Fact 2']) +const updated = await peer.setCard(['Fact 1'], targetPeer) +``` + +--- + +## Strict Input Validation (v2.0.2) + +Client constructor and all input schemas now use `.strict()` Zod validation. + +```typescript +// Before (v2.0.1) — silently ignored +const honcho = new Honcho({ baseUrl: 'http://...' }) // typo fell back to default + +// After (v2.0.2+) — ZodError thrown +const honcho = new Honcho({ baseUrl: 'http://...' }) // ZodError: Unrecognized key "baseUrl" +``` + +--- + +## peer() and session() Always Make API Calls (v2.1.0) + +### Before (v2.0.x) + +```typescript +// Without options: lazy object, no API call +const peer = honcho.peer('user-123') + +// With options: made API call +const peer = await honcho.peer('user-123', { metadata: { key: 'value' } }) +``` + +### After (v2.1.0+) + +```typescript +// Always makes a get-or-create API call +const peer = await honcho.peer('user-123') +// peer.createdAt is now always populated +``` + +--- + +## New Properties: createdAt, isActive (v2.1.0) + +```typescript +// Peer +const peer = await honcho.peer('user-123') +console.log(peer.createdAt) // string | undefined + +// Session +const session = await honcho.session('sess-1') +console.log(session.createdAt) // string | undefined +console.log(session.isActive) // boolean | undefined + +// Refreshed by getMetadata(), getConfiguration(), and refresh() +await session.refresh() +``` + +--- + +## getMessage() on Session (v2.1.0) + +```typescript +// Fetch a single message by ID +const msg = await session.getMessage('msg-abc123') +console.log(msg.content, msg.createdAt) +``` + +--- + +## Pagination Parameters (v2.1.0) + +All list methods now accept `page`, `size`, and `reverse`: + +```typescript +// Defaults: page=1, size=50, reverse=false +const peersPage = await honcho.peers({ + filters: { metadata: { role: 'admin' } }, + page: 2, + size: 25, + reverse: true +}) + +// Page properties: +console.log(peersPage.total) // Total items +console.log(peersPage.pages) // Total pages +console.log(peersPage.hasNextPage) // boolean + +// Works on: +// honcho.peers(), honcho.sessions(), honcho.workspaces() +// peer.sessions() +// session.messages() +// scope.list() +``` + +--- + +## searchQuery Moved in context() (v2.1.0) + +### Before (v2.0.x) + +```typescript +const ctx = await session.context({ + searchQuery: 'What are my preferences?', + representationOptions: { maxConclusions: 50 } +}) +``` + +### After (v2.1.0+) + +```typescript +const ctx = await session.context({ + representationOptions: { + searchQuery: 'What are my preferences?', + maxConclusions: 50 + } +}) +``` + +--- + +## Broader Fetch Retry Logic (v2.1.1) + +The SDK now retries on all `TypeError` network failures (connection resets, DNS errors, etc.) instead of only those containing `'fetch'` in the error message. This is transparent — no code changes needed. diff --git a/.claude/skills/migrate-honcho-ts/MIGRATION-CHECKLIST.md b/.claude/skills/migrate-honcho-ts/MIGRATION-CHECKLIST.md index 6adcf94b..7abdd277 100644 --- a/.claude/skills/migrate-honcho-ts/MIGRATION-CHECKLIST.md +++ b/.claude/skills/migrate-honcho-ts/MIGRATION-CHECKLIST.md @@ -5,7 +5,7 @@ Use this checklist to track migration progress. Copy into your working notes and ## Dependencies - [ ] Remove `@honcho-ai/core` from dependencies -- [ ] Update `@honcho-ai/sdk` to v2.0.0 +- [ ] Update `@honcho-ai/sdk` to v2.1.1 ## Client-Level Changes @@ -101,6 +101,44 @@ Use this checklist to track migration progress. Copy into your working notes and - [ ] Remove usage of `Representation` class methods (`.explicit`, `.deductive`, `.isEmpty()`, `.diff()`) - [ ] Handle representation as plain string +## Card Method Updates (v2.0.1) + +- [ ] Replace `peer.card()` with `peer.getCard()` (card() is deprecated) +- [ ] Use `peer.setCard(string[])` if setting peer cards + +## Strict Validation (v2.0.2) + +- [ ] Verify no constructor options or input schemas pass unknown/misspelled fields (now throws `ZodError`) +- [ ] Check for `baseUrl` vs `baseURL` typo in Honcho constructor + +## peer() / session() API Call Change (v2.1.0) + +- [ ] Update code that relied on lazy `peer()` / `session()` — they now always make API calls +- [ ] Ensure all `peer()` and `session()` calls are `await`ed + +## New Properties (v2.1.0) + +- [ ] Use `peer.createdAt` / `session.createdAt` where creation time is needed +- [ ] Use `session.isActive` where session active status is needed + +## New Methods (v2.1.0) + +- [ ] Use `session.getMessage(messageId)` to fetch single messages by ID + +## Pagination Parameters (v2.1.0) + +- [ ] Add `page`, `size`, `reverse` parameters to list calls where needed: + - [ ] `honcho.peers()` + - [ ] `honcho.sessions()` + - [ ] `honcho.workspaces()` + - [ ] `peer.sessions()` + - [ ] `session.messages()` + - [ ] `scope.list()` + +## searchQuery Location Change (v2.1.0) + +- [ ] Move `searchQuery` from top-level `context()` options to `representationOptions.searchQuery` + ## Final Verification - [ ] Run TypeScript compiler with no errors diff --git a/.claude/skills/migrate-honcho-ts/SKILL.md b/.claude/skills/migrate-honcho-ts/SKILL.md index 26cbff70..5de5e973 100644 --- a/.claude/skills/migrate-honcho-ts/SKILL.md +++ b/.claude/skills/migrate-honcho-ts/SKILL.md @@ -1,13 +1,13 @@ --- name: migrate-honcho-ts -description: Migrates Honcho TypeScript SDK code from v1.6.0 to v2.0.0. Use when upgrading @honcho-ai/sdk, fixing breaking changes after upgrade, or when errors mention removed APIs like .core, getConfig, observations, or snake_case properties. +description: Migrates Honcho TypeScript SDK code from v1.6.0 to v2.1.1. Use when upgrading @honcho-ai/sdk, fixing breaking changes after upgrade, or when errors mention removed APIs like .core, getConfig, observations, or snake_case properties. --- -# Honcho TypeScript SDK Migration (v1.6.0 → v2.0.0) +# Honcho TypeScript SDK Migration (v1.6.0 → v2.1.1) ## Overview -This skill migrates code from `@honcho-ai/sdk` v1.6.0 to v2.0.0 (required for Honcho 3.0.0+). +This skill migrates code from `@honcho-ai/sdk` v1.6.0 to v2.1.1 (required for Honcho 3.0.0+). **Key breaking changes:** @@ -148,6 +148,101 @@ await honcho.updateMessage(message, metadata, session) await session.updateMessage(message, metadata) ``` +### 11. Update card() to getCard() (v2.0.1+) + +```typescript +// Before +const card = await peer.card(target) + +// After (v2.0.1+) +const card = await peer.getCard(target) // Returns string[] | null + +// peer.card() still works but is deprecated — use getCard() + +// New: setPeerCard / setCard +await peer.setCard(['Prefers dark mode', 'Located in US']) +``` + +### 12. Strict input validation (v2.0.2+) + +Client constructor and all input schemas now reject unknown options via `.strict()` Zod validation. + +```typescript +// Before (v2.0.1 and earlier) — silently ignored +const honcho = new Honcho({ baseUrl: 'http://...' }) // typo: baseUrl vs baseURL — silently fell back to default + +// After (v2.0.2+) — throws ZodError +const honcho = new Honcho({ baseUrl: 'http://...' }) // ZodError! Use baseURL +``` + +### 13. peer() and session() always make API calls (v2.1.0+) + +**Breaking**: `peer()` and `session()` now always make a get-or-create API call. Previously, calling without metadata/configuration returned a lazy object with no API call. + +```typescript +// Before (v2.0.x) — no API call without options +const session = honcho.session('my-session') // Lazy, no network request + +// After (v2.1.0+) — always hits the API +const session = await honcho.session('my-session') // Makes POST to /sessions (get-or-create) +``` + +### 14. New properties and methods (v2.1.0+) + +```typescript +// createdAt on Peer and Session +const peer = await honcho.peer('user-123') +console.log(peer.createdAt) // string | undefined + +const session = await honcho.session('sess-1') +console.log(session.createdAt) // string | undefined + +// isActive on Session +console.log(session.isActive) // boolean | undefined + +// getMessage() on Session +const msg = await session.getMessage('msg-id') +``` + +### 15. Pagination parameters on list methods (v2.1.0+) + +All list methods now accept `page`, `size`, and `reverse` parameters: + +```typescript +// Before (v2.0.x) — only filters +const peers = await honcho.peers({ metadata: { role: 'admin' } }) + +// After (v2.1.0+) — pagination controls via options object +const peers = await honcho.peers({ + filters: { metadata: { role: 'admin' } }, + page: 2, + size: 25, + reverse: true +}) + +// Legacy raw-filter form still works: +const peers = await honcho.peers({ metadata: { role: 'admin' } }) + +// Works on: honcho.peers(), honcho.sessions(), honcho.workspaces(), +// peer.sessions(), session.messages(), scope.list() +``` + +### 16. searchQuery moved in context() (v2.1.0+) + +**Breaking**: `searchQuery` removed from top-level `context()` options. Use `representationOptions.searchQuery` instead. + +```typescript +// Before (v2.0.x) +await session.context({ searchQuery: '...' }) + +// After (v2.1.0+) +await session.context({ representationOptions: { searchQuery: '...' } }) +``` + +### 17. Broader fetch retry logic (v2.1.1+) + +The SDK now retries on all `TypeError` network failures (connection resets, DNS errors, etc.) instead of only those with `'fetch'` in the message. No code changes needed — this is transparent. + ## Quick Reference Table | v1.6.0 | v2.0.0 | @@ -172,15 +267,22 @@ await session.updateMessage(message, metadata) | `session.workingRep()` | `session.representation()` | | `session.peerConfig()` | `session.getPeerConfiguration()` | | `session.setPeerConfig()` | `session.setPeerConfiguration()` | -| `{ timeoutMs: 60000 }` | `{ timeout: 60 }` | +| `{ timeoutMs: 60000 }` | `{ timeout: 60000 }` | | `{ maxObservations: 50 }` | `{ maxConclusions: 50 }` | | `{ includeMostDerived }` | `{ includeMostFrequent }` | | `{ lastUserMessage }` | `{ searchQuery }` | | `{ config: ... }` | `{ configuration: ... }` | | `message.peer_id` | `message.peerId` | | `message.created_at` | `message.createdAt` | +| `peer.card()` | `peer.getCard()` *(card() deprecated)* | +| *(new)* | `peer.setCard(string[])` | | `Observation` | `Conclusion` | | `ObservationScope` | `ConclusionScope` | +| *(new v2.1.0)* | `peer.createdAt` / `session.createdAt` | +| *(new v2.1.0)* | `session.isActive` | +| *(new v2.1.0)* | `session.getMessage(id)` | +| *(new v2.1.0)* | `page`, `size`, `reverse` on list methods | +| `context({ searchQuery })` | `context({ representationOptions: { searchQuery } })` | ## Detailed Reference diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9e405212..2297b658 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,7 +8,7 @@ Before you start contributing, please: 1. **Set up your development environment** - Follow the [Local Development guide](./README.md#local-development) in the README to get Honcho running locally. -2. **Join our community** - Feel free to join us in our [Discord](http://discord.gg/plasticlabs) to discuss your changes, get help, or ask questions. +2. **Join our community** - Feel free to join us in our [Discord](http://discord.gg/honcho) to discuss your changes, get help, or ask questions. 3. **Review existing issues** - Check the [issues tab](https://github.com/plastic-labs/honcho/issues) to see what's already being worked on or to find something to contribute to. @@ -164,7 +164,7 @@ When reporting bugs or requesting features: ## Questions and Support -- **General questions** - Join our [Discord](http://discord.gg/plasticlabs) +- **General questions** - Join our [Discord](http://discord.gg/honcho) - **Bug reports** - Use GitHub issues - **Feature requests** - Use GitHub issues with the feature request template - **Security issues** - Please email us privately rather than opening a public issue diff --git a/README.md b/README.md index c1555554..1a909d0f 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ ![Static Badge](https://img.shields.io/badge/Version-3.0.5-blue) [![PyPI version](https://img.shields.io/pypi/v/honcho-ai.svg)](https://pypi.org/project/honcho-ai/) [![NPM version](https://img.shields.io/npm/v/@honcho-ai/sdk.svg)](https://npmjs.org/package/@honcho-ai/sdk) -[![Discord](https://img.shields.io/discord/1016845111637839922?style=flat&logo=discord&logoColor=23ffffff&label=Plastic%20Labs&labelColor=235865F2)](https://discord.gg/plasticlabs) +[![Discord](https://img.shields.io/discord/1016845111637839922?style=flat&logo=discord&logoColor=23ffffff&label=Plastic%20Labs&labelColor=235865F2)](https://discord.gg/honcho) Honcho is an open source memory library with a managed service for building stateful agents. Use it with any model, framework, or architecture. It enables agents to build diff --git a/docs/changelog/introduction.mdx b/docs/changelog/introduction.mdx index 562778b3..25320350 100644 --- a/docs/changelog/introduction.mdx +++ b/docs/changelog/introduction.mdx @@ -540,6 +540,11 @@ Welcome to the Honcho changelog! This section documents all notable changes to t [Python SDK](https://pypi.org/project/honcho-ai/) + + ### 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 + ### Added @@ -677,6 +682,11 @@ Welcome to the Honcho changelog! This section documents all notable changes to t [TypeScript SDK](https://www.npmjs.com/package/@honcho-ai/sdk) + + ### 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) + ### Added @@ -844,4 +854,4 @@ Welcome to the Honcho changelog! This section documents all notable changes to t 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/plasticlabs) for support +2. Join our [Discord community](http://discord.gg/honcho) for support diff --git a/docs/v1/contributing/guidelines.mdx b/docs/v1/contributing/guidelines.mdx index 70bff6e5..a5b64d19 100644 --- a/docs/v1/contributing/guidelines.mdx +++ b/docs/v1/contributing/guidelines.mdx @@ -11,7 +11,7 @@ indicate a feature or bug fix you are working on. Once you have finished your contribution make a PR , and it will be reviewed by a project manager. Feel free to join us in our -[discord](http://discord.gg/plasticlabs) to discuss your changes or get help. +[discord](http://discord.gg/honcho) to discuss your changes or get help. Your changes will undergo a period of testing and discussion before finally being entered into the `main` branch and being staged for release. For more diff --git a/docs/v1/guides/honcho-mcp.mdx b/docs/v1/guides/honcho-mcp.mdx index 7647b6cb..272dbea7 100644 --- a/docs/v1/guides/honcho-mcp.mdx +++ b/docs/v1/guides/honcho-mcp.mdx @@ -59,4 +59,4 @@ Finally, Claude needs instructions on how to use Honcho. The Desktop app doesn't Be sure to update the \ and \ variables in the instructions.txt file. -Claude should then query for insights before responding and write your messages to storage! If you come up with more creative ways to get Claude to manage its own memory with Honcho, feel free to [let us know](https://discord.gg/plasticlabs) or make a PR on this [repo](https://github.com/plastic-labs/honcho-mcp/tree/main)! +Claude should then query for insights before responding and write your messages to storage! If you come up with more creative ways to get Claude to manage its own memory with Honcho, feel free to [let us know](https://discord.gg/honcho) or make a PR on this [repo](https://github.com/plastic-labs/honcho-mcp/tree/main)! diff --git a/docs/v2/contributing/guidelines.mdx b/docs/v2/contributing/guidelines.mdx index f064e51b..398a8b09 100644 --- a/docs/v2/contributing/guidelines.mdx +++ b/docs/v2/contributing/guidelines.mdx @@ -11,7 +11,7 @@ Before you start contributing, please: 1. **Set up your development environment** - Follow the [Local Development guide](https://github.com/plastic-labs/honcho/blob/main/CONTRIBUTING.md#local-development) in the Honcho repository to get Honcho running locally. -2. **Join our community** - Feel free to join us in our [Discord](http://discord.gg/plasticlabs) to discuss your changes, get help, or ask questions. +2. **Join our community** - Feel free to join us in our [Discord](http://discord.gg/honcho) to discuss your changes, get help, or ask questions. 3. **Review existing issues** - Check the [issues tab](https://github.com/plastic-labs/honcho/issues) to see what's already being worked on or to find something to contribute to. @@ -160,7 +160,7 @@ When reporting bugs or requesting features: ## Questions and Support -- **General questions** - Join our [Discord](http://discord.gg/plasticlabs) +- **General questions** - Join our [Discord](http://discord.gg/honcho) - **Bug reports** - Use GitHub issues - **Feature requests** - Use GitHub issues with the feature request template - **Security issues** - Please email us privately rather than opening a public issue diff --git a/docs/v2/contributing/self-hosting.mdx b/docs/v2/contributing/self-hosting.mdx index 5ad3e5a5..99a22528 100644 --- a/docs/v2/contributing/self-hosting.mdx +++ b/docs/v2/contributing/self-hosting.mdx @@ -280,7 +280,7 @@ const client = new Honcho({ - **Explore the API**: Check out the [API Reference](/v2/api-reference/introduction) - **Try the SDKs**: See our [guides](/v2/guides) for examples - **Configure Honcho**: Visit the [Configuration Guide](./configuration) for detailed settings -- **Join the community**: [Discord](https://discord.gg/plasticlabs) +- **Join the community**: [Discord](https://discord.gg/honcho) ## Troubleshooting @@ -311,7 +311,7 @@ const client = new Honcho({ ### Getting Help - **GitHub Issues**: [Report bugs](https://github.com/plastic-labs/honcho/issues) -- **Discord**: [Join our community](https://discord.gg/plasticlabs) +- **Discord**: [Join our community](https://discord.gg/honcho) - **Documentation**: Check the [Configuration Guide](./configuration) for detailed settings ## Production Considerations diff --git a/docs/v2/documentation/introduction/overview.mdx b/docs/v2/documentation/introduction/overview.mdx index e94a85de..c83b1e5b 100644 --- a/docs/v2/documentation/introduction/overview.mdx +++ b/docs/v2/documentation/introduction/overview.mdx @@ -115,5 +115,5 @@ fundamental concepts ## Community & Support - **GitHub**: [plastic-labs/honcho](https://github.com/plastic-labs/honcho) -- **Discord**: [Join our community](http://discord.gg/plasticlabs) +- **Discord**: [Join our community](http://discord.gg/honcho) - **Issues**: Report bugs and request features on GitHub diff --git a/docs/v2/documentation/reference/guided-tutorial.mdx b/docs/v2/documentation/reference/guided-tutorial.mdx index a7cac2f5..fd5331f6 100644 --- a/docs/v2/documentation/reference/guided-tutorial.mdx +++ b/docs/v2/documentation/reference/guided-tutorial.mdx @@ -422,4 +422,4 @@ Congratulations! You've built a complete personal AI assistant with Honcho that - [SDK Reference](/v2/documentation/reference/sdk) - [API Reference](/v2/api-reference/introduction) - [More Examples](/v2/guides/overview) -- [Discord Community](http://discord.gg/plasticlabs) +- [Discord Community](http://discord.gg/honcho) diff --git a/docs/v2/documentation/reference/platform.mdx b/docs/v2/documentation/reference/platform.mdx index 522d714d..d599b951 100644 --- a/docs/v2/documentation/reference/platform.mdx +++ b/docs/v2/documentation/reference/platform.mdx @@ -206,7 +206,7 @@ Dive into our [API Reference](/v2/api-reference) to explore all available endpoi Get started with managed Honcho instances - + Connect with 1000+ developers building with Honcho diff --git a/docs/v2/integrations/mcp.mdx b/docs/v2/integrations/mcp.mdx index 9c828580..8896da9f 100644 --- a/docs/v2/integrations/mcp.mdx +++ b/docs/v2/integrations/mcp.mdx @@ -70,4 +70,4 @@ You may customize your assistant name and/or workspace ID. Both are optional. 4. Finally, Claude needs instructions on how to use Honcho. The Desktop app doesn't allow you to add system prompts directly, but you can create a project and paste these [instructions](https://raw.githubusercontent.com/plastic-labs/honcho/refs/heads/main/mcp/instructions.md) into the "Project Instructions" field. -Claude should then query for insights before responding and write your messages to storage! If you come up with more creative ways to get Claude to manage its own memory with Honcho, feel free to [let us know](https://discord.gg/plasticlabs) or make a PR on this [repo](https://github.com/plastic-labs/honcho/tree/main/mcp)! +Claude should then query for insights before responding and write your messages to storage! If you come up with more creative ways to get Claude to manage its own memory with Honcho, feel free to [let us know](https://discord.gg/honcho) or make a PR on this [repo](https://github.com/plastic-labs/honcho/tree/main/mcp)! diff --git a/docs/v3/contributing/guidelines.mdx b/docs/v3/contributing/guidelines.mdx index f064e51b..398a8b09 100644 --- a/docs/v3/contributing/guidelines.mdx +++ b/docs/v3/contributing/guidelines.mdx @@ -11,7 +11,7 @@ Before you start contributing, please: 1. **Set up your development environment** - Follow the [Local Development guide](https://github.com/plastic-labs/honcho/blob/main/CONTRIBUTING.md#local-development) in the Honcho repository to get Honcho running locally. -2. **Join our community** - Feel free to join us in our [Discord](http://discord.gg/plasticlabs) to discuss your changes, get help, or ask questions. +2. **Join our community** - Feel free to join us in our [Discord](http://discord.gg/honcho) to discuss your changes, get help, or ask questions. 3. **Review existing issues** - Check the [issues tab](https://github.com/plastic-labs/honcho/issues) to see what's already being worked on or to find something to contribute to. @@ -160,7 +160,7 @@ When reporting bugs or requesting features: ## Questions and Support -- **General questions** - Join our [Discord](http://discord.gg/plasticlabs) +- **General questions** - Join our [Discord](http://discord.gg/honcho) - **Bug reports** - Use GitHub issues - **Feature requests** - Use GitHub issues with the feature request template - **Security issues** - Please email us privately rather than opening a public issue diff --git a/docs/v3/contributing/self-hosting.mdx b/docs/v3/contributing/self-hosting.mdx index 4dc0957c..4c9c4f22 100644 --- a/docs/v3/contributing/self-hosting.mdx +++ b/docs/v3/contributing/self-hosting.mdx @@ -279,7 +279,7 @@ const client = new Honcho({ - **Explore the API**: Check out the [API Reference](../api-reference/introduction) - **Try the SDKs**: See our [guides](../guides) for examples - **Configure Honcho**: Visit the [Configuration Guide](./configuration) for detailed settings -- **Join the community**: [Discord](https://discord.gg/plasticlabs) +- **Join the community**: [Discord](https://discord.gg/honcho) ## Troubleshooting @@ -310,7 +310,7 @@ const client = new Honcho({ ### Getting Help - **GitHub Issues**: [Report bugs](https://github.com/plastic-labs/honcho/issues) -- **Discord**: [Join our community](https://discord.gg/plasticlabs) +- **Discord**: [Join our community](https://discord.gg/honcho) - **Documentation**: Check the [Configuration Guide](./configuration) for detailed settings ## Production Considerations diff --git a/docs/v3/documentation/core-concepts/design-patterns.mdx b/docs/v3/documentation/core-concepts/design-patterns.mdx index 9f871cd0..be7d2caa 100644 --- a/docs/v3/documentation/core-concepts/design-patterns.mdx +++ b/docs/v3/documentation/core-concepts/design-patterns.mdx @@ -103,7 +103,7 @@ Not every peer needs a representation. Set `observe_me: false` on peers that beh ```python Python -from honcho import PeerConfig +from honcho.api_types import PeerConfig # The assistant doesn't need a representation assistant = honcho.peer("assistant", configuration=PeerConfig(observe_me=False)) diff --git a/docs/v3/documentation/core-concepts/reasoning.mdx b/docs/v3/documentation/core-concepts/reasoning.mdx index 750ccc77..6d198c5a 100644 --- a/docs/v3/documentation/core-concepts/reasoning.mdx +++ b/docs/v3/documentation/core-concepts/reasoning.mdx @@ -83,7 +83,7 @@ The approach balances quality with practical constraints. Custom models are smal Honcho's reasoning capabilities are actively being improved. Current areas of development include enhanced inductive and abductive reasoning, multi-hop and temporal reasoning, and expanded file types and modalities. The system is designed to be extensible--new reasoning capabilities can be added without breaking existing functionality. -If you find that the data you're uploading to Honcho isn't being reasoned over to your liking, we'd love to improve it for you and ingest your data for free--reach out via [Discord](https://discord.gg/plasticlabs) or [email](mailto:support@plasticlabs.ai)! +If you find that the data you're uploading to Honcho isn't being reasoned over to your liking, we'd love to improve it for you and ingest your data for free--reach out via [Discord](https://discord.gg/honcho) or [email](mailto:support@plasticlabs.ai)! ## Next Steps diff --git a/docs/v3/documentation/features/advanced/representation-scopes.mdx b/docs/v3/documentation/features/advanced/representation-scopes.mdx index d6e03867..d7c478d7 100644 --- a/docs/v3/documentation/features/advanced/representation-scopes.mdx +++ b/docs/v3/documentation/features/advanced/representation-scopes.mdx @@ -80,7 +80,8 @@ The `target` parameter controls which representation you retrieve: ```python Python -from honcho import Honcho, SessionPeerConfig +from honcho import Honcho +from honcho.api_types import SessionPeerConfig honcho = Honcho() session = honcho.session("game-session") diff --git a/docs/v3/documentation/reference/platform.mdx b/docs/v3/documentation/reference/platform.mdx index 11df5884..75fc9bd5 100644 --- a/docs/v3/documentation/reference/platform.mdx +++ b/docs/v3/documentation/reference/platform.mdx @@ -163,7 +163,7 @@ Dive into our [API Reference](/v3/api-reference) to explore all available endpoi Get started with managed Honcho instances - + Connect with 1000+ developers building with Honcho diff --git a/docs/v3/documentation/reference/sdk.mdx b/docs/v3/documentation/reference/sdk.mdx index 3f5cc764..77652bf0 100644 --- a/docs/v3/documentation/reference/sdk.mdx +++ b/docs/v3/documentation/reference/sdk.mdx @@ -751,7 +751,7 @@ const metadata = await session.getMetadata(); ```python Python -from honcho import SessionPeerConfig +from honcho.api_types import SessionPeerConfig # Configure peer observation settings config = SessionPeerConfig( diff --git a/sdks/python/CHANGELOG.md b/sdks/python/CHANGELOG.md index ba055bcd..36576f05 100644 --- a/sdks/python/CHANGELOG.md +++ b/sdks/python/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [2.1.1] - 2026-04-01 + +### 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 + ## [2.1.0] - 2026-03-25 ### Added diff --git a/sdks/python/README.md b/sdks/python/README.md index 6d391fdc..fa83ba0e 100644 --- a/sdks/python/README.md +++ b/sdks/python/README.md @@ -29,9 +29,6 @@ session.add_messages([ bob.message("Hi Alice, how are you?") ]) -# Wait for deriver to process all messages (only necessary if very recent messages are critical to query) -client.poll_deriver_status() - # Query conversation context response = alice.chat("What did Bob say to the user?") print(response) @@ -73,7 +70,7 @@ session.add_messages([ ]) # Get conversation context -context = session.get_context() +context = session.context() ``` ### Messages and Context @@ -82,7 +79,7 @@ Retrieve and use conversation history: ```python # Get messages from a session -messages = session.get_messages() +messages = session.messages() # Convert to OpenAI format for further prompting openai_messages = context.to_openai(assistant="assistant") @@ -93,11 +90,24 @@ anthropic_messages = context.to_anthropic(assistant="assistant") ### Async Support +The SDK provides async access via the `.aio` accessor on any instance: + ```python -from honcho import AsyncHoncho +from honcho import Honcho async def main(): - client = AsyncHoncho(api_key="your-api-key") + client = Honcho(api_key="your-api-key") + + # Async peer and session creation + peer = await client.aio.peer("user-123") + session = await client.aio.session("conversation-1") + + # Async chat + response = await peer.aio.chat("What does this user prefer?") + + # Async iteration + async for p in client.aio.peers(): + print(p.id) ``` ### Metadata Management @@ -119,7 +129,7 @@ response = alice.chat("Does Bob remember our discussion about the budget?", targ # Session-specific perspective response = alice.chat("What does Bob think about this project?", target=bob, - session_id=session.id) + session=session) ``` ## Configuration @@ -137,21 +147,12 @@ export HONCHO_WORKSPACE_ID="your-workspace" # Optional ```python client = Honcho( api_key="your-api-key", - environment="production", # or "local", "demo" + environment="production", # or "local" workspace_id="custom-workspace", base_url="https://api.honcho.dev" ) ``` -## Examples - -Check out the `examples/` directory for complete usage examples: - -- `example.py` - Comprehensive feature demonstration -- `chat.py` - Basic multi-peer chat -- `async_example.py` - Async/await usage -- `search.py` - Context search and retrieval - ## License Apache 2.0 - see [LICENSE](../../LICENSE) for details. @@ -159,5 +160,5 @@ Apache 2.0 - see [LICENSE](../../LICENSE) for details. ## Support - [Documentation](https://docs.honcho.dev) -- [GitHub Issues](https://github.com/plastic-labs/honcho-sdks/issues) +- [GitHub Issues](https://github.com/plastic-labs/honcho/issues) - [Discord Community](https://discord.gg/honcho) diff --git a/sdks/python/pyproject.toml b/sdks/python/pyproject.toml index 3fda759a..acee404d 100644 --- a/sdks/python/pyproject.toml +++ b/sdks/python/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "honcho-ai" -version = "2.1.0" +version = "2.1.1" description = "Official DX Optimized Python SDK for Honcho" dynamic = ["readme"] license = "Apache-2.0" diff --git a/sdks/python/src/honcho/http/async_client.py b/sdks/python/src/honcho/http/async_client.py index 0db853b8..14a1df8c 100644 --- a/sdks/python/src/honcho/http/async_client.py +++ b/sdks/python/src/honcho/http/async_client.py @@ -131,17 +131,15 @@ class AsyncHonchoHTTPClient: raise error - except httpx.TimeoutException as e: - error = TimeoutError(f"Request timed out after {request_timeout}s") - if attempt < self.max_retries: - last_error = error - await asyncio.sleep(self._get_retry_delay(attempt)) - attempt += 1 - continue - raise error from e - - except httpx.ConnectError as e: - error = ConnectionError(f"Connection failed: {e}") + except ( + httpx.TimeoutException, + httpx.NetworkError, + httpx.RemoteProtocolError, + ) as e: + if isinstance(e, httpx.TimeoutException): + error = TimeoutError(f"Request timed out after {request_timeout}s") + else: + error = ConnectionError(f"Connection error: {e}") if attempt < self.max_retries: last_error = error await asyncio.sleep(self._get_retry_delay(attempt)) diff --git a/sdks/python/src/honcho/http/client.py b/sdks/python/src/honcho/http/client.py index dd406953..f3cc2fc9 100644 --- a/sdks/python/src/honcho/http/client.py +++ b/sdks/python/src/honcho/http/client.py @@ -131,17 +131,15 @@ class HonchoHTTPClient: raise error - except httpx.TimeoutException as e: - error = TimeoutError(f"Request timed out after {request_timeout}s") - if attempt < self.max_retries: - last_error = error - time.sleep(self._get_retry_delay(attempt)) - attempt += 1 - continue - raise error from e - - except httpx.ConnectError as e: - error = ConnectionError(f"Connection failed: {e}") + except ( + httpx.TimeoutException, + httpx.NetworkError, + httpx.RemoteProtocolError, + ) as e: + if isinstance(e, httpx.TimeoutException): + error = TimeoutError(f"Request timed out after {request_timeout}s") + else: + error = ConnectionError(f"Connection error: {e}") if attempt < self.max_retries: last_error = error time.sleep(self._get_retry_delay(attempt)) diff --git a/sdks/typescript/CHANGELOG.md b/sdks/typescript/CHANGELOG.md index ca77230a..008d2f45 100644 --- a/sdks/typescript/CHANGELOG.md +++ b/sdks/typescript/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [2.1.1] - 2026-04-01 + +### 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) + ## [2.1.0] - 2026-03-25 ### Added diff --git a/sdks/typescript/README.md b/sdks/typescript/README.md index c6ac05bc..ad8b8069 100644 --- a/sdks/typescript/README.md +++ b/sdks/typescript/README.md @@ -1,6 +1,6 @@ # Honcho TypeScript SDK -A high-level, ergonomic TypeScript SDK for the Honcho conversational memory platform. This library wraps [honcho-node-core](../honcho-node-core) to provide a user-friendly, Pythonic API for managing peers, sessions, and conversational context. +A high-level, ergonomic TypeScript SDK for the Honcho conversational memory platform. Provides a user-friendly API for managing peers, sessions, and conversational context. ## Installation @@ -19,12 +19,12 @@ const honcho = new Honcho({ workspaceId: "test", }); -const assistant = honcho.peer("bob"); -const alice = honcho.peer("alice"); +const assistant = await honcho.peer("bob"); +const alice = await honcho.peer("alice"); -await honcho.getPeers(); +await honcho.peers(); -const session = honcho.session("session_1"); +const session = await honcho.session("session_1"); await session.addPeers([alice, assistant]); await session.addMessages([ diff --git a/sdks/typescript/package.json b/sdks/typescript/package.json index 29b06e85..136b716a 100644 --- a/sdks/typescript/package.json +++ b/sdks/typescript/package.json @@ -1,6 +1,6 @@ { "name": "@honcho-ai/sdk", - "version": "2.1.0", + "version": "2.1.1", "description": "Official DX Optimized TypeScript SDK for Honcho", "author": "Plastic Labs ", "license": "Apache-2.0", diff --git a/sdks/typescript/src/http/client.ts b/sdks/typescript/src/http/client.ts index a3ff2c1f..e22480d2 100644 --- a/sdks/typescript/src/http/client.ts +++ b/sdks/typescript/src/http/client.ts @@ -134,18 +134,6 @@ export class HonchoHTTPClient { throw error } - // Handle fetch errors (network issues) - if (error instanceof TypeError && error.message.includes('fetch')) { - const connError = new ConnectionError(error.message) - if (attempt < this.maxRetries) { - lastError = connError - await this.sleep(this.getRetryDelay(attempt)) - attempt++ - continue - } - throw connError - } - throw error } } @@ -342,6 +330,14 @@ export class HonchoHTTPClient { if (error instanceof DOMException && error.name === 'AbortError') { throw new TimeoutError(`Request timed out after ${timeout}ms`) } + // fetch() throws TypeError for network-level failures (e.g. "fetch + // failed", connection reset, DNS errors). Convert these to + // ConnectionError so the retry loop can handle them. This mapping + // lives here rather than in the outer catch so that TypeErrors from + // other sources (e.g. JSON.stringify serialization) propagate as-is. + if (error instanceof TypeError) { + throw new ConnectionError(error.message) + } throw error } finally { clearTimeout(timeoutId) diff --git a/uv.lock b/uv.lock index a206b216..7c814b9b 100644 --- a/uv.lock +++ b/uv.lock @@ -1397,7 +1397,7 @@ dev = [ [[package]] name = "honcho-ai" -version = "2.1.0" +version = "2.1.1" source = { editable = "sdks/python" } dependencies = [ { name = "httpx" },