Compare commits

...
Author SHA1 Message Date
Nicolò BoschiandClaude Opus 4.5 24cccd7c69 Fix: rename 'background' parameter to 'mission' in Python client create_bank()
The parameter was named 'background' but the internal code used 'mission',
causing undefined variable errors. The tests also expected 'mission'.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-26 10:39:45 +01:00
Nicolò BoschiandClaude Opus 4.5 d4d646218e Fix test using non-existent 'enabled' parameter in configure()
The test was calling configure(enabled=False) but configure() doesn't
have an enabled parameter. Changed to test is_configured() returns False
when reset_config() has been called.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-26 10:17:27 +01:00
Chris Bartholomew ef6db8365c Add sensible defaults for simpler API usage
Make it easier to get started with hindsight-litellm by providing
sensible defaults:

- Default API URL: https://api.hindsight.vectorize.io (production)
- Default bank_id: "default"
- Read api_key from HINDSIGHT_API_KEY environment variable

Now users can simply do:

    client = wrap_openai(OpenAI())

With just the HINDSIGHT_API_KEY env var set, and it works.

Also adds comprehensive unit tests for the new defaults behavior.
2026-01-26 10:11:30 +01:00
Chris Bartholomew 654c1a4488 Fix: Pass api_key to Hindsight client in litellm integration
The recall(), reflect(), and retain() wrapper functions were creating
Hindsight client instances without passing the api_key from the config.
This caused 401 Unauthorized errors when using hindsight-litellm with
authenticated Hindsight API servers.

