feat: add set peer card to SDK, bump version, document
This commit is contained in:
parent
e93e57175e
commit
f531c3f095
|
|
@ -4,27 +4,23 @@ description: "Compatibility guide for Honcho's SDKs and API"
|
|||
icon: "shield-check"
|
||||
---
|
||||
|
||||
This guide helps you understand which versions of Honcho's API are compatible with which SDK versions.
|
||||
This guide helps you match the right SDK version to your Honcho API version. Newer SDK patch versions are always backward-compatible within the same major version — install the latest patch for your range.
|
||||
|
||||
## Version Compatibility
|
||||
|
||||
### Honcho API v3.0.2 (Current)
|
||||
## Current Versions
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="TypeScript SDK" icon="js">
|
||||
**Compatible Version:** v2.0.0
|
||||
**Latest:** v2.0.1
|
||||
|
||||
Install with:
|
||||
```bash
|
||||
npm install @honcho-ai/sdk@2.0.0
|
||||
npm install @honcho-ai/sdk
|
||||
```
|
||||
</Card>
|
||||
<Card title="Python SDK" icon="python">
|
||||
**Compatible Version:** v2.0.0
|
||||
**Latest:** v2.0.1
|
||||
|
||||
Install with:
|
||||
```bash
|
||||
pip install honcho-ai==2.0.0
|
||||
pip install honcho-ai
|
||||
```
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
|
@ -34,9 +30,9 @@ This guide helps you understand which versions of Honcho's API are compatible wi
|
|||
|
||||
| Honcho API Version | TypeScript SDK | Python SDK |
|
||||
|-------------------|---------------|------------|
|
||||
| v3.0.2 (Current) | v2.0.0 | v2.0.0 |
|
||||
| v3.0.1 | v2.0.0 | v2.0.0 |
|
||||
| v3.0.0 | v2.0.0 | v2.0.0 |
|
||||
| v3.0.2 (Current) | v2.0.0+ | v2.0.0+ |
|
||||
| v3.0.1 | v2.0.0+ | v2.0.0+ |
|
||||
| v3.0.0 | v2.0.0+ | v2.0.0+ |
|
||||
| v2.5.1 | v1.6.0 | v1.6.0 |
|
||||
| v2.5.0 | v1.6.0 | v1.6.0 |
|
||||
| v2.4.3 | v1.5.0 | v1.5.0 |
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[project]
|
||||
name = "honcho-ai"
|
||||
version = "2.0.0"
|
||||
version = "2.0.1"
|
||||
description = "Official DX Optimized Python SDK for Honcho"
|
||||
dynamic = ["readme"]
|
||||
license = "Apache-2.0"
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ from .types import (
|
|||
DialecticStreamResponse,
|
||||
)
|
||||
|
||||
__version__ = "2.0.0"
|
||||
__version__ = "2.0.1"
|
||||
__author__ = "Plastic Labs"
|
||||
__email__ = "hello@plasticlabs.ai"
|
||||
|
||||
|
|
|
|||
|
|
@ -604,6 +604,25 @@ class PeerAio(AsyncMetadataConfigMixin):
|
|||
response = PeerCardResponse.model_validate(data)
|
||||
return response.peer_card
|
||||
|
||||
@validate_call(config=ConfigDict(arbitrary_types_allowed=True))
|
||||
async def set_card(
|
||||
self,
|
||||
peer_card: list[str],
|
||||
target: str | PeerBase | None = None,
|
||||
) -> list[str] | None:
|
||||
"""Set the peer card asynchronously."""
|
||||
await self._peer._honcho._ensure_workspace_async()
|
||||
target_id = resolve_id(target)
|
||||
|
||||
query = {"target": target_id} if target_id else None
|
||||
data = await self._peer._honcho._async_http_client.put(
|
||||
routes.peer_card(self._peer.workspace_id, self._peer.id),
|
||||
body={"peer_card": peer_card},
|
||||
query=query,
|
||||
)
|
||||
response = PeerCardResponse.model_validate(data)
|
||||
return response.peer_card
|
||||
|
||||
@validate_call(config=ConfigDict(arbitrary_types_allowed=True))
|
||||
async def representation(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -476,6 +476,38 @@ class Peer(PeerBase, MetadataConfigMixin):
|
|||
|
||||
return response.peer_card
|
||||
|
||||
@validate_call(config=ConfigDict(arbitrary_types_allowed=True))
|
||||
def set_card(
|
||||
self,
|
||||
peer_card: list[str],
|
||||
target: str | PeerBase | None = None,
|
||||
) -> list[str] | None:
|
||||
"""
|
||||
Set the peer card for this peer.
|
||||
|
||||
Makes an API call to set the peer card. If a target is provided, sets this
|
||||
peer's local card of the target peer.
|
||||
|
||||
Args:
|
||||
peer_card: A list of strings to set as the peer card.
|
||||
target: Optional target peer for local card. If provided, sets this
|
||||
peer's card of the target peer. Can be a Peer object or peer ID string.
|
||||
|
||||
Returns:
|
||||
A list of strings representing the updated peer card, or None if none is available
|
||||
"""
|
||||
self._honcho._ensure_workspace()
|
||||
target_id = resolve_id(target)
|
||||
|
||||
query = {"target": target_id} if target_id else None
|
||||
data = self._honcho._http.put(
|
||||
routes.peer_card(self.workspace_id, self.id),
|
||||
body={"peer_card": peer_card},
|
||||
query=query,
|
||||
)
|
||||
response = PeerCardResponse.model_validate(data)
|
||||
return response.peer_card
|
||||
|
||||
@validate_call(config=ConfigDict(arbitrary_types_allowed=True))
|
||||
def representation(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -430,6 +430,48 @@ describe('Peer', () => {
|
|||
})
|
||||
})
|
||||
|
||||
// ===========================================================================
|
||||
// Set Peer Card (PUT /peers/:id/card)
|
||||
// ===========================================================================
|
||||
|
||||
describe('PUT /peers/:id/card', () => {
|
||||
test('setCard sets and returns peer card', async () => {
|
||||
const peer = await client.peer('setcard-peer')
|
||||
|
||||
const cardData = ['fact one', 'fact two']
|
||||
const result = await peer.setCard(cardData)
|
||||
|
||||
expect(result).toEqual(cardData)
|
||||
|
||||
// Verify with get
|
||||
const card = await peer.card()
|
||||
expect(card).toEqual(cardData)
|
||||
})
|
||||
|
||||
test('setCard with target peer', async () => {
|
||||
const observer = await client.peer('setcard-observer')
|
||||
const observed = await client.peer('setcard-observed')
|
||||
|
||||
const cardData = ['target likes TypeScript', 'target is clever']
|
||||
const result = await observer.setCard(cardData, observed)
|
||||
|
||||
expect(result).toEqual(cardData)
|
||||
|
||||
// Verify with get
|
||||
const card = await observer.card(observed)
|
||||
expect(card).toEqual(cardData)
|
||||
})
|
||||
|
||||
test('setCard with target ID string', async () => {
|
||||
const peer = await client.peer('setcard-string-peer')
|
||||
|
||||
const cardData = ['some fact']
|
||||
const result = await peer.setCard(cardData, 'setcard-string-target')
|
||||
|
||||
expect(result).toEqual(cardData)
|
||||
})
|
||||
})
|
||||
|
||||
// ===========================================================================
|
||||
// Peer Context (POST /peers/:id/context)
|
||||
// ===========================================================================
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@honcho-ai/sdk",
|
||||
"version": "2.0.0",
|
||||
"version": "2.0.1",
|
||||
"description": "Official DX Optimized TypeScript SDK for Honcho",
|
||||
"author": "Plastic Labs <hello@plasticlabs.ai>",
|
||||
"license": "Apache-2.0",
|
||||
|
|
|
|||
|
|
@ -295,6 +295,18 @@ export class Peer {
|
|||
)
|
||||
}
|
||||
|
||||
private async _setCard(params: {
|
||||
peer_card: string[]
|
||||
target?: string
|
||||
}): Promise<PeerCardResponse> {
|
||||
await this._ensureWorkspace()
|
||||
const { peer_card, ...query } = params
|
||||
return this._http.put<PeerCardResponse>(
|
||||
`/${API_VERSION}/workspaces/${this.workspaceId}/peers/${this.id}/card`,
|
||||
{ body: { peer_card }, query }
|
||||
)
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// Public Methods
|
||||
// ===========================================================================
|
||||
|
|
@ -662,6 +674,30 @@ export class Peer {
|
|||
return response.peer_card
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the peer card for this peer.
|
||||
*
|
||||
* Makes an API call to set the peer card. If a target is provided, sets this
|
||||
* peer's local card of the target peer.
|
||||
*
|
||||
* @param peerCard - An array of strings to set as the peer card.
|
||||
* @param target - Optional target peer for local card. If provided, sets this
|
||||
* peer's card of the target peer. Can be a Peer object or peer ID string.
|
||||
* @returns Promise resolving to an array of strings containing the updated peer card items,
|
||||
* or null if no peer card exists
|
||||
*/
|
||||
async setCard(
|
||||
peerCard: string[],
|
||||
target?: string | Peer
|
||||
): Promise<string[] | null> {
|
||||
const validatedTarget = CardTargetSchema.parse(target)
|
||||
const response = await this._setCard({
|
||||
peer_card: peerCard,
|
||||
target: validatedTarget,
|
||||
})
|
||||
return response.peer_card
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a subset of Honcho's Representation of a peer.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -909,3 +909,52 @@ async def test_get_peer_card_with_data(
|
|||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["peer_card"] == target_card_content
|
||||
|
||||
|
||||
def test_set_peer_card(client: TestClient, sample_data: tuple[Workspace, Peer]):
|
||||
"""Test setting peer cards via the PUT endpoint."""
|
||||
test_workspace, observer_peer = sample_data
|
||||
|
||||
# Create a target peer
|
||||
target_peer_name = str(generate_nanoid())
|
||||
response = client.post(
|
||||
f"/v3/workspaces/{test_workspace.name}/peers",
|
||||
json={"name": target_peer_name},
|
||||
)
|
||||
assert response.status_code in [200, 201]
|
||||
|
||||
# Set the observer's own card
|
||||
self_card = ["I am a test peer", "I like writing tests"]
|
||||
response = client.put(
|
||||
f"/v3/workspaces/{test_workspace.name}/peers/{observer_peer.name}/card",
|
||||
json={"peer_card": self_card},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["peer_card"] == self_card
|
||||
|
||||
# Verify with GET
|
||||
response = client.get(
|
||||
f"/v3/workspaces/{test_workspace.name}/peers/{observer_peer.name}/card"
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.json()["peer_card"] == self_card
|
||||
|
||||
# Set a card for the target peer
|
||||
target_card = ["Target is helpful", "Target knows Python"]
|
||||
response = client.put(
|
||||
f"/v3/workspaces/{test_workspace.name}/peers/{observer_peer.name}/card",
|
||||
params={"target": target_peer_name},
|
||||
json={"peer_card": target_card},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["peer_card"] == target_card
|
||||
|
||||
# Verify with GET
|
||||
response = client.get(
|
||||
f"/v3/workspaces/{test_workspace.name}/peers/{observer_peer.name}/card",
|
||||
params={"target": target_peer_name},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.json()["peer_card"] == target_card
|
||||
|
|
|
|||
|
|
@ -104,3 +104,37 @@ def test_message_and_chat_operations(honcho_test_client: Honcho):
|
|||
|
||||
# This is a mock response from the agent
|
||||
_response = user.chat("What did I ask about?")
|
||||
|
||||
|
||||
def test_peer_card_operations(honcho_test_client: Honcho):
|
||||
"""
|
||||
Tests setting and getting peer cards.
|
||||
"""
|
||||
peer = honcho_test_client.peer(id="card-test-peer")
|
||||
target = honcho_test_client.peer(id="card-test-target")
|
||||
|
||||
# Initially card should be None
|
||||
card = peer.card()
|
||||
assert card is None
|
||||
|
||||
# Set own card
|
||||
own_card = ["I am a helpful assistant", "I enjoy learning"]
|
||||
result = peer.set_card(own_card)
|
||||
assert result == own_card
|
||||
|
||||
# Verify with get
|
||||
card = peer.card()
|
||||
assert card == own_card
|
||||
|
||||
# Set card for target
|
||||
target_card = ["Target likes Python", "Target is friendly"]
|
||||
result = peer.set_card(target_card, target=target)
|
||||
assert result == target_card
|
||||
|
||||
# Verify with get
|
||||
card = peer.card(target=target)
|
||||
assert card == target_card
|
||||
|
||||
# Own card should still be unchanged
|
||||
card = peer.card()
|
||||
assert card == own_card
|
||||
|
|
|
|||
Loading…
Reference in New Issue