diff --git a/docs/v3/documentation/reference/sdk.mdx b/docs/v3/documentation/reference/sdk.mdx index 967f39ff..7016b840 100644 --- a/docs/v3/documentation/reference/sdk.mdx +++ b/docs/v3/documentation/reference/sdk.mdx @@ -280,6 +280,12 @@ metadata = alice.get_metadata() metadata["location"] = "Paris" alice.set_metadata(metadata) +# Peer card management +card = alice.get_card() # Get peer card +card = alice.get_card(target="bob") # Get card about another peer +updated = alice.set_card(["Likes Python", "Lives in NYC"]) # Set peer card +updated = alice.set_card(["Works at Acme"], target="bob") # Set card about another peer + # Get peer context (representation + peer card in one call) context = alice.context() context = alice.context(target="bob") # What alice knows about bob @@ -334,6 +340,12 @@ await alice.setMetadata({ location: "Paris" }); +// Peer card management +const card = await alice.getCard(); // Get peer card +const targetCard = await alice.getCard("bob"); // Get card about another peer +const updated = await alice.setCard(["Likes TypeScript", "Lives in NYC"]); // Set peer card +const updatedTarget = await alice.setCard(["Works at Acme"], "bob"); // Set card about another peer + // Get peer context (representation + peer card in one call) const context = await alice.context(); const targetContext = await alice.context({ target: "bob" }); // What alice knows about bob @@ -396,6 +408,46 @@ const searchedContext = await alice.context({ ``` +### Peer Card + +The peer card contains stable biographical facts about a peer (name, preferences, background). Use `get_card()` / `getCard()` to retrieve it and `set_card()` / `setCard()` to overwrite it: + + +```python Python +# Get peer's own card +card = alice.get_card() +print(card) # ["Likes Python", "Lives in NYC", ...] + +# Get card about another peer (local representation) +bob_card = alice.get_card(target="bob") + +# Set peer's own card +updated = alice.set_card(["Likes Python", "Lives in NYC"]) + +# Set card about another peer +updated = alice.set_card(["Works at Acme", "Enjoys hiking"], target="bob") +``` + +```typescript TypeScript +// Get peer's own card +const card = await alice.getCard(); +console.log(card); // ["Likes TypeScript", "Lives in NYC", ...] + +// Get card about another peer (local representation) +const bobCard = await alice.getCard("bob"); + +// Set peer's own card +const updated = await alice.setCard(["Likes TypeScript", "Lives in NYC"]); + +// Set card about another peer +const updatedBob = await alice.setCard(["Works at Acme", "Enjoys hiking"], "bob"); +``` + + + +Peer cards are automatically maintained by the deriver agent during message processing. Use `set_card()` / `setCard()` when you need to manually override or seed the card — the peer will be created automatically if it doesn't already exist. + + ### Conclusions Peers can access their conclusions (facts derived from messages) through the `conclusions` property and `conclusions_of()` method: diff --git a/docs/v3/guides/migrations/mem0.mdx b/docs/v3/guides/migrations/mem0.mdx index 6a2bbd22..1d56bde6 100644 --- a/docs/v3/guides/migrations/mem0.mdx +++ b/docs/v3/guides/migrations/mem0.mdx @@ -274,7 +274,7 @@ Additional features with **no Mem0 equivalent**: | Honcho Method | Description | Use Case | |---------------|-------------|----------| -| `peer.card()` | Stable biographical facts (name, preferences, background) | User profiles, personalization | +| `peer.get_card()` / `peer.set_card()` | Stable biographical facts (name, preferences, background) | User profiles, personalization | | `session.representation(peer)` | Cached psychological analysis (mental state, intentions) | Real-time adaptation | | `session.summaries()` | Auto-generated short/long session summaries | Conversation continuity | | `SessionPeerConfig` | Configure observation settings (who learns about whom) | Privacy controls, role-based learning | diff --git a/docs/v3/migrations/from-mem0.mdx b/docs/v3/migrations/from-mem0.mdx index 6a2bbd22..1d56bde6 100644 --- a/docs/v3/migrations/from-mem0.mdx +++ b/docs/v3/migrations/from-mem0.mdx @@ -274,7 +274,7 @@ Additional features with **no Mem0 equivalent**: | Honcho Method | Description | Use Case | |---------------|-------------|----------| -| `peer.card()` | Stable biographical facts (name, preferences, background) | User profiles, personalization | +| `peer.get_card()` / `peer.set_card()` | Stable biographical facts (name, preferences, background) | User profiles, personalization | | `session.representation(peer)` | Cached psychological analysis (mental state, intentions) | Real-time adaptation | | `session.summaries()` | Auto-generated short/long session summaries | Conversation continuity | | `SessionPeerConfig` | Configure observation settings (who learns about whom) | Privacy controls, role-based learning | diff --git a/tests/sdk/test_peer.py b/tests/sdk/test_peer.py index dae19398..62b3a54f 100644 --- a/tests/sdk/test_peer.py +++ b/tests/sdk/test_peer.py @@ -93,7 +93,7 @@ async def test_peer_card_global(client_fixture: tuple[Honcho, str]): await session.aio.add_messages([peer.message("I like pizza")]) # Get global peer card - card_response = await peer.aio.card() + card_response = await peer.aio.get_card() assert card_response is None or isinstance(card_response, list) else: peer = honcho_client.peer(id="test-card-global-peer") @@ -103,7 +103,7 @@ async def test_peer_card_global(client_fixture: tuple[Honcho, str]): session.add_messages([peer.message("I like pizza")]) # Get global peer card - card_response = peer.card() + card_response = peer.get_card() assert card_response is None or isinstance(card_response, list) @@ -125,11 +125,11 @@ async def test_peer_card_local(client_fixture: tuple[Honcho, str]): ) # Get local peer card with target as Peer object - card_response = await observer.aio.card(target=target) + card_response = await observer.aio.get_card(target=target) assert card_response is None or isinstance(card_response, list) # Get local peer card with target as string - card_response = await observer.aio.card(target=target.id) + card_response = await observer.aio.get_card(target=target.id) assert card_response is None or isinstance(card_response, list) else: observer = honcho_client.peer(id="test-card-local-observer") @@ -140,11 +140,11 @@ async def test_peer_card_local(client_fixture: tuple[Honcho, str]): session.add_messages([observer.message("Hello"), target.message("Hi there")]) # Get local peer card with target as Peer object - card_response = observer.card(target=target) + card_response = observer.get_card(target=target) assert card_response is None or isinstance(card_response, list) # Get local peer card with target as string - card_response = observer.card(target=target.id) + card_response = observer.get_card(target=target.id) assert card_response is None or isinstance(card_response, list) @@ -161,13 +161,13 @@ async def test_peer_card_with_empty_target(client_fixture: tuple[Honcho, str]): peer = await honcho_client.aio.peer(id="test-card-validation-peer") # Empty target is treated as no target (same as None) - result = await peer.aio.card(target="") + result = await peer.aio.get_card(target="") assert result is None or isinstance(result, list) else: peer = honcho_client.peer(id="test-card-validation-peer") # Empty target is treated as no target (same as None) - result = peer.card(target="") + result = peer.get_card(target="") assert result is None or isinstance(result, list) diff --git a/tests/unified/runner.py b/tests/unified/runner.py index 2168d1c4..0d07d5fe 100644 --- a/tests/unified/runner.py +++ b/tests/unified/runner.py @@ -345,7 +345,7 @@ class UnifiedTestExecutor: raise ValueError("peer_id required for get_peer_card") peer = await self.client.aio.peer(id=step.observer_peer_id) - card = await peer.aio.card( + card = await peer.aio.get_card( step.observed_peer_id if step.observed_peer_id else step.observer_peer_id