Also added api_key parameter to:
- HindsightOpenAI and HindsightAnthropic wrapper classes
- wrap_openai() and wrap_anthropic() functions
2026-01-26 10:09:46 +01:00
7 changed files with 370 additions and 54 deletions
@@ -324,7 +324,7 @@ class Hindsight:
self,
bank_id: str,
name: str | None = None,
background: str | None = None,
mission: str | None = None,
disposition: dict[str, float] | None = None,
) -> BankProfileResponse:
"""Create or update a memory bank.
@@ -15,10 +15,16 @@ This module provides a clean API for configuring Hindsight integration:
4. set_bank_mission() - Set the mission for a memory bank (for mental models)
"""
import os
from typing import Optional, List, Any, Dict
from dataclasses import dataclass, field
from enum import Enum
# Default Hindsight API URL (production)
DEFAULT_HINDSIGHT_API_URL = "https://api.hindsight.vectorize.io"
DEFAULT_BANK_ID = "default"
HINDSIGHT_API_KEY_ENV = "HINDSIGHT_API_KEY"
class MemoryInjectionMode(str, Enum):
"""How memories should be injected into the prompt.
@@ -37,7 +43,11 @@ class HindsightConfig:
Attributes:
hindsight_api_url: URL of the Hindsight API server
api_key: Optional API key for Hindsight authentication
(default: https://api.hindsight.vectorize.io)
bank_id: Memory bank ID for memory operations (default: "default").
For multi-user support, use different bank_ids per user (e.g., f"user-{user_id}")
api_key: API key for Hindsight authentication. If not provided,
reads from HINDSIGHT_API_KEY environment variable.
store_conversations: Whether to store conversations to Hindsight
inject_memories: Whether to inject relevant memories into prompts
injection_mode: How to inject memories (system_message or prepend_user)
@@ -47,7 +57,8 @@ class HindsightConfig:
If False (default), storage runs in background thread for better performance.
"""
hindsight_api_url: str = "http://localhost:8888"
hindsight_api_url: str = DEFAULT_HINDSIGHT_API_URL
bank_id: str = DEFAULT_BANK_ID
api_key: Optional[str] = None
store_conversations: bool = True
inject_memories: bool = True
@@ -102,8 +113,11 @@ _global_defaults: Optional[HindsightDefaults] = None
def configure(
hindsight_api_url: str = "http://localhost:8888",
hindsight_api_url: Optional[str] = None,
bank_id: Optional[str] = None,
api_key: Optional[str] = None,
background: Optional[str] = None,
bank_name: Optional[str] = None,
store_conversations: bool = True,
inject_memories: bool = True,
injection_mode: MemoryInjectionMode = MemoryInjectionMode.SYSTEM_MESSAGE,
@@ -116,9 +130,20 @@ def configure(
This sets up settings that typically don't change during a session.
For per-call settings like bank_id, use set_defaults() or per-call kwargs.
With sensible defaults, you can use minimal configuration:
configure() # Just set HINDSIGHT_API_KEY env var
enable()
Args:
hindsight_api_url: URL of the Hindsight API server
api_key: Optional API key for Hindsight authentication
(default: https://api.hindsight.vectorize.io)
bank_id: Memory bank ID for memory operations (default: "default").
For multi-user support, use different bank_ids per user (e.g., f"user-{user_id}")
api_key: API key for Hindsight authentication. If not provided,
reads from HINDSIGHT_API_KEY environment variable.
background: Instructions guiding what Hindsight should learn and remember.
bank_name: Optional display name for the bank.
store_conversations: Whether to store conversations to Hindsight
inject_memories: Whether to inject relevant memories into prompts
injection_mode: How to inject memories into the prompt
@@ -132,20 +157,30 @@ def configure(
The configured HindsightConfig instance
Example:
>>> from hindsight_litellm import configure, set_defaults, enable
>>> from hindsight_litellm import configure, enable
>>>
>>> # Minimal usage - just set HINDSIGHT_API_KEY env var
>>> configure()
>>> enable()
>>>
>>> # Or with custom settings
>>> configure(
... hindsight_api_url="http://localhost:8888",
... api_key="your-api-key",
... verbose=True,
... bank_id="user-123", # Per-user bank for multi-user support
... background="Remember user preferences and past interactions.",
... )
>>> set_defaults(bank_id="user-123")
>>> enable() # Start memory integration
>>> enable()
"""
global _global_config
# Apply defaults
resolved_api_url = hindsight_api_url or DEFAULT_HINDSIGHT_API_URL
resolved_bank_id = bank_id or DEFAULT_BANK_ID
resolved_api_key = api_key or os.environ.get(HINDSIGHT_API_KEY_ENV)
_global_config = HindsightConfig(
hindsight_api_url=hindsight_api_url,
api_key=api_key,
hindsight_api_url=resolved_api_url,
bank_id=resolved_bank_id,
api_key=resolved_api_key,
store_conversations=store_conversations,
inject_memories=inject_memories,
injection_mode=injection_mode,
@@ -154,6 +189,17 @@ def configure(
sync_storage=sync_storage,
)
# If background or bank_name is provided, create/update the bank
if background or bank_name:
_create_or_update_bank(
hindsight_api_url=resolved_api_url,
bank_id=resolved_bank_id,
name=bank_name,
mission=background,
verbose=verbose,
api_key=resolved_api_key,
)
return _global_config
@@ -244,6 +290,7 @@ def _create_or_update_bank(
name: Optional[str] = None,
mission: Optional[str] = None,
verbose: bool = False,
api_key: Optional[str] = None,
) -> None:
"""Create or update a memory bank with the given configuration.
@@ -257,7 +304,7 @@ def _create_or_update_bank(
try:
from hindsight_client import Hindsight
client = Hindsight(hindsight_api_url)
client = Hindsight(base_url=hindsight_api_url, api_key=api_key)
client.create_bank(
bank_id=bank_id,
name=name,
@@ -305,8 +352,10 @@ def is_configured() -> bool:
"""Check if Hindsight has been configured with a valid bank_id.
Returns:
True if configure() has been called and a bank_id is set in defaults
True if configure() has been called and a bank_id is set
"""
if _global_config is not None and _global_config.bank_id:
return True
return (
_global_config is not None
and _global_defaults is not None
@@ -8,10 +8,16 @@ integration with native client libraries.
"""
import logging
import os
import threading
from typing import Any, Dict, List, Optional, Union
from dataclasses import dataclass
# Default Hindsight API URL (production)
DEFAULT_HINDSIGHT_API_URL = "https://api.hindsight.vectorize.io"
DEFAULT_BANK_ID = "default"
HINDSIGHT_API_KEY_ENV = "HINDSIGHT_API_KEY"
from .config import get_config, get_defaults, is_configured, HindsightConfig
@@ -22,7 +28,7 @@ _retain_errors_lock = threading.Lock()
logger = logging.getLogger(__name__)
def _get_client(api_url: str):
def _get_client(api_url: str, api_key: Optional[str] = None):
"""Create a fresh Hindsight client for the given URL.
Note: We create a fresh client each time because the hindsight_client
@@ -30,7 +36,7 @@ def _get_client(api_url: str):
calls causes asyncio context issues.
"""
from hindsight_client import Hindsight
return Hindsight(base_url=api_url, timeout=30.0)
return Hindsight(base_url=api_url, api_key=api_key, timeout=30.0)
def _close_client():
@@ -145,7 +151,7 @@ def recall(
client = None
try:
# Create fresh client for this operation
client = _get_client(api_url)
client = _get_client(api_url, config.api_key if config else None)
# Call recall API
results = client.recall(
@@ -308,7 +314,7 @@ def reflect(
client = None
try:
# Create fresh client for this operation
client = _get_client(api_url)
client = _get_client(api_url, config.api_key if config else None)
# Call reflect API
reflect_kwargs = {
@@ -410,12 +416,13 @@ def _retain_sync(
target_document_id: Optional[str],
metadata: Optional[Dict[str, str]],
verbose: bool,
api_key: Optional[str] = None,
) -> RetainResult:
"""Internal synchronous retain implementation."""
client = None
try:
# Create fresh client for this operation
client = _get_client(api_url)
client = _get_client(api_url, api_key)
# Call retain API
result = client.retain(
@@ -467,6 +474,7 @@ def _retain_background(
target_document_id: Optional[str],
metadata: Optional[Dict[str, str]],
verbose: bool,
api_key: Optional[str] = None,
) -> None:
"""Background thread worker for async retain."""
global _retain_errors
@@ -479,6 +487,7 @@ def _retain_background(
target_document_id=target_document_id,
metadata=metadata,
verbose=verbose,
api_key=api_key,
)
except Exception as e:
with _retain_errors_lock:
@@ -571,6 +580,8 @@ def retain(
"Hindsight not configured. Call configure() or provide bank_id and hindsight_api_url."
)
api_key = config.api_key if config else None
if sync:
# Synchronous mode - block and return result
return _retain_sync(
@@ -581,6 +592,7 @@ def retain(
target_document_id=target_document_id,
metadata=metadata,
verbose=verbose,
api_key=api_key,
)
else:
# Async mode - run in background thread
@@ -594,6 +606,7 @@ def retain(
target_document_id,
metadata,
verbose,
api_key,
),
daemon=True,
)
@@ -653,6 +666,7 @@ class HindsightOpenAI:
client: Any,
bank_id: str,
hindsight_api_url: str = "http://localhost:8888",
api_key: Optional[str] = None,
session_id: Optional[str] = None,
store_conversations: bool = True,
inject_memories: bool = True,
@@ -667,6 +681,7 @@ class HindsightOpenAI:
bank_id: Memory bank ID for memory operations. For multi-user support,
use different bank_ids per user (e.g., f"user-{user_id}")
hindsight_api_url: URL of the Hindsight API server
api_key: Optional API key for Hindsight authentication
session_id: Session identifier for conversation grouping
store_conversations: Whether to store conversations
inject_memories: Whether to inject relevant memories
@@ -677,6 +692,7 @@ class HindsightOpenAI:
self._client = client
self._bank_id = bank_id
self._api_url = hindsight_api_url
self._api_key = api_key
self._session_id = session_id
self._store_conversations = store_conversations
self._inject_memories = inject_memories
@@ -694,6 +710,7 @@ class HindsightOpenAI:
from hindsight_client import Hindsight
self._hindsight_client = Hindsight(
base_url=self._api_url,
api_key=self._api_key,
timeout=30.0,
)
return self._hindsight_client
@@ -857,6 +874,7 @@ class HindsightAnthropic:
client: Any,
bank_id: str,
hindsight_api_url: str = "http://localhost:8888",
api_key: Optional[str] = None,
session_id: Optional[str] = None,
store_conversations: bool = True,
inject_memories: bool = True,
@@ -871,6 +889,7 @@ class HindsightAnthropic:
bank_id: Memory bank ID for memory operations. For multi-user support,
use different bank_ids per user (e.g., f"user-{user_id}")
hindsight_api_url: URL of the Hindsight API server
api_key: Optional API key for Hindsight authentication
session_id: Session identifier for conversation grouping
store_conversations: Whether to store conversations
inject_memories: Whether to inject relevant memories
@@ -881,6 +900,7 @@ class HindsightAnthropic:
self._client = client
self._bank_id = bank_id
self._api_url = hindsight_api_url
self._api_key = api_key
self._session_id = session_id
self._store_conversations = store_conversations
self._inject_memories = inject_memories
@@ -898,6 +918,7 @@ class HindsightAnthropic:
from hindsight_client import Hindsight
self._hindsight_client = Hindsight(
base_url=self._api_url,
api_key=self._api_key,
timeout=30.0,
)
return self._hindsight_client
@@ -1031,8 +1052,9 @@ class _WrappedAnthropicMessages:
def wrap_openai(
client: Any,
bank_id: str,
hindsight_api_url: str = "http://localhost:8888",
bank_id: Optional[str] = None,
hindsight_api_url: Optional[str] = None,
api_key: Optional[str] = None,
session_id: Optional[str] = None,
store_conversations: bool = True,
inject_memories: bool = True,
@@ -1045,14 +1067,23 @@ def wrap_openai(
This creates a wrapped client that automatically injects memories
and stores conversations when making chat completion calls.
With sensible defaults, you can use it with minimal configuration:
client = wrap_openai(OpenAI())
Just set the HINDSIGHT_API_KEY environment variable and you're ready to go.
Args:
client: The OpenAI client instance to wrap
bank_id: Memory bank ID for memory operations. For multi-user support,
bank_id: Memory bank ID (default: "default"). For multi-user support,
use different bank_ids per user (e.g., f"user-{user_id}")
hindsight_api_url: URL of the Hindsight API server
(default: https://api.hindsight.vectorize.io)
api_key: API key for Hindsight authentication. If not provided,
reads from HINDSIGHT_API_KEY environment variable.
session_id: Session identifier for conversation grouping
store_conversations: Whether to store conversations
inject_memories: Whether to inject relevant memories
store_conversations: Whether to store conversations (default: True)
inject_memories: Whether to inject relevant memories (default: True)
max_memories: Maximum number of memories to inject (None = no limit)
budget: Budget level for memory recall (low, mid, high)
verbose: Enable verbose logging
@@ -1064,21 +1095,24 @@ def wrap_openai(
>>> from openai import OpenAI
>>> from hindsight_litellm import wrap_openai
>>>
>>> client = OpenAI()
>>> wrapped = wrap_openai(
... client,
... bank_id=f"user-{user_id}", # Multi-user support via separate banks
... )
>>> # Minimal usage - just set HINDSIGHT_API_KEY env var
>>> client = wrap_openai(OpenAI())
>>>
>>> response = wrapped.chat.completions.create(
... model="gpt-4",
>>> response = client.chat.completions.create(
... model="gpt-4o-mini",
... messages=[{"role": "user", "content": "What do you know about me?"}]
... )
"""
# Apply defaults
resolved_bank_id = bank_id or DEFAULT_BANK_ID
resolved_api_url = hindsight_api_url or DEFAULT_HINDSIGHT_API_URL
resolved_api_key = api_key or os.environ.get(HINDSIGHT_API_KEY_ENV)
return HindsightOpenAI(
client=client,
bank_id=bank_id,
hindsight_api_url=hindsight_api_url,
bank_id=resolved_bank_id,
hindsight_api_url=resolved_api_url,
api_key=resolved_api_key,
session_id=session_id,
store_conversations=store_conversations,
inject_memories=inject_memories,
@@ -1090,8 +1124,9 @@ def wrap_openai(
def wrap_anthropic(
client: Any,
bank_id: str,
hindsight_api_url: str = "http://localhost:8888",
bank_id: Optional[str] = None,
hindsight_api_url: Optional[str] = None,
api_key: Optional[str] = None,
session_id: Optional[str] = None,
store_conversations: bool = True,
inject_memories: bool = True,
@@ -1104,14 +1139,23 @@ def wrap_anthropic(
This creates a wrapped client that automatically injects memories
and stores conversations when making message calls.
With sensible defaults, you can use it with minimal configuration:
client = wrap_anthropic(Anthropic())
Just set the HINDSIGHT_API_KEY environment variable and you're ready to go.
Args:
client: The Anthropic client instance to wrap
bank_id: Memory bank ID for memory operations. For multi-user support,
bank_id: Memory bank ID (default: "default"). For multi-user support,
use different bank_ids per user (e.g., f"user-{user_id}")
hindsight_api_url: URL of the Hindsight API server
(default: https://api.hindsight.vectorize.io)
api_key: API key for Hindsight authentication. If not provided,
reads from HINDSIGHT_API_KEY environment variable.
session_id: Session identifier for conversation grouping
store_conversations: Whether to store conversations
inject_memories: Whether to inject relevant memories
store_conversations: Whether to store conversations (default: True)
inject_memories: Whether to inject relevant memories (default: True)
max_memories: Maximum number of memories to inject (None = no limit)
budget: Budget level for memory recall (low, mid, high)
verbose: Enable verbose logging
@@ -1123,22 +1167,25 @@ def wrap_anthropic(
>>> from anthropic import Anthropic
>>> from hindsight_litellm import wrap_anthropic
>>>
>>> client = Anthropic()
>>> wrapped = wrap_anthropic(
... client,
... bank_id=f"user-{user_id}", # Multi-user support via separate banks
... )
>>> # Minimal usage - just set HINDSIGHT_API_KEY env var
>>> client = wrap_anthropic(Anthropic())
>>>
>>> response = wrapped.messages.create(
... model="claude-3-5-sonnet-20241022",
>>> response = client.messages.create(
... model="claude-sonnet-4-20250514",
... max_tokens=1024,
... messages=[{"role": "user", "content": "What do you know about me?"}]
... )
"""
# Apply defaults
resolved_bank_id = bank_id or DEFAULT_BANK_ID
resolved_api_url = hindsight_api_url or DEFAULT_HINDSIGHT_API_URL
resolved_api_key = api_key or os.environ.get(HINDSIGHT_API_KEY_ENV)
return HindsightAnthropic(
client=client,
bank_id=bank_id,
hindsight_api_url=hindsight_api_url,
bank_id=resolved_bank_id,
hindsight_api_url=resolved_api_url,
api_key=resolved_api_key,
session_id=session_id,
store_conversations=store_conversations,
inject_memories=inject_memories,
@@ -61,3 +61,8 @@ packages = ["hindsight_litellm"]
[tool.pytest.ini_options]
asyncio_mode = "auto"
testpaths = ["tests"]
[dependency-groups]
dev = [
"pytest>=9.0.2",
]
@@ -0,0 +1,202 @@
"""Unit tests for hindsight_litellm configuration and defaults."""
import os
from unittest.mock import MagicMock, patch
import pytest
from hindsight_litellm import configure, wrap_openai, wrap_anthropic, reset_config, is_configured
from hindsight_litellm.config import (
DEFAULT_HINDSIGHT_API_URL,
DEFAULT_BANK_ID,
HINDSIGHT_API_KEY_ENV,
reset_config,
get_config,
is_configured,
)
from hindsight_litellm.wrappers import HindsightOpenAI, HindsightAnthropic
class TestDefaults:
"""Test default configuration values."""
def test_default_api_url(self):
"""Test default API URL is production."""
assert DEFAULT_HINDSIGHT_API_URL == "https://api.hindsight.vectorize.io"
def test_default_bank_id(self):
"""Test default bank ID is 'default'."""
assert DEFAULT_BANK_ID == "default"
def test_env_var_name(self):
"""Test environment variable name for API key."""
assert HINDSIGHT_API_KEY_ENV == "HINDSIGHT_API_KEY"
class TestConfigure:
"""Test configure() function."""
def setup_method(self):
"""Reset config before each test."""
reset_config()
def teardown_method(self):
"""Reset config after each test."""
reset_config()
def test_configure_with_no_arguments(self):
"""Test configure() with no arguments uses defaults."""
config = configure()
assert config.hindsight_api_url == DEFAULT_HINDSIGHT_API_URL
assert config.bank_id == DEFAULT_BANK_ID
def test_configure_reads_api_key_from_env(self):
"""Test configure() reads API key from environment variable."""
with patch.dict(os.environ, {HINDSIGHT_API_KEY_ENV: "test-api-key-123"}):
config = configure()
assert config.api_key == "test-api-key-123"
def test_configure_explicit_api_key_overrides_env(self):
"""Test explicit api_key parameter overrides environment variable."""
with patch.dict(os.environ, {HINDSIGHT_API_KEY_ENV: "env-key"}):
config = configure(api_key="explicit-key")
assert config.api_key == "explicit-key"
def test_configure_explicit_values_override_defaults(self):
"""Test explicit values override defaults."""
config = configure(
hindsight_api_url="http://custom-url:8888",
bank_id="custom-bank",
api_key="custom-key",
)
assert config.hindsight_api_url == "http://custom-url:8888"
assert config.bank_id == "custom-bank"
assert config.api_key == "custom-key"
def test_is_configured_true_with_defaults(self):
"""Test is_configured() returns True with default config."""
configure()
assert is_configured() is True
def test_is_configured_false_when_not_configured(self):
"""Test is_configured() returns False when not configured."""
reset_config()
assert is_configured() is False
class TestWrapOpenAI:
"""Test wrap_openai() function."""
def setup_method(self):
"""Reset config before each test."""
reset_config()
def teardown_method(self):
"""Reset config after each test."""
reset_config()
def test_wrap_openai_with_only_client(self):
"""Test wrap_openai() works with only the client argument."""
mock_client = MagicMock()
with patch.dict(os.environ, {HINDSIGHT_API_KEY_ENV: "test-key"}):
wrapped = wrap_openai(mock_client)
assert isinstance(wrapped, HindsightOpenAI)
assert wrapped._bank_id == DEFAULT_BANK_ID
assert wrapped._api_url == DEFAULT_HINDSIGHT_API_URL
assert wrapped._api_key == "test-key"
def test_wrap_openai_uses_defaults(self):
"""Test wrap_openai() uses default values."""
mock_client = MagicMock()
wrapped = wrap_openai(mock_client)
assert wrapped._bank_id == DEFAULT_BANK_ID
assert wrapped._api_url == DEFAULT_HINDSIGHT_API_URL
def test_wrap_openai_reads_api_key_from_env(self):
"""Test wrap_openai() reads API key from environment."""
mock_client = MagicMock()
with patch.dict(os.environ, {HINDSIGHT_API_KEY_ENV: "env-api-key"}):
wrapped = wrap_openai(mock_client)
assert wrapped._api_key == "env-api-key"
def test_wrap_openai_explicit_overrides_defaults(self):
"""Test wrap_openai() explicit values override defaults."""
mock_client = MagicMock()
wrapped = wrap_openai(
mock_client,
bank_id="my-bank",
hindsight_api_url="http://localhost:9999",
api_key="my-key",
)
assert wrapped._bank_id == "my-bank"
assert wrapped._api_url == "http://localhost:9999"
assert wrapped._api_key == "my-key"
class TestWrapAnthropic:
"""Test wrap_anthropic() function."""
def setup_method(self):
"""Reset config before each test."""
reset_config()
def teardown_method(self):
"""Reset config after each test."""
reset_config()
def test_wrap_anthropic_with_only_client(self):
"""Test wrap_anthropic() works with only the client argument."""
mock_client = MagicMock()
with patch.dict(os.environ, {HINDSIGHT_API_KEY_ENV: "test-key"}):
wrapped = wrap_anthropic(mock_client)
assert isinstance(wrapped, HindsightAnthropic)
assert wrapped._bank_id == DEFAULT_BANK_ID
assert wrapped._api_url == DEFAULT_HINDSIGHT_API_URL
assert wrapped._api_key == "test-key"
def test_wrap_anthropic_uses_defaults(self):
"""Test wrap_anthropic() uses default values."""
mock_client = MagicMock()
wrapped = wrap_anthropic(mock_client)
assert wrapped._bank_id == DEFAULT_BANK_ID
assert wrapped._api_url == DEFAULT_HINDSIGHT_API_URL
def test_wrap_anthropic_reads_api_key_from_env(self):
"""Test wrap_anthropic() reads API key from environment."""
mock_client = MagicMock()
with patch.dict(os.environ, {HINDSIGHT_API_KEY_ENV: "env-api-key"}):
wrapped = wrap_anthropic(mock_client)
assert wrapped._api_key == "env-api-key"
def test_wrap_anthropic_explicit_overrides_defaults(self):
"""Test wrap_anthropic() explicit values override defaults."""
mock_client = MagicMock()
wrapped = wrap_anthropic(
mock_client,
bank_id="my-bank",
hindsight_api_url="http://localhost:9999",
api_key="my-key",
)
assert wrapped._bank_id == "my-bank"
assert wrapped._api_url == "http://localhost:9999"
assert wrapped._api_key == "my-key"
@@ -85,17 +85,22 @@ class TestConfiguration:
assert defaults.fact_types == ["world", "opinion"]
assert defaults.document_id == "doc-123"
def test_is_configured_without_bank_id(self):
"""Test is_configured returns False without bank_id."""
configure(hindsight_api_url="http://localhost:8888")
assert is_configured() is False
def test_is_configured_with_defaults(self):
"""Test is_configured returns True with default bank_id."""
configure() # Uses default bank_id="default"
assert is_configured() is True
def test_is_configured_with_bank_id(self):
"""Test is_configured returns True with bank_id."""
def test_is_configured_with_bank_id_in_defaults(self):
"""Test is_configured returns True with bank_id in defaults."""
configure(hindsight_api_url="http://localhost:8888")
set_defaults(bank_id="test-agent")
assert is_configured() is True
def test_is_configured_with_explicit_bank_id(self):
"""Test is_configured returns True with explicit bank_id."""
configure(bank_id="test-agent")
assert is_configured() is True
def test_reset_config(self):
"""Test reset_config clears the configuration."""
configure(hindsight_api_url="http://localhost:8888")
+8
View File
@@ -707,6 +707,11 @@ dev = [
{ name = "pytest-mock" },
]
[package.dev-dependencies]
dev = [
{ name = "pytest" },
]
[package.metadata]
requires-dist = [
{ name = "aiohttp", specifier = ">=3.13.3" },
@@ -719,6 +724,9 @@ requires-dist = [
]
provides-extras = ["dev"]
[package.metadata.requires-dev]
dev = [{ name = "pytest", specifier = ">=9.0.2" }]
[[package]]
name = "httpcore"
version = "1.0.9"