From 2c6681394438d544ea2aeb0e9c26de8b4669ef19 Mon Sep 17 00:00:00 2001 From: Benjamin McCormick Date: Mon, 12 Jan 2026 17:27:54 -0500 Subject: [PATCH] fix: use real stainless releases, update to match --- sdks/python/pyproject.toml | 2 +- sdks/python/src/honcho/async_client/client.py | 10 ++-- sdks/python/src/honcho/async_client/peer.py | 16 ++--- .../python/src/honcho/async_client/session.py | 34 +++++------ sdks/python/src/honcho/client.py | 10 ++-- sdks/python/src/honcho/conclusions.py | 7 ++- sdks/python/src/honcho/peer.py | 44 +++++++------- sdks/python/src/honcho/session.py | 54 ++++++++--------- sdks/typescript/__tests__/client.test.ts | 14 ++--- sdks/typescript/__tests__/integration.test.ts | 18 +++--- sdks/typescript/__tests__/peer.test.ts | 46 +++++++------- sdks/typescript/__tests__/session.test.ts | 60 +++++++++---------- sdks/typescript/bun.lock | 4 +- sdks/typescript/package.json | 2 +- sdks/typescript/src/client.ts | 12 ++-- sdks/typescript/src/conclusions.ts | 2 +- sdks/typescript/src/peer.ts | 4 +- sdks/typescript/src/session.ts | 18 +++--- src/config.py | 2 +- src/utils/agent_tools.py | 6 +- src/utils/config_helpers.py | 19 +++--- tests/sdk/test_client.py | 32 +++++----- tests/sdk/test_session.py | 28 ++++----- tests/unified/runner.py | 4 +- uv.lock | 22 ++----- 25 files changed, 227 insertions(+), 243 deletions(-) diff --git a/sdks/python/pyproject.toml b/sdks/python/pyproject.toml index b453f001..c08edd85 100644 --- a/sdks/python/pyproject.toml +++ b/sdks/python/pyproject.toml @@ -8,7 +8,7 @@ authors = [ { name = "Plastic Labs", email = "hello@plasticlabs.ai" }, ] dependencies = [ - "honcho-core @ https://pkg.stainless.com/s/honcho-python/b5539818022ab4ad757250ea3234648f8dc5906e/honcho_core-1.8.0-py3-none-any.whl", + "honcho-core==1.9.0", "httpx>=0.28.0, <1", "pydantic>=2.0.0, <3", "typing-extensions>=4.12.0; python_version < \"3.12\"", diff --git a/sdks/python/src/honcho/async_client/client.py b/sdks/python/src/honcho/async_client/client.py index e3e18293..814d89db 100644 --- a/sdks/python/src/honcho/async_client/client.py +++ b/sdks/python/src/honcho/async_client/client.py @@ -8,7 +8,7 @@ from typing import Any, Literal import httpx from honcho_core import AsyncHoncho as AsyncHonchoCore from honcho_core import Honcho as HonchoCore -from honcho_core.types.workspaces import QueueGetStatusResponse +from honcho_core.types.workspaces import QueueStatusResponse from honcho_core.types.workspaces.peer import Peer as PeerCore from honcho_core.types.workspaces.session import Session as SessionCore from honcho_core.types.workspaces.sessions.message import Message @@ -474,7 +474,7 @@ class AsyncHoncho(BaseModel): observer: str | PeerBase | None = None, sender: str | PeerBase | None = None, session: str | SessionBase | None = None, - ) -> QueueGetStatusResponse: + ) -> QueueStatusResponse: """ Get the queue processing status, optionally scoped to an observer, sender, and/or session. @@ -499,7 +499,7 @@ class AsyncHoncho(BaseModel): else (session if isinstance(session, str) else session.id) ) - return await self._client.workspaces.queue.get_status( + return await self._client.workspaces.queue.status( workspace_id=self.workspace_id, observer_id=resolved_observer_id, sender_id=resolved_sender_id, @@ -517,7 +517,7 @@ class AsyncHoncho(BaseModel): gt=0, description="Maximum time to poll in seconds. Defaults to 5 minutes (300 seconds).", ), - ) -> QueueGetStatusResponse: + ) -> QueueStatusResponse: """ Poll get_queue_status until pending_work_units and in_progress_work_units are both 0. This allows you to guarantee that all messages have been processed by the queue for @@ -532,7 +532,7 @@ class AsyncHoncho(BaseModel): timeout: Maximum time to poll in seconds. Defaults to 5 minutes (300 seconds). Returns: - QueueGetStatusResponse when all work units are complete + QueueStatusResponse when all work units are complete Raises: TimeoutError: If timeout is exceeded before work units complete diff --git a/sdks/python/src/honcho/async_client/peer.py b/sdks/python/src/honcho/async_client/peer.py index e3d88431..ce2893b9 100644 --- a/sdks/python/src/honcho/async_client/peer.py +++ b/sdks/python/src/honcho/async_client/peer.py @@ -7,11 +7,11 @@ from typing import Literal from honcho_core import AsyncHoncho as AsyncHonchoCore from honcho_core._types import omit from honcho_core.types.workspaces import PeerCardResponse -from honcho_core.types.workspaces.peer_get_context_response import ( - PeerGetContextResponse, +from honcho_core.types.workspaces.peer_context_response import ( + PeerContextResponse, ) -from honcho_core.types.workspaces.peer_get_representation_response import ( - PeerGetRepresentationResponse, +from honcho_core.types.workspaces.peer_representation_response import ( + PeerRepresentationResponse, ) from honcho_core.types.workspaces.session import Session as SessionCore from honcho_core.types.workspaces.sessions import MessageCreateParam @@ -565,8 +565,8 @@ class AsyncPeer(PeerBase): if target is None else (target if isinstance(target, str) else target.id) ) - data: PeerGetRepresentationResponse = ( - await self._client.workspaces.peers.get_representation( + data: PeerRepresentationResponse = ( + await self._client.workspaces.peers.representation( peer_id=self.id, workspace_id=self.workspace_id, session_id=session_id, @@ -594,7 +594,7 @@ class AsyncPeer(PeerBase): search_max_distance: float | None = None, include_most_frequent: bool | None = None, max_conclusions: int | None = None, - ) -> PeerGetContextResponse: + ) -> PeerContextResponse: """ Get context for this peer, including representation and peer card. @@ -637,7 +637,7 @@ class AsyncPeer(PeerBase): else (target if isinstance(target, str) else target.id) ) - return await self._client.workspaces.peers.get_context( + return await self._client.workspaces.peers.context( peer_id=self.id, workspace_id=self.workspace_id, target=target_id, diff --git a/sdks/python/src/honcho/async_client/session.py b/sdks/python/src/honcho/async_client/session.py index 0e7d90a0..f68c38c0 100644 --- a/sdks/python/src/honcho/async_client/session.py +++ b/sdks/python/src/honcho/async_client/session.py @@ -9,9 +9,9 @@ from typing import TYPE_CHECKING, Any from honcho_core import AsyncHoncho as AsyncHonchoCore from honcho_core._types import omit -from honcho_core.types.workspaces import QueueGetStatusResponse -from honcho_core.types.workspaces.peer_get_representation_response import ( - PeerGetRepresentationResponse, +from honcho_core.types.workspaces import QueueStatusResponse +from honcho_core.types.workspaces.peer_representation_response import ( + PeerRepresentationResponse, ) from honcho_core.types.workspaces.sessions import MessageCreateParam from honcho_core.types.workspaces.sessions.message import Message @@ -306,16 +306,14 @@ class AsyncSession(SessionBase): Get the configuration for a peer in this session. """ peer_id = peer if isinstance(peer, str) else peer.id - peer_get_config_response = ( - await self._client.workspaces.sessions.peers.get_config( - peer_id=peer_id, - workspace_id=self.workspace_id, - session_id=self.id, - ) + peer_config_response = await self._client.workspaces.sessions.peers.config( + peer_id=peer_id, + workspace_id=self.workspace_id, + session_id=self.id, ) return SessionPeerConfig( - observe_others=peer_get_config_response.observe_others, - observe_me=peer_get_config_response.observe_me, + observe_others=peer_config_response.observe_others, + observe_me=peer_config_response.observe_me, ) async def set_peer_config( @@ -654,7 +652,7 @@ class AsyncSession(SessionBase): if isinstance(last_user_message, Message) else last_user_message ) - context = await self._client.workspaces.sessions.get_context( + context = await self._client.workspaces.sessions.context( session_id=self.id, workspace_id=self.workspace_id, tokens=tokens if tokens is not None else omit, @@ -916,8 +914,8 @@ class AsyncSession(SessionBase): if target is None else (target if isinstance(target, str) else target.id) ) - data: PeerGetRepresentationResponse = ( - await self._client.workspaces.peers.get_representation( + data: PeerRepresentationResponse = ( + await self._client.workspaces.peers.representation( peer_id, workspace_id=self.workspace_id, session_id=self.id, @@ -942,7 +940,7 @@ class AsyncSession(SessionBase): self, observer: str | PeerBase | None = None, sender: str | PeerBase | None = None, - ) -> QueueGetStatusResponse: + ) -> QueueStatusResponse: """ Get the queue processing status, optionally scoped to an observer, sender, and/or session. @@ -961,7 +959,7 @@ class AsyncSession(SessionBase): else (sender if isinstance(sender, str) else sender.id) ) - return await self._client.workspaces.queue.get_status( + return await self._client.workspaces.queue.status( workspace_id=self.workspace_id, observer_id=resolved_observer_id, sender_id=resolved_sender_id, @@ -978,7 +976,7 @@ class AsyncSession(SessionBase): gt=0, description="Maximum time to poll in seconds. Defaults to 5 minutes (300 seconds).", ), - ) -> QueueGetStatusResponse: + ) -> QueueStatusResponse: """ Poll get_queue_status until pending_work_units and in_progress_work_units are both 0. This allows you to guarantee that all messages have been processed by the queue for @@ -992,7 +990,7 @@ class AsyncSession(SessionBase): timeout: Maximum time to poll in seconds. Defaults to 5 minutes (300 seconds). Returns: - QueueGetStatusResponse when all work units are complete + QueueStatusResponse when all work units are complete Raises: TimeoutError: If timeout is exceeded before work units complete diff --git a/sdks/python/src/honcho/client.py b/sdks/python/src/honcho/client.py index fad04b82..75711906 100644 --- a/sdks/python/src/honcho/client.py +++ b/sdks/python/src/honcho/client.py @@ -6,7 +6,7 @@ from typing import Any, Literal import httpx from honcho_core import Honcho as HonchoCore -from honcho_core.types.workspaces import QueueGetStatusResponse +from honcho_core.types.workspaces import QueueStatusResponse from honcho_core.types.workspaces.peer import Peer as PeerCore from honcho_core.types.workspaces.session import Session as SessionCore from honcho_core.types.workspaces.sessions.message import Message @@ -449,7 +449,7 @@ class Honcho(BaseModel): observer: str | PeerBase | None = None, sender: str | PeerBase | None = None, session: str | SessionBase | None = None, - ) -> QueueGetStatusResponse: + ) -> QueueStatusResponse: """ Get the queue processing status, optionally scoped to an observer, sender, and/or session. @@ -474,7 +474,7 @@ class Honcho(BaseModel): else (session if isinstance(session, str) else session.id) ) - return self._client.workspaces.queue.get_status( + return self._client.workspaces.queue.status( workspace_id=self.workspace_id, observer_id=resolved_observer_id, sender_id=resolved_sender_id, @@ -492,7 +492,7 @@ class Honcho(BaseModel): gt=0, description="Maximum time to poll in seconds. Defaults to 5 minutes (300 seconds).", ), - ) -> QueueGetStatusResponse: + ) -> QueueStatusResponse: """ Poll get_queue_status until pending_work_units and in_progress_work_units are both 0. This allows you to guarantee that all messages have been processed by the queue for @@ -507,7 +507,7 @@ class Honcho(BaseModel): timeout: Maximum time to poll in seconds. Defaults to 5 minutes (300 seconds). Returns: - QueueGetStatusResponse when all work units are complete + QueueStatusResponse when all work units are complete Raises: TimeoutError: If timeout is exceeded before work units complete diff --git a/sdks/python/src/honcho/conclusions.py b/sdks/python/src/honcho/conclusions.py index d3fe0f48..6e572b60 100644 --- a/sdks/python/src/honcho/conclusions.py +++ b/sdks/python/src/honcho/conclusions.py @@ -19,6 +19,7 @@ __all__ = [ "ConclusionCreateResponse", "ConclusionScope", "ConclusionCreateParams", + "AsyncConclusionScope", ] ConclusionCreateResponse: TypeAlias = list[Conclusion] @@ -202,7 +203,7 @@ class ConclusionScope: ], ) - def get_representation( + def representation( self, search_query: str | None = None, search_top_k: int | None = None, @@ -228,7 +229,7 @@ class ConclusionScope: """ from honcho_core._types import omit - response = self._client.workspaces.peers.get_representation( + response = self._client.workspaces.peers.representation( peer_id=self.observer, workspace_id=self.workspace_id, target=self.observed, @@ -450,7 +451,7 @@ class AsyncConclusionScope: """ from honcho_core._types import omit - response = await self._client.workspaces.peers.get_representation( + response = await self._client.workspaces.peers.representation( peer_id=self.observer, workspace_id=self.workspace_id, target=self.observed, diff --git a/sdks/python/src/honcho/peer.py b/sdks/python/src/honcho/peer.py index c5042acc..50ecdf30 100644 --- a/sdks/python/src/honcho/peer.py +++ b/sdks/python/src/honcho/peer.py @@ -7,11 +7,11 @@ from typing import Literal from honcho_core import Honcho as HonchoCore from honcho_core._types import omit from honcho_core.types.workspaces import PeerCardResponse -from honcho_core.types.workspaces.peer_get_context_response import ( - PeerGetContextResponse, +from honcho_core.types.workspaces.peer_context_response import ( + PeerContextResponse, ) -from honcho_core.types.workspaces.peer_get_representation_response import ( - PeerGetRepresentationResponse, +from honcho_core.types.workspaces.peer_representation_response import ( + PeerRepresentationResponse, ) from honcho_core.types.workspaces.session import Session as SessionCore from honcho_core.types.workspaces.sessions import MessageCreateParam @@ -541,24 +541,20 @@ class Peer(PeerBase): if target is None else (target if isinstance(target, str) else target.id) ) - data: PeerGetRepresentationResponse = ( - self._client.workspaces.peers.get_representation( - peer_id=self.id, - workspace_id=self.workspace_id, - session_id=session_id, - target=target_id, - search_query=search_query if search_query is not None else omit, - search_top_k=search_top_k if search_top_k is not None else omit, - search_max_distance=search_max_distance - if search_max_distance is not None - else omit, - include_most_frequent=include_most_frequent - if include_most_frequent is not None - else omit, - max_conclusions=max_conclusions - if max_conclusions is not None - else omit, - ) + data: PeerRepresentationResponse = self._client.workspaces.peers.representation( + peer_id=self.id, + workspace_id=self.workspace_id, + session_id=session_id, + target=target_id, + search_query=search_query if search_query is not None else omit, + search_top_k=search_top_k if search_top_k is not None else omit, + search_max_distance=search_max_distance + if search_max_distance is not None + else omit, + include_most_frequent=include_most_frequent + if include_most_frequent is not None + else omit, + max_conclusions=max_conclusions if max_conclusions is not None else omit, ) return data.representation @@ -570,7 +566,7 @@ class Peer(PeerBase): search_max_distance: float | None = None, include_most_frequent: bool | None = None, max_conclusions: int | None = None, - ) -> PeerGetContextResponse: + ) -> PeerContextResponse: """ Get context for this peer, including representation and peer card. @@ -614,7 +610,7 @@ class Peer(PeerBase): else (target if isinstance(target, str) else target.id) ) - return self._client.workspaces.peers.get_context( + return self._client.workspaces.peers.context( peer_id=self.id, workspace_id=self.workspace_id, target=target_id, diff --git a/sdks/python/src/honcho/session.py b/sdks/python/src/honcho/session.py index 46dc4e6a..4e48edd3 100644 --- a/sdks/python/src/honcho/session.py +++ b/sdks/python/src/honcho/session.py @@ -8,9 +8,9 @@ from typing import TYPE_CHECKING, Any from honcho_core import Honcho as HonchoCore from honcho_core._types import omit -from honcho_core.types.workspaces import QueueGetStatusResponse -from honcho_core.types.workspaces.peer_get_representation_response import ( - PeerGetRepresentationResponse, +from honcho_core.types.workspaces import QueueStatusResponse +from honcho_core.types.workspaces.peer_representation_response import ( + PeerRepresentationResponse, ) from honcho_core.types.workspaces.sessions import MessageCreateParam from honcho_core.types.workspaces.sessions.message import Message @@ -281,14 +281,14 @@ class Session(SessionBase): Get the configuration for a peer in this session. """ peer_id = peer if isinstance(peer, str) else peer.id - peer_get_config_response = self._client.workspaces.sessions.peers.get_config( + peer_config_response = self._client.workspaces.sessions.peers.config( peer_id=peer_id, workspace_id=self.workspace_id, session_id=self.id, ) return SessionPeerConfig( - observe_others=peer_get_config_response.observe_others, - observe_me=peer_get_config_response.observe_me, + observe_others=peer_config_response.observe_others, + observe_me=peer_config_response.observe_me, ) def set_peer_config(self, peer: str | PeerBase, config: SessionPeerConfig) -> None: @@ -625,7 +625,7 @@ class Session(SessionBase): if isinstance(last_user_message, Message) else last_user_message ) - context = self._client.workspaces.sessions.get_context( + context = self._client.workspaces.sessions.context( session_id=self.id, workspace_id=self.workspace_id, tokens=tokens if tokens is not None else omit, @@ -887,24 +887,20 @@ class Session(SessionBase): if target is None else (target if isinstance(target, str) else target.id) ) - data: PeerGetRepresentationResponse = ( - self._client.workspaces.peers.get_representation( - peer_id, - workspace_id=self.workspace_id, - session_id=self.id, - target=target_id, - search_query=search_query if search_query is not None else omit, - search_top_k=search_top_k if search_top_k is not None else omit, - search_max_distance=search_max_distance - if search_max_distance is not None - else omit, - include_most_frequent=include_most_frequent - if include_most_frequent is not None - else omit, - max_conclusions=max_conclusions - if max_conclusions is not None - else omit, - ) + data: PeerRepresentationResponse = self._client.workspaces.peers.representation( + peer_id, + workspace_id=self.workspace_id, + session_id=self.id, + target=target_id, + search_query=search_query if search_query is not None else omit, + search_top_k=search_top_k if search_top_k is not None else omit, + search_max_distance=search_max_distance + if search_max_distance is not None + else omit, + include_most_frequent=include_most_frequent + if include_most_frequent is not None + else omit, + max_conclusions=max_conclusions if max_conclusions is not None else omit, ) return data.representation @@ -913,7 +909,7 @@ class Session(SessionBase): self, observer: str | PeerBase | None = None, sender: str | PeerBase | None = None, - ) -> QueueGetStatusResponse: + ) -> QueueStatusResponse: """ Get the queue processing status, optionally scoped to an observer, sender, and/or session. @@ -932,7 +928,7 @@ class Session(SessionBase): else (sender if isinstance(sender, str) else sender.id) ) - return self._client.workspaces.queue.get_status( + return self._client.workspaces.queue.status( workspace_id=self.workspace_id, observer_id=resolved_observer_id, sender_id=resolved_sender_id, @@ -949,7 +945,7 @@ class Session(SessionBase): gt=0, description="Maximum time to poll in seconds. Defaults to 5 minutes (300 seconds).", ), - ) -> QueueGetStatusResponse: + ) -> QueueStatusResponse: """ Poll get_queue_status until pending_work_units and in_progress_work_units are both 0. This allows you to guarantee that all messages have been processed by the queue for @@ -963,7 +959,7 @@ class Session(SessionBase): timeout: Maximum time to poll in seconds. Defaults to 5 minutes (300 seconds). Returns: - QueueGetStatusResponse when all work units are complete + QueueStatusResponse when all work units are complete Raises: TimeoutError: If timeout is exceeded before work units complete diff --git a/sdks/typescript/__tests__/client.test.ts b/sdks/typescript/__tests__/client.test.ts index ac5c51c6..5c3c18fa 100644 --- a/sdks/typescript/__tests__/client.test.ts +++ b/sdks/typescript/__tests__/client.test.ts @@ -17,7 +17,7 @@ jest.mock('@honcho-ai/core', () => { getOrCreate: jest.fn(), }, queue: { - getStatus: jest.fn(), + status: jest.fn(), }, getOrCreate: jest.fn().mockResolvedValue({ id: 'test-workspace', metadata: {} }), update: jest.fn(), @@ -419,7 +419,7 @@ describe('Honcho Client', () => { pending_work_units: 2, sessions: { 'session1': { status: 'active' } }, }; - mockClient.workspaces.queue.getStatus.mockResolvedValue(mockStatus); + mockClient.workspaces.queue.status.mockResolvedValue(mockStatus); const status = await honcho.getQueueStatus(); @@ -430,7 +430,7 @@ describe('Honcho Client', () => { pendingWorkUnits: 2, sessions: { 'session1': { status: 'active' } }, }); - expect(mockClient.workspaces.queue.getStatus).toHaveBeenCalledWith( + expect(mockClient.workspaces.queue.status).toHaveBeenCalledWith( 'test-workspace', {} ); @@ -443,7 +443,7 @@ describe('Honcho Client', () => { in_progress_work_units: 1, pending_work_units: 1, }; - mockClient.workspaces.queue.getStatus.mockResolvedValue(mockStatus); + mockClient.workspaces.queue.status.mockResolvedValue(mockStatus); const status = await honcho.getQueueStatus({ observer: 'observer1', @@ -458,7 +458,7 @@ describe('Honcho Client', () => { pendingWorkUnits: 1, sessions: undefined, }); - expect(mockClient.workspaces.queue.getStatus).toHaveBeenCalledWith( + expect(mockClient.workspaces.queue.status).toHaveBeenCalledWith( 'test-workspace', { observer_id: 'observer1', @@ -477,7 +477,7 @@ describe('Honcho Client', () => { in_progress_work_units: 0, pending_work_units: 0, }; - mockClient.workspaces.queue.getStatus.mockResolvedValue(mockStatusComplete); + mockClient.workspaces.queue.status.mockResolvedValue(mockStatusComplete); const status = await honcho.pollQueueStatus(); @@ -497,7 +497,7 @@ describe('Honcho Client', () => { in_progress_work_units: 2, pending_work_units: 1, }; - mockClient.workspaces.queue.getStatus.mockResolvedValue(mockStatusPending); + mockClient.workspaces.queue.status.mockResolvedValue(mockStatusPending); await expect(honcho.pollQueueStatus({ timeoutMs: 0 })).rejects.toThrow(); }); diff --git a/sdks/typescript/__tests__/integration.test.ts b/sdks/typescript/__tests__/integration.test.ts index 1be878fc..96fded3a 100644 --- a/sdks/typescript/__tests__/integration.test.ts +++ b/sdks/typescript/__tests__/integration.test.ts @@ -25,7 +25,7 @@ describe('Honcho SDK Integration Tests', () => { getOrCreate: jest.fn(), update: jest.fn(), search: jest.fn(), - getRepresentation: jest.fn(), + representation: jest.fn(), }, sessions: { list: jest.fn(), @@ -38,7 +38,7 @@ describe('Honcho SDK Integration Tests', () => { messages: { create: jest.fn(), list: jest.fn() }, getOrCreate: jest.fn(), update: jest.fn(), - getContext: jest.fn(), + context: jest.fn(), search: jest.fn(), }, getOrCreate: jest.fn(), @@ -90,7 +90,7 @@ describe('Honcho SDK Integration Tests', () => { mockWorkspacesApi.workspaces.sessions.messages.create.mockResolvedValue( {} ) - mockWorkspacesApi.workspaces.sessions.getContext.mockResolvedValue( + mockWorkspacesApi.workspaces.sessions.context.mockResolvedValue( mockContextData ) mockWorkspacesApi.workspaces.peers.chat.mockResolvedValue({ @@ -284,7 +284,7 @@ describe('Honcho SDK Integration Tests', () => { mockWorkspacesApi.workspaces.peers.chat.mockRejectedValue( new Error('Chat API failed') ) - mockWorkspacesApi.workspaces.sessions.getContext.mockRejectedValue( + mockWorkspacesApi.workspaces.sessions.context.mockRejectedValue( new Error('Context API failed') ) @@ -372,7 +372,7 @@ describe('Honcho SDK Integration Tests', () => { const mockRepresentation = 'Alice likes coffee\nAlice works as a developer\nAlice is a coffee-drinking developer' - mockWorkspacesApi.workspaces.peers.getRepresentation.mockResolvedValue({ + mockWorkspacesApi.workspaces.peers.representation.mockResolvedValue({ representation: mockRepresentation, }) @@ -384,7 +384,7 @@ describe('Honcho SDK Integration Tests', () => { const globalRep = await session.getRepresentation('alice') expect(globalRep).toBe(mockRepresentation) expect( - mockWorkspacesApi.workspaces.peers.getRepresentation + mockWorkspacesApi.workspaces.peers.representation ).toHaveBeenCalledWith('integration-test-workspace', 'alice', { session_id: 'working-rep-session', target: undefined, @@ -399,7 +399,7 @@ describe('Honcho SDK Integration Tests', () => { const targetRep = await session.getRepresentation(alice, bob) expect(targetRep).toBe(mockRepresentation) expect( - mockWorkspacesApi.workspaces.peers.getRepresentation + mockWorkspacesApi.workspaces.peers.representation ).toHaveBeenCalledWith('integration-test-workspace', 'alice', { session_id: 'working-rep-session', target: 'bob', @@ -423,7 +423,7 @@ describe('Honcho SDK Integration Tests', () => { total: 0, hasNextPage: false, }) - mockWorkspacesApi.workspaces.sessions.getContext.mockResolvedValue({ + mockWorkspacesApi.workspaces.sessions.context.mockResolvedValue({ messages: [], }) @@ -461,7 +461,7 @@ describe('Honcho SDK Integration Tests', () => { expect(typeof message.metadata).toBe('object') // Mock successful operations - mockWorkspacesApi.workspaces.sessions.getContext.mockResolvedValue({ + mockWorkspacesApi.workspaces.sessions.context.mockResolvedValue({ messages: [{ id: 'msg1', content: 'Hello', peer_id: 'typed-peer' }], summary: { content: 'Test summary', diff --git a/sdks/typescript/__tests__/peer.test.ts b/sdks/typescript/__tests__/peer.test.ts index 232c91c2..8a3d26e2 100644 --- a/sdks/typescript/__tests__/peer.test.ts +++ b/sdks/typescript/__tests__/peer.test.ts @@ -554,12 +554,12 @@ describe('Peer', () => { describe('getRepresentation', () => { beforeEach(() => { - mockClient.workspaces.peers.getRepresentation = jest.fn(); + mockClient.workspaces.peers.representation = jest.fn(); }); it('should get working representation with no parameters', async () => { const mockRepresentation = 'Observation 1\nObservation 2\nConclusion 1'; - mockClient.workspaces.peers.getRepresentation.mockResolvedValue({ + mockClient.workspaces.peers.representation.mockResolvedValue({ representation: mockRepresentation, }); @@ -567,7 +567,7 @@ describe('Peer', () => { expect(result).toBe(mockRepresentation); expect( - mockClient.workspaces.peers.getRepresentation + mockClient.workspaces.peers.representation ).toHaveBeenCalledWith('test-workspace', 'test-peer', { session_id: undefined, target: undefined, @@ -581,7 +581,7 @@ describe('Peer', () => { it('should get working representation with session as string', async () => { const mockRepresentation = 'Session-scoped observation'; - mockClient.workspaces.peers.getRepresentation.mockResolvedValue({ + mockClient.workspaces.peers.representation.mockResolvedValue({ representation: mockRepresentation, }); @@ -589,7 +589,7 @@ describe('Peer', () => { expect(result).toBe(mockRepresentation); expect( - mockClient.workspaces.peers.getRepresentation + mockClient.workspaces.peers.representation ).toHaveBeenCalledWith('test-workspace', 'test-peer', { session_id: 'session-123', target: undefined, @@ -604,7 +604,7 @@ describe('Peer', () => { it('should get working representation with session as Session object', async () => { const session = new Session('session-123', 'test-workspace', mockClient); const mockRepresentation = 'Session object observation'; - mockClient.workspaces.peers.getRepresentation.mockResolvedValue({ + mockClient.workspaces.peers.representation.mockResolvedValue({ representation: mockRepresentation, }); @@ -612,7 +612,7 @@ describe('Peer', () => { expect(result).toBe(mockRepresentation); expect( - mockClient.workspaces.peers.getRepresentation + mockClient.workspaces.peers.representation ).toHaveBeenCalledWith('test-workspace', 'test-peer', { session_id: 'session-123', target: undefined, @@ -626,7 +626,7 @@ describe('Peer', () => { it('should get working representation with target as string', async () => { const mockRepresentation = "Observer's view of target"; - mockClient.workspaces.peers.getRepresentation.mockResolvedValue({ + mockClient.workspaces.peers.representation.mockResolvedValue({ representation: mockRepresentation, }); @@ -634,7 +634,7 @@ describe('Peer', () => { expect(result).toBe(mockRepresentation); expect( - mockClient.workspaces.peers.getRepresentation + mockClient.workspaces.peers.representation ).toHaveBeenCalledWith('test-workspace', 'test-peer', { session_id: undefined, target: 'target-peer', @@ -649,7 +649,7 @@ describe('Peer', () => { it('should get working representation with target as Peer object', async () => { const targetPeer = new Peer('target-peer', 'test-workspace', mockClient); const mockRepresentation = "Observer's view of target peer object"; - mockClient.workspaces.peers.getRepresentation.mockResolvedValue({ + mockClient.workspaces.peers.representation.mockResolvedValue({ representation: mockRepresentation, }); @@ -657,7 +657,7 @@ describe('Peer', () => { expect(result).toBe(mockRepresentation); expect( - mockClient.workspaces.peers.getRepresentation + mockClient.workspaces.peers.representation ).toHaveBeenCalledWith('test-workspace', 'test-peer', { session_id: undefined, target: 'target-peer', @@ -671,7 +671,7 @@ describe('Peer', () => { it('should get working representation with search query', async () => { const mockRepresentation = 'Query-curated observation'; - mockClient.workspaces.peers.getRepresentation.mockResolvedValue({ + mockClient.workspaces.peers.representation.mockResolvedValue({ representation: mockRepresentation, }); @@ -683,7 +683,7 @@ describe('Peer', () => { expect(result).toBe(mockRepresentation); expect( - mockClient.workspaces.peers.getRepresentation + mockClient.workspaces.peers.representation ).toHaveBeenCalledWith('test-workspace', 'test-peer', { session_id: undefined, target: undefined, @@ -697,7 +697,7 @@ describe('Peer', () => { it('should get working representation with custom size', async () => { const mockRepresentation = 'Limited observations'; - mockClient.workspaces.peers.getRepresentation.mockResolvedValue({ + mockClient.workspaces.peers.representation.mockResolvedValue({ representation: mockRepresentation, }); @@ -705,7 +705,7 @@ describe('Peer', () => { expect(result).toBe(mockRepresentation); expect( - mockClient.workspaces.peers.getRepresentation + mockClient.workspaces.peers.representation ).toHaveBeenCalledWith('test-workspace', 'test-peer', { session_id: undefined, target: undefined, @@ -721,7 +721,7 @@ describe('Peer', () => { const session = new Session('session-123', 'test-workspace', mockClient); const targetPeer = new Peer('target-peer', 'test-workspace', mockClient); const mockRepresentation = 'Fully parameterized observation\nConclusion with all params'; - mockClient.workspaces.peers.getRepresentation.mockResolvedValue({ + mockClient.workspaces.peers.representation.mockResolvedValue({ representation: mockRepresentation, }); @@ -733,7 +733,7 @@ describe('Peer', () => { expect(result).toBe(mockRepresentation); expect( - mockClient.workspaces.peers.getRepresentation + mockClient.workspaces.peers.representation ).toHaveBeenCalledWith('test-workspace', 'test-peer', { session_id: 'session-123', target: 'target-peer', @@ -747,7 +747,7 @@ describe('Peer', () => { it('should get working representation with string session and string target', async () => { const mockRepresentation = 'String params observation'; - mockClient.workspaces.peers.getRepresentation.mockResolvedValue({ + mockClient.workspaces.peers.representation.mockResolvedValue({ representation: mockRepresentation, }); @@ -759,7 +759,7 @@ describe('Peer', () => { expect(result).toBe(mockRepresentation); expect( - mockClient.workspaces.peers.getRepresentation + mockClient.workspaces.peers.representation ).toHaveBeenCalledWith('test-workspace', 'test-peer', { session_id: 'session-456', target: 'target-peer-123', @@ -773,7 +773,7 @@ describe('Peer', () => { it('should handle boundary size values', async () => { const mockRepresentationString = 'Boundary test representation'; - mockClient.workspaces.peers.getRepresentation.mockResolvedValue({ + mockClient.workspaces.peers.representation.mockResolvedValue({ representation: mockRepresentationString, }); @@ -781,7 +781,7 @@ describe('Peer', () => { const result1 = await peer.getRepresentation(undefined, undefined, { maxConclusions: 1 }); expect(result1).toBe(mockRepresentationString); expect( - mockClient.workspaces.peers.getRepresentation + mockClient.workspaces.peers.representation ).toHaveBeenLastCalledWith('test-workspace', 'test-peer', { session_id: undefined, target: undefined, @@ -796,7 +796,7 @@ describe('Peer', () => { const result2 = await peer.getRepresentation(undefined, undefined, { maxConclusions: 100 }); expect(result2).toBe(mockRepresentationString); expect( - mockClient.workspaces.peers.getRepresentation + mockClient.workspaces.peers.representation ).toHaveBeenLastCalledWith('test-workspace', 'test-peer', { session_id: undefined, target: undefined, @@ -809,7 +809,7 @@ describe('Peer', () => { }); it('should handle API errors', async () => { - mockClient.workspaces.peers.getRepresentation.mockRejectedValue( + mockClient.workspaces.peers.representation.mockRejectedValue( new Error('Working representation fetch failed') ); diff --git a/sdks/typescript/__tests__/session.test.ts b/sdks/typescript/__tests__/session.test.ts index 0012b564..409cfbee 100644 --- a/sdks/typescript/__tests__/session.test.ts +++ b/sdks/typescript/__tests__/session.test.ts @@ -14,7 +14,7 @@ jest.mock('@honcho-ai/core', () => { set: jest.fn(), remove: jest.fn(), list: jest.fn(), - getConfig: jest.fn(), + config: jest.fn(), setConfig: jest.fn(), }, messages: { @@ -26,14 +26,14 @@ jest.mock('@honcho-ai/core', () => { update: jest.fn(), delete: jest.fn(), clone: jest.fn(), - getContext: jest.fn(), + context: jest.fn(), search: jest.fn(), }, peers: { - getRepresentation: jest.fn(), + representation: jest.fn(), }, queue: { - getStatus: jest.fn(), + status: jest.fn(), }, getOrCreate: jest.fn(), update: jest.fn(), @@ -333,7 +333,7 @@ describe('Session', () => { describe('getPeerConfig', () => { it('should return peer configuration', async () => { const mockConfig = { observe_me: true, observe_others: false } - mockClient.workspaces.sessions.peers.getConfig.mockResolvedValue( + mockClient.workspaces.sessions.peers.config.mockResolvedValue( mockConfig ) @@ -341,14 +341,14 @@ describe('Session', () => { expect(config).toEqual(mockConfig) expect( - mockClient.workspaces.sessions.peers.getConfig + mockClient.workspaces.sessions.peers.config ).toHaveBeenCalledWith('test-workspace', 'test-session', 'peer1') }) it('should handle Peer object input', async () => { const peer = new Peer('peer1', 'test-workspace', mockClient) const mockConfig = { observe_me: false, observe_others: true } - mockClient.workspaces.sessions.peers.getConfig.mockResolvedValue( + mockClient.workspaces.sessions.peers.config.mockResolvedValue( mockConfig ) @@ -356,7 +356,7 @@ describe('Session', () => { expect(config).toEqual(mockConfig) expect( - mockClient.workspaces.sessions.peers.getConfig + mockClient.workspaces.sessions.peers.config ).toHaveBeenCalledWith('test-workspace', 'test-session', 'peer1') }) }) @@ -775,7 +775,7 @@ describe('Session', () => { token_count: 100, }, } - mockClient.workspaces.sessions.getContext.mockResolvedValue(mockContext) + mockClient.workspaces.sessions.context.mockResolvedValue(mockContext) const context = await session.getContext() @@ -783,7 +783,7 @@ describe('Session', () => { expect(context.sessionId).toBe('test-session') expect(context.messages).toEqual(mockContext.messages) expect(context.summary?.content).toBe('Conversation summary') - expect(mockClient.workspaces.sessions.getContext).toHaveBeenCalledWith( + expect(mockClient.workspaces.sessions.context).toHaveBeenCalledWith( 'test-workspace', 'test-session', { tokens: undefined, summary: undefined } @@ -801,12 +801,12 @@ describe('Session', () => { token_count: 50, }, } - mockClient.workspaces.sessions.getContext.mockResolvedValue(mockContext) + mockClient.workspaces.sessions.context.mockResolvedValue(mockContext) const context = await session.getContext({ summary: true, tokens: 1000 }) expect(context).toBeInstanceOf(SessionContext) - expect(mockClient.workspaces.sessions.getContext).toHaveBeenCalledWith( + expect(mockClient.workspaces.sessions.context).toHaveBeenCalledWith( 'test-workspace', 'test-session', { tokens: 1000, summary: true } @@ -817,7 +817,7 @@ describe('Session', () => { const mockContext = { messages: [{ id: 'msg1', content: 'Hello', peer_id: 'peer1' }], } - mockClient.workspaces.sessions.getContext.mockResolvedValue(mockContext) + mockClient.workspaces.sessions.context.mockResolvedValue(mockContext) const context = await session.getContext() @@ -825,7 +825,7 @@ describe('Session', () => { }) it('should handle API errors', async () => { - mockClient.workspaces.sessions.getContext.mockRejectedValue( + mockClient.workspaces.sessions.context.mockRejectedValue( new Error('Failed to get context') ) @@ -907,7 +907,7 @@ describe('Session', () => { describe('getRepresentation', () => { it('should get working representation with peer string', async () => { const mockRepresentationString = 'Some knowledge about the peer' - mockClient.workspaces.peers.getRepresentation.mockResolvedValue({ + mockClient.workspaces.peers.representation.mockResolvedValue({ representation: mockRepresentationString, }) @@ -916,7 +916,7 @@ describe('Session', () => { expect(typeof result).toBe('string') expect(result).toBe(mockRepresentationString) expect( - mockClient.workspaces.peers.getRepresentation + mockClient.workspaces.peers.representation ).toHaveBeenCalledWith('test-workspace', 'peer1', { session_id: 'test-session', target: undefined, @@ -931,7 +931,7 @@ describe('Session', () => { it('should get working representation with Peer object', async () => { const peer = new Peer('peer1', 'test-workspace', mockClient) const mockRepresentationString = 'Some knowledge' - mockClient.workspaces.peers.getRepresentation.mockResolvedValue({ + mockClient.workspaces.peers.representation.mockResolvedValue({ representation: mockRepresentationString, }) @@ -940,7 +940,7 @@ describe('Session', () => { expect(typeof result).toBe('string') expect(result).toBe(mockRepresentationString) expect( - mockClient.workspaces.peers.getRepresentation + mockClient.workspaces.peers.representation ).toHaveBeenCalledWith('test-workspace', 'peer1', { session_id: 'test-session', target: undefined, @@ -954,7 +954,7 @@ describe('Session', () => { it('should get working representation with target peer string', async () => { const mockRepresentationString = 'What peer1 knows about target' - mockClient.workspaces.peers.getRepresentation.mockResolvedValue({ + mockClient.workspaces.peers.representation.mockResolvedValue({ representation: mockRepresentationString, }) @@ -963,7 +963,7 @@ describe('Session', () => { expect(typeof result).toBe('string') expect(result).toBe(mockRepresentationString) expect( - mockClient.workspaces.peers.getRepresentation + mockClient.workspaces.peers.representation ).toHaveBeenCalledWith('test-workspace', 'peer1', { session_id: 'test-session', target: 'target-peer', @@ -979,7 +979,7 @@ describe('Session', () => { const peer = new Peer('peer1', 'test-workspace', mockClient) const target = new Peer('target-peer', 'test-workspace', mockClient) const mockRepresentationString = 'What peer1 knows about target' - mockClient.workspaces.peers.getRepresentation.mockResolvedValue({ + mockClient.workspaces.peers.representation.mockResolvedValue({ representation: mockRepresentationString, }) @@ -988,7 +988,7 @@ describe('Session', () => { expect(typeof result).toBe('string') expect(result).toBe(mockRepresentationString) expect( - mockClient.workspaces.peers.getRepresentation + mockClient.workspaces.peers.representation ).toHaveBeenCalledWith('test-workspace', 'peer1', { session_id: 'test-session', target: 'target-peer', @@ -1001,7 +1001,7 @@ describe('Session', () => { }) it('should handle API errors', async () => { - mockClient.workspaces.peers.getRepresentation.mockRejectedValue( + mockClient.workspaces.peers.representation.mockRejectedValue( new Error('Failed to get working representation') ) @@ -1106,7 +1106,7 @@ describe('Session', () => { pending_work_units: 2, sessions: { session1: { status: 'active' } }, } - mockClient.workspaces.queue.getStatus.mockResolvedValue(mockStatus) + mockClient.workspaces.queue.status.mockResolvedValue(mockStatus) const status = await session.getQueueStatus() @@ -1117,7 +1117,7 @@ describe('Session', () => { pendingWorkUnits: 2, sessions: { session1: { status: 'active' } }, }) - expect(mockClient.workspaces.queue.getStatus).toHaveBeenCalledWith( + expect(mockClient.workspaces.queue.status).toHaveBeenCalledWith( 'test-workspace', { session_id: 'test-session' } ) @@ -1130,7 +1130,7 @@ describe('Session', () => { in_progress_work_units: 1, pending_work_units: 1, } - mockClient.workspaces.queue.getStatus.mockResolvedValue(mockStatus) + mockClient.workspaces.queue.status.mockResolvedValue(mockStatus) const status = await session.getQueueStatus({ observer: 'observer1', @@ -1144,7 +1144,7 @@ describe('Session', () => { pendingWorkUnits: 1, sessions: undefined, }) - expect(mockClient.workspaces.queue.getStatus).toHaveBeenCalledWith( + expect(mockClient.workspaces.queue.status).toHaveBeenCalledWith( 'test-workspace', { observer_id: 'observer1', @@ -1162,7 +1162,7 @@ describe('Session', () => { in_progress_work_units: 0, pending_work_units: 0, } - mockClient.workspaces.queue.getStatus.mockResolvedValue( + mockClient.workspaces.queue.status.mockResolvedValue( mockStatusComplete ) @@ -1176,7 +1176,7 @@ describe('Session', () => { sessions: undefined, }) - expect(mockClient.workspaces.queue.getStatus).toHaveBeenCalledWith( + expect(mockClient.workspaces.queue.status).toHaveBeenCalledWith( 'test-workspace', { session_id: 'test-session' } ) @@ -1189,7 +1189,7 @@ describe('Session', () => { in_progress_work_units: 2, pending_work_units: 1, } - mockClient.workspaces.queue.getStatus.mockResolvedValue(mockStatusPending) + mockClient.workspaces.queue.status.mockResolvedValue(mockStatusPending) await expect( session.pollQueueStatus({ timeoutMs: 100 }) diff --git a/sdks/typescript/bun.lock b/sdks/typescript/bun.lock index 321d3c70..b9152434 100644 --- a/sdks/typescript/bun.lock +++ b/sdks/typescript/bun.lock @@ -4,7 +4,7 @@ "": { "name": "@honcho-ai/sdk", "dependencies": { - "@honcho-ai/core": "https://pkg.stainless.com/s/honcho-node/dc4ac0ffd48642608da2f99f306f77f7ee5a9d1d/dist.tar.gz", + "@honcho-ai/core": "2.0.0", "@types/node": "^24.0.1", "zod": "4.0.0", }, @@ -106,7 +106,7 @@ "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.3.8", "", { "os": "win32", "cpu": "x64" }, "sha512-RguzimPoZWtBapfKhKjcWXBVI91tiSprqdBYu7tWhgN8pKRZhw24rFeNZTNf6UiBfjCYCi9eFQs/JzJZIhuK4w=="], - "@honcho-ai/core": ["@honcho-ai/core@https://pkg.stainless.com/s/honcho-node/dc4ac0ffd48642608da2f99f306f77f7ee5a9d1d/dist.tar.gz", { "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", "abort-controller": "^3.0.0", "agentkeepalive": "^4.2.1", "form-data-encoder": "1.7.2", "formdata-node": "^4.3.2", "node-fetch": "^2.6.7" } }], + "@honcho-ai/core": ["@honcho-ai/core@2.0.0", "", { "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", "abort-controller": "^3.0.0", "agentkeepalive": "^4.2.1", "form-data-encoder": "1.7.2", "formdata-node": "^4.3.2", "node-fetch": "^2.6.7" } }, "sha512-2VVtVuyRtFzHvEca74PBrio5ee97P3rl2q68WkGT++8TL+a3SmFPTxjezxCvGgOForvUVZJu4I/7MkmpqwE+Fg=="], "@istanbuljs/load-nyc-config": ["@istanbuljs/load-nyc-config@1.1.0", "", { "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", "get-package-type": "^0.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" } }, "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ=="], diff --git a/sdks/typescript/package.json b/sdks/typescript/package.json index 2975123f..52def930 100644 --- a/sdks/typescript/package.json +++ b/sdks/typescript/package.json @@ -20,7 +20,7 @@ "test:coverage": "jest --coverage" }, "dependencies": { - "@honcho-ai/core": "https://pkg.stainless.com/s/honcho-node/dc4ac0ffd48642608da2f99f306f77f7ee5a9d1d/dist.tar.gz", + "@honcho-ai/core": "2.0.0", "@types/node": "^24.0.1", "zod": "4.0.0" }, diff --git a/sdks/typescript/src/client.ts b/sdks/typescript/src/client.ts index 7d5d0383..9485e202 100644 --- a/sdks/typescript/src/client.ts +++ b/sdks/typescript/src/client.ts @@ -1,8 +1,8 @@ import HonchoCore from '@honcho-ai/core' import type { DefaultQuery } from '@honcho-ai/core/core' import type { - QueueGetStatusParams, - QueueGetStatusResponse, + QueueStatusParams, + QueueStatusResponse, } from '@honcho-ai/core/resources/workspaces/queue' import type { Message } from '@honcho-ai/core/resources/workspaces/sessions/messages' import { Page } from './pagination' @@ -504,7 +504,7 @@ export class Honcho { completedWorkUnits: number inProgressWorkUnits: number pendingWorkUnits: number - sessions?: Record + sessions?: Record }> { const resolvedObserverId = options?.observer ? typeof options.observer === 'string' @@ -522,12 +522,12 @@ export class Honcho { : options.session.id : undefined - const queryParams: QueueGetStatusParams = {} + const queryParams: QueueStatusParams = {} if (resolvedObserverId) queryParams.observer_id = resolvedObserverId if (resolvedSenderId) queryParams.sender_id = resolvedSenderId if (resolvedSessionId) queryParams.session_id = resolvedSessionId - const status = await this._client.workspaces.queue.getStatus( + const status = await this._client.workspaces.queue.status( this.workspaceId, queryParams ) @@ -570,7 +570,7 @@ export class Honcho { completedWorkUnits: number inProgressWorkUnits: number pendingWorkUnits: number - sessions?: Record + sessions?: Record }> { const timeoutMs = options?.timeoutMs ?? 300000 // Default to 5 minutes const startTime = Date.now() diff --git a/sdks/typescript/src/conclusions.ts b/sdks/typescript/src/conclusions.ts index 9476d390..e53217c5 100644 --- a/sdks/typescript/src/conclusions.ts +++ b/sdks/typescript/src/conclusions.ts @@ -300,7 +300,7 @@ export class ConclusionScope { * @returns Promise resolving to a string of the representation */ async getRepresentation(options?: RepresentationOptions): Promise { - const response = await this._client.workspaces.peers.getRepresentation( + const response = await this._client.workspaces.peers.representation( this.workspaceId, this.observer, { diff --git a/sdks/typescript/src/peer.ts b/sdks/typescript/src/peer.ts index 2996fa6a..fd9b69d1 100644 --- a/sdks/typescript/src/peer.ts +++ b/sdks/typescript/src/peer.ts @@ -535,7 +535,7 @@ export class Peer { : getRepresentationParams.target.id : undefined - const response = await this._client.workspaces.peers.getRepresentation( + const response = await this._client.workspaces.peers.representation( this.workspaceId, this.id, { @@ -590,7 +590,7 @@ export class Peer { : target.id : undefined - const response = await this._client.workspaces.peers.getContext( + const response = await this._client.workspaces.peers.context( this.workspaceId, this.id, { diff --git a/sdks/typescript/src/session.ts b/sdks/typescript/src/session.ts index 877f3f26..4105ee41 100644 --- a/sdks/typescript/src/session.ts +++ b/sdks/typescript/src/session.ts @@ -1,7 +1,7 @@ import type HonchoCore from '@honcho-ai/core' import type { - QueueGetStatusParams, - QueueGetStatusResponse, + QueueStatusParams, + QueueStatusResponse, } from '@honcho-ai/core/resources/workspaces/queue' import type { Message } from '@honcho-ai/core/resources/workspaces/sessions/messages' import type { Uploadable } from '@honcho-ai/core/uploads' @@ -337,7 +337,7 @@ export class Session { */ async getPeerConfig(peer: string | Peer): Promise { const peerId = typeof peer === 'string' ? peer : peer.id - return await this._client.workspaces.sessions.peers.getConfig( + return await this._client.workspaces.sessions.peers.config( this.workspaceId, this.id, peerId @@ -700,7 +700,7 @@ export class Session { ? contextParams.lastUserMessage : contextParams.lastUserMessage?.id - const context = await this._client.workspaces.sessions.getContext( + const context = await this._client.workspaces.sessions.context( this.workspaceId, this.id, { @@ -820,7 +820,7 @@ export class Session { completedWorkUnits: number inProgressWorkUnits: number pendingWorkUnits: number - sessions?: Record + sessions?: Record }> { const resolvedObserverId = options?.observer ? typeof options.observer === 'string' @@ -833,13 +833,13 @@ export class Session { : options.sender.id : undefined - const queryParams: QueueGetStatusParams = { + const queryParams: QueueStatusParams = { session_id: this.id, // Always use this session's ID } if (resolvedObserverId) queryParams.observer_id = resolvedObserverId if (resolvedSenderId) queryParams.sender_id = resolvedSenderId - const status = await this._client.workspaces.queue.getStatus( + const status = await this._client.workspaces.queue.status( this.workspaceId, queryParams ) @@ -880,7 +880,7 @@ export class Session { completedWorkUnits: number inProgressWorkUnits: number pendingWorkUnits: number - sessions?: Record + sessions?: Record }> { const timeoutMs = options?.timeoutMs ?? 300000 // Default to 5 minutes const startTime = Date.now() @@ -1057,7 +1057,7 @@ export class Session { : getRepresentationParams.target.id : undefined - const response = await this._client.workspaces.peers.getRepresentation( + const response = await this._client.workspaces.peers.representation( this.workspaceId, peerId, { diff --git a/src/config.py b/src/config.py index be67fd13..91ff1636 100644 --- a/src/config.py +++ b/src/config.py @@ -252,7 +252,7 @@ class DeriverSettings(BackupLLMSettingsMixin, HonchoSettings): # Whether to deduplicate documents when creating them DEDUPLICATE: bool = True - MAX_OUTPUT_TOKENS: Annotated[int, Field(default=10_000, gt=0, le=100_000)] = 4096 + MAX_OUTPUT_TOKENS: Annotated[int, Field(default=4096, gt=0, le=100_000)] = 4096 THINKING_BUDGET_TOKENS: Annotated[int, Field(default=1024, gt=0, le=5000)] = 1024 LOG_OBSERVATIONS: bool = False diff --git a/src/utils/agent_tools.py b/src/utils/agent_tools.py index 8b251b34..c07eced9 100644 --- a/src/utils/agent_tools.py +++ b/src/utils/agent_tools.py @@ -86,7 +86,7 @@ def _extract_pattern_snippet( if len(content) <= max_chars: return content - match = re.search(pattern, content, re.IGNORECASE) + match = re.search(re.escape(pattern), content, re.IGNORECASE) if not match: # No match, return beginning return content[:max_chars] + "..." @@ -1086,7 +1086,7 @@ async def _handle_get_observation_context( async def _handle_search_messages(ctx: ToolContext, tool_input: dict[str, Any]) -> str: """Handle search_messages tool.""" query = tool_input["query"] - limit = min(tool_input.get("limit", 10), 10) # Cap at 10 + limit = min(tool_input.get("limit", 10), 20) # Cap at 20 snippets = await crud.search_messages( ctx.db, workspace_name=ctx.workspace_name, @@ -1106,7 +1106,7 @@ async def _handle_grep_messages(ctx: ToolContext, tool_input: dict[str, Any]) -> text = tool_input.get("text", "") if not text: return "ERROR: 'text' parameter is required" - limit = min(tool_input.get("limit", 10), 15) # Cap at 15 + limit = min(tool_input.get("limit", 10), 30) # Cap at 30 context_window = min(tool_input.get("context_window", 2), 2) # Cap context snippets = await crud.grep_messages( diff --git a/src/utils/config_helpers.py b/src/utils/config_helpers.py index bf17902d..bb76bc9d 100644 --- a/src/utils/config_helpers.py +++ b/src/utils/config_helpers.py @@ -47,23 +47,28 @@ def normalize_configuration_dict(raw: dict[str, Any]) -> dict[str, Any]: normalized: dict[str, Any] = dict(raw) reasoning_raw = normalized.get("reasoning") - reasoning: dict[str, Any] = ( - cast(dict[str, Any], reasoning_raw) if isinstance(reasoning_raw, dict) else {} - ) + reasoning_present = "reasoning" in normalized + reasoning: dict[str, Any] + if isinstance(reasoning_raw, dict): + reasoning = dict(cast(dict[str, Any], reasoning_raw)) + else: + reasoning = {} reasoning_enabled_explicit = reasoning.get("enabled") is not None if not reasoning_enabled_explicit: deriver_raw = normalized.get("deriver") - deriver = ( - cast(dict[str, Any], deriver_raw) if isinstance(deriver_raw, dict) else {} - ) + deriver: dict[str, Any] + if isinstance(deriver_raw, dict): + deriver = dict(cast(dict[str, Any], deriver_raw)) + else: + deriver = {} if deriver.get("enabled") is not None: reasoning["enabled"] = bool(deriver["enabled"]) if not reasoning_enabled_explicit and normalized.get("skip_deriver") is True: reasoning["enabled"] = False - if reasoning: + if reasoning_present or reasoning: normalized["reasoning"] = reasoning normalized.pop("deriver", None) diff --git a/tests/sdk/test_client.py b/tests/sdk/test_client.py index 32fede70..1b247d9f 100644 --- a/tests/sdk/test_client.py +++ b/tests/sdk/test_client.py @@ -2,7 +2,7 @@ from unittest.mock import patch import pytest from fastapi.testclient import TestClient -from honcho_core.types.workspaces import QueueGetStatusResponse +from honcho_core.types.workspaces import QueueStatusResponse from honcho_core.types.workspaces.sessions.message import Message from sdks.python.src.honcho.async_client.client import AsyncHoncho @@ -201,7 +201,7 @@ async def test_get_deriver_status(client_fixture: tuple[Honcho | AsyncHoncho, st assert isinstance(honcho_client, AsyncHoncho) # Test with no parameters - this should work in the SDK even though API requires at least one status = await honcho_client.get_queue_status() - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) assert hasattr(status, "total_work_units") assert hasattr(status, "completed_work_units") assert hasattr(status, "in_progress_work_units") @@ -211,28 +211,28 @@ async def test_get_deriver_status(client_fixture: tuple[Honcho | AsyncHoncho, st peer = await honcho_client.peer(id="test-peer-deriver-status") await peer.get_metadata() # Create the peer status = await honcho_client.get_queue_status(observer=peer.id) - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) # Test with session_id only session = await honcho_client.session(id="test-session-deriver-status") await session.get_metadata() # Create the session status = await honcho_client.get_queue_status(session=session.id) - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) # Test with both peer and session status = await honcho_client.get_queue_status( observer=peer.id, session=session.id ) - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) # Test with sender status = await honcho_client.get_queue_status(observer=peer.id, sender=peer.id) - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) else: assert isinstance(honcho_client, Honcho) # Test with no parameters status = honcho_client.get_queue_status() - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) assert hasattr(status, "total_work_units") assert hasattr(status, "completed_work_units") assert hasattr(status, "in_progress_work_units") @@ -242,21 +242,21 @@ async def test_get_deriver_status(client_fixture: tuple[Honcho | AsyncHoncho, st peer = honcho_client.peer(id="test-peer-queue-status") peer.get_metadata() # Create the peer status = honcho_client.get_queue_status(observer=peer.id) - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) # Test with session_id only session = honcho_client.session(id="test-session-queue-status") session.get_metadata() # Create the session status = honcho_client.get_queue_status(session=session.id) - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) # Test with both peer and session status = honcho_client.get_queue_status(observer=peer.id, session=session.id) - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) # Test with sender status = honcho_client.get_queue_status(observer=peer.id, sender=peer.id) - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) @pytest.mark.asyncio @@ -268,7 +268,7 @@ async def test_poll_queue_status(client_fixture: tuple[Honcho | AsyncHoncho, str # Mock the get_queue_status method to return a "completed" status # to avoid infinite polling in tests - completed_status = QueueGetStatusResponse( + completed_status = QueueStatusResponse( total_work_units=0, completed_work_units=0, in_progress_work_units=0, @@ -281,7 +281,7 @@ async def test_poll_queue_status(client_fixture: tuple[Honcho | AsyncHoncho, str honcho_client, "get_queue_status", return_value=completed_status ): status = await honcho_client.poll_queue_status() - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) assert status.pending_work_units == 0 assert status.in_progress_work_units == 0 @@ -293,14 +293,14 @@ async def test_poll_queue_status(client_fixture: tuple[Honcho | AsyncHoncho, str status = await honcho_client.poll_queue_status( observer=peer.id, sender=peer.id ) - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) else: assert isinstance(honcho_client, Honcho) with patch.object( honcho_client, "get_queue_status", return_value=completed_status ): status = honcho_client.poll_queue_status() - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) assert status.pending_work_units == 0 assert status.in_progress_work_units == 0 @@ -310,7 +310,7 @@ async def test_poll_queue_status(client_fixture: tuple[Honcho | AsyncHoncho, str honcho_client, "get_queue_status", return_value=completed_status ): status = honcho_client.poll_queue_status(observer=peer.id, sender=peer.id) - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) @pytest.mark.asyncio diff --git a/tests/sdk/test_session.py b/tests/sdk/test_session.py index 2368c1dc..beed854c 100644 --- a/tests/sdk/test_session.py +++ b/tests/sdk/test_session.py @@ -1,7 +1,7 @@ from unittest.mock import AsyncMock, patch import pytest -from honcho_core.types.workspaces import QueueGetStatusResponse +from honcho_core.types.workspaces import QueueStatusResponse from sdks.python.src.honcho.async_client.client import AsyncHoncho from sdks.python.src.honcho.async_client.peer import AsyncPeer @@ -465,7 +465,7 @@ async def test_session_get_queue_status( assert isinstance(session, AsyncSession) status = await session.get_queue_status() - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) assert hasattr(status, "total_work_units") assert hasattr(status, "completed_work_units") assert hasattr(status, "in_progress_work_units") @@ -476,15 +476,15 @@ async def test_session_get_queue_status( peer = await honcho_client.peer(id="test-peer-session-deriver") await peer.get_metadata() # Create the peer status = await session.get_queue_status(observer=peer.id) - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) # Test with sender only status = await session.get_queue_status(sender=peer.id) - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) # Test with both observer and sender status = await session.get_queue_status(observer=peer.id, sender=peer.id) - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) else: assert isinstance(honcho_client, Honcho) session = honcho_client.session(id="test-session-deriver-status") @@ -492,7 +492,7 @@ async def test_session_get_queue_status( # Test with no parameters status = session.get_queue_status() - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) assert hasattr(status, "total_work_units") assert hasattr(status, "completed_work_units") assert hasattr(status, "in_progress_work_units") @@ -503,15 +503,15 @@ async def test_session_get_queue_status( peer = honcho_client.peer(id="test-peer-session-deriver") peer.get_metadata() # Create the peer status = session.get_queue_status(observer=peer.id) - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) # Test with sender only status = session.get_queue_status(sender=peer.id) - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) # Test with both observer and sender status = session.get_queue_status(observer=peer.id, sender=peer.id) - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) @pytest.mark.asyncio @@ -525,7 +525,7 @@ async def test_session_poll_queue_status( # Mock the get_queue_status method to return a "completed" status # to avoid infinite polling in tests - completed_status = QueueGetStatusResponse( + completed_status = QueueStatusResponse( total_work_units=0, completed_work_units=0, in_progress_work_units=0, @@ -543,7 +543,7 @@ async def test_session_poll_queue_status( new=AsyncMock(return_value=completed_status), ): status = await session.poll_queue_status() - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) assert status.pending_work_units == 0 assert status.in_progress_work_units == 0 @@ -555,7 +555,7 @@ async def test_session_poll_queue_status( new=AsyncMock(return_value=completed_status), ): status = await session.poll_queue_status(observer=peer.id, sender=peer.id) - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) else: assert isinstance(honcho_client, Honcho) session = honcho_client.session(id="test-session-poll-queue") @@ -565,7 +565,7 @@ async def test_session_poll_queue_status( session.__class__, "get_queue_status", return_value=completed_status ): status = session.poll_queue_status() - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) assert status.pending_work_units == 0 assert status.in_progress_work_units == 0 @@ -575,7 +575,7 @@ async def test_session_poll_queue_status( session.__class__, "get_queue_status", return_value=completed_status ): status = session.poll_queue_status(observer=peer.id, sender=peer.id) - assert isinstance(status, QueueGetStatusResponse) + assert isinstance(status, QueueStatusResponse) @pytest.mark.asyncio diff --git a/tests/unified/runner.py b/tests/unified/runner.py index 927d4b23..c146d29b 100644 --- a/tests/unified/runner.py +++ b/tests/unified/runner.py @@ -13,7 +13,7 @@ import httpx from anthropic import AsyncAnthropic from honcho.async_client.session import AsyncSession from honcho.session_context import SessionContext -from honcho_core.types.workspaces import QueueGetStatusResponse +from honcho_core.types.workspaces import QueueStatusResponse from pydantic import ValidationError # Adjust path to allow imports from tests.bench @@ -292,7 +292,7 @@ class UnifiedTestExecutor: await asyncio.sleep(1) start = time.time() while time.time() - start < timeout: - status: QueueGetStatusResponse = await self.client.get_queue_status() + status: QueueStatusResponse = await self.client.get_queue_status() # status structure from schema: DeriverStatus with pending_work_units, in_progress_work_units if status.pending_work_units == 0 and status.in_progress_work_units == 0: return diff --git a/uv.lock b/uv.lock index 4087cebf..d126d9cb 100644 --- a/uv.lock +++ b/uv.lock @@ -859,7 +859,7 @@ dev = [ [package.metadata] requires-dist = [ - { name = "honcho-core", url = "https://pkg.stainless.com/s/honcho-python/b5539818022ab4ad757250ea3234648f8dc5906e/honcho_core-1.8.0-py3-none-any.whl" }, + { name = "honcho-core", specifier = "==1.9.0" }, { name = "httpx", specifier = ">=0.28.0,<1" }, { name = "pydantic", specifier = ">=2.0.0,<3" }, { name = "typing-extensions", marker = "python_full_version < '3.12'", specifier = ">=4.12.0" }, @@ -870,8 +870,8 @@ dev = [{ name = "ruff", specifier = ">=0.11.13" }] [[package]] name = "honcho-core" -version = "1.8.0" -source = { url = "https://pkg.stainless.com/s/honcho-python/b5539818022ab4ad757250ea3234648f8dc5906e/honcho_core-1.8.0-py3-none-any.whl" } +version = "1.9.0" +source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, { name = "distro" }, @@ -880,23 +880,11 @@ dependencies = [ { name = "sniffio" }, { name = "typing-extensions" }, ] +sdist = { url = "https://files.pythonhosted.org/packages/e0/be/4496fa3deb447e958d06490e6a18ae173c8ddb427a86a60a2bcaa9bba649/honcho_core-1.9.0.tar.gz", hash = "sha256:baaa61be3826e9fd3489037a5606c6d87e6ff6ac0c2d17139ed2153691f9bae8", size = 144184, upload-time = "2026-01-12T22:11:27.159Z" } wheels = [ - { url = "https://pkg.stainless.com/s/honcho-python/b5539818022ab4ad757250ea3234648f8dc5906e/honcho_core-1.8.0-py3-none-any.whl", hash = "sha256:2684c2dbd4d6479c381028038500b9972bbf3c66cf3f37c404f8cbe4cecfba01" }, + { url = "https://files.pythonhosted.org/packages/d1/64/99a96c61e15e6aaa696ea67a752bdcda0472712de2d5f5a0f827f0de22d9/honcho_core-1.9.0-py3-none-any.whl", hash = "sha256:b80f1215b5f9f5e134421b7243865eea6620e66fbe39629e3d59cc688031cf90", size = 138655, upload-time = "2026-01-12T22:11:26.204Z" }, ] -[package.metadata] -requires-dist = [ - { name = "aiohttp", marker = "extra == 'aiohttp'" }, - { name = "anyio", specifier = ">=3.5.0,<5" }, - { name = "distro", specifier = ">=1.7.0,<2" }, - { name = "httpx", specifier = ">=0.23.0,<1" }, - { name = "httpx-aiohttp", marker = "extra == 'aiohttp'", specifier = ">=0.1.9" }, - { name = "pydantic", specifier = ">=1.9.0,<3" }, - { name = "sniffio" }, - { name = "typing-extensions", specifier = ">=4.10,<5" }, -] -provides-extras = ["aiohttp"] - [[package]] name = "httpcore" version = "1.0.9"