* Added hindsight_liteLLM implementation * Add instructions for entity vs bank id * Add another line about entity * Address PR review comments and enhance litellm integration - Remove deprecated limit parameter from recall() and arecall() functions since Hindsight uses budget/max_tokens for result control - Remove dead MODEL_MAX_OUTPUT_TOKENS dict and max_output_tokens property from LLMProvider (superseded by hardcoded max_completion_tokens) - Add test-litellm-integration job to CI workflow - Add reflect API support with use_reflect config option - Add verbose mode debug info via get_last_injection_debug() - Add entity_id support for multi-user memory isolation - Add retain() and reflect() wrapper functions - Update docstrings and examples 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Make max_memories optional to allow unlimited memory injection - Change max_memories default from 10 to None (no limit) - When max_memories is None, all results from the API are used - Fix recall result handling to properly detect list vs object return - Update wrappers (OpenAI, Anthropic) with same optional behavior This allows users to control memory limits via max_memory_tokens and recall_budget without an artificial count limit. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Remove entity_id from hindsight_litellm; add gpt-4o token cap Multi-user support now uses separate bank_ids per user instead of entity_id scoping (e.g., bank_id=f"user-{user_id}"). This simplifies the API and aligns with the Hindsight architecture. Also fixes max_completion_tokens error for gpt-4o models by capping the value at 16384 (gpt-4o's limit) instead of sending the default 65000 which exceeds the model's supported maximum. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Fix dark mode styling across Control Plane UI components Improvements to ensure proper text visibility and contrast in both light and dark modes: - Add global CSS rules for datetime-local calendar picker icon visibility using filter: invert() for both light (0.5) and dark (1) modes - Fix text colors in dialog components to use theme-aware foreground colors - Update memory detail panel, document/chunk modals, and data views to use proper dark mode text classes (text-foreground, text-card-foreground) - Fix form labels, headings, and content text in bank selector dialogs - Update entities view and documents view table styling for dark mode - Bump package versions to 0.1.4 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Remove session_id feature and add How It Works section to README - Remove session_id and session management (new_session, set_session, get_session) from config.py, callbacks.py, and __init__.py - Session management was a client-only abstraction not backed by core API - Add "How It Works" section to README with visual flow diagram - Update README to remove session management documentation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Fix readme example * Add dark mode again --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
232 lines
9.1 KiB
Python
232 lines
9.1 KiB
Python
"""Global configuration for Hindsight-LiteLLM integration."""
|
|
|
|
from typing import Optional, List
|
|
from dataclasses import dataclass, field
|
|
from enum import Enum
|
|
|
|
|
|
class MemoryInjectionMode(str, Enum):
|
|
"""How memories should be injected into the prompt."""
|
|
SYSTEM_MESSAGE = "system_message" # Add as system message
|
|
PREPEND_USER = "prepend_user" # Prepend to user message
|
|
DISABLED = "disabled" # Don't inject memories
|
|
|
|
|
|
@dataclass
|
|
class HindsightConfig:
|
|
"""Configuration for Hindsight integration with LiteLLM.
|
|
|
|
Attributes:
|
|
hindsight_api_url: URL of the Hindsight API server
|
|
bank_id: Memory bank ID for memory operations (required). For multi-user
|
|
support, use different bank_ids per user (e.g., f"user-{user_id}")
|
|
api_key: Optional API key for Hindsight authentication
|
|
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)
|
|
max_memories: Maximum number of memories to inject
|
|
max_memory_tokens: Maximum tokens for injected memory context
|
|
recall_budget: Budget level for memory recall (low, mid, high)
|
|
fact_types: List of fact types to filter recall (world, agent, opinion, observation)
|
|
document_id: Optional document ID for grouping stored conversations
|
|
enabled: Master switch to enable/disable Hindsight integration
|
|
excluded_models: List of model patterns to exclude from interception
|
|
verbose: Enable verbose logging
|
|
bank_name: Optional display name for the memory bank
|
|
background: Optional background/instructions for memory extraction
|
|
use_reflect: Use reflect API instead of recall for memory injection (synthesizes answer)
|
|
"""
|
|
|
|
hindsight_api_url: str = "http://localhost:8888"
|
|
bank_id: Optional[str] = None
|
|
api_key: Optional[str] = None
|
|
store_conversations: bool = True
|
|
inject_memories: bool = True
|
|
injection_mode: MemoryInjectionMode = MemoryInjectionMode.SYSTEM_MESSAGE
|
|
max_memories: Optional[int] = None # None = no limit (use all results from API)
|
|
max_memory_tokens: int = 4096
|
|
recall_budget: str = "mid" # low, mid, high
|
|
fact_types: Optional[List[str]] = None # world, agent, opinion, observation
|
|
document_id: Optional[str] = None
|
|
enabled: bool = True
|
|
excluded_models: List[str] = field(default_factory=list)
|
|
verbose: bool = False
|
|
bank_name: Optional[str] = None # Display name for the memory bank
|
|
background: Optional[str] = None # Background/instructions for memory extraction
|
|
use_reflect: bool = False # Use reflect instead of recall for memory injection
|
|
reflect_include_facts: bool = False # Include facts used by reflect in debug info
|
|
|
|
|
|
# Global configuration instance
|
|
_global_config: Optional[HindsightConfig] = None
|
|
|
|
|
|
def configure(
|
|
hindsight_api_url: str = "http://localhost:8888",
|
|
bank_id: Optional[str] = None,
|
|
api_key: Optional[str] = None,
|
|
store_conversations: bool = True,
|
|
inject_memories: bool = True,
|
|
injection_mode: MemoryInjectionMode = MemoryInjectionMode.SYSTEM_MESSAGE,
|
|
max_memories: Optional[int] = None,
|
|
max_memory_tokens: int = 4096,
|
|
recall_budget: str = "mid",
|
|
fact_types: Optional[List[str]] = None,
|
|
document_id: Optional[str] = None,
|
|
enabled: bool = True,
|
|
excluded_models: Optional[List[str]] = None,
|
|
verbose: bool = False,
|
|
bank_name: Optional[str] = None,
|
|
background: Optional[str] = None,
|
|
use_reflect: bool = False,
|
|
reflect_include_facts: bool = False,
|
|
) -> HindsightConfig:
|
|
"""Configure global Hindsight integration settings for LiteLLM.
|
|
|
|
This function sets up the global configuration that will be used by the
|
|
LiteLLM callbacks to inject memories and store conversations.
|
|
|
|
Args:
|
|
hindsight_api_url: URL of the Hindsight API server
|
|
bank_id: Memory bank ID for memory operations (required). For multi-user
|
|
support, use different bank_ids per user (e.g., f"user-{user_id}")
|
|
api_key: Optional API key for Hindsight authentication
|
|
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
|
|
max_memories: Maximum number of memories to inject
|
|
max_memory_tokens: Maximum tokens for injected memory context
|
|
recall_budget: Budget level for memory recall (low, mid, high)
|
|
fact_types: List of fact types to filter (world, agent, opinion, observation)
|
|
document_id: Optional document ID for grouping stored conversations
|
|
enabled: Master switch to enable/disable Hindsight integration
|
|
excluded_models: List of model patterns to exclude from interception
|
|
verbose: Enable verbose logging
|
|
bank_name: Optional display name for the memory bank
|
|
background: Optional background/instructions that help Hindsight understand
|
|
what information is important to extract and remember from conversations.
|
|
This is passed to create_bank() to configure the memory bank.
|
|
use_reflect: Use reflect API instead of recall for memory injection.
|
|
When True, Hindsight will synthesize a contextual answer based on
|
|
memories rather than returning raw memory facts.
|
|
reflect_include_facts: When use_reflect=True, include the facts that
|
|
were used to generate the reflect response in the debug info.
|
|
This is useful for debugging what memories the reflect API used.
|
|
|
|
Returns:
|
|
The configured HindsightConfig instance
|
|
|
|
Example:
|
|
>>> from hindsight_litellm import configure, enable
|
|
>>> configure(
|
|
... hindsight_api_url="http://localhost:8888",
|
|
... bank_id="user-123", # Per-user bank for multi-user support
|
|
... store_conversations=True,
|
|
... inject_memories=True,
|
|
... background="This agent routes customer requests to support channels. "
|
|
... "Remember which types of issues should go to which channels.",
|
|
... )
|
|
>>> enable() # Register callbacks with LiteLLM
|
|
"""
|
|
global _global_config
|
|
|
|
_global_config = HindsightConfig(
|
|
hindsight_api_url=hindsight_api_url,
|
|
bank_id=bank_id,
|
|
api_key=api_key,
|
|
store_conversations=store_conversations,
|
|
inject_memories=inject_memories,
|
|
injection_mode=injection_mode,
|
|
max_memories=max_memories,
|
|
max_memory_tokens=max_memory_tokens,
|
|
recall_budget=recall_budget,
|
|
fact_types=fact_types,
|
|
document_id=document_id,
|
|
enabled=enabled,
|
|
excluded_models=excluded_models or [],
|
|
verbose=verbose,
|
|
bank_name=bank_name,
|
|
background=background,
|
|
use_reflect=use_reflect,
|
|
reflect_include_facts=reflect_include_facts,
|
|
)
|
|
|
|
# If background or bank_name is provided, create/update the bank
|
|
if bank_id and (background or bank_name):
|
|
_create_or_update_bank(
|
|
hindsight_api_url=hindsight_api_url,
|
|
bank_id=bank_id,
|
|
name=bank_name,
|
|
background=background,
|
|
verbose=verbose,
|
|
)
|
|
|
|
return _global_config
|
|
|
|
|
|
def _create_or_update_bank(
|
|
hindsight_api_url: str,
|
|
bank_id: str,
|
|
name: Optional[str] = None,
|
|
background: Optional[str] = None,
|
|
verbose: bool = False,
|
|
) -> None:
|
|
"""Create or update a memory bank with the given configuration.
|
|
|
|
This is called automatically by configure() when background or bank_name is provided.
|
|
"""
|
|
try:
|
|
from hindsight_client import Hindsight
|
|
|
|
client = Hindsight(hindsight_api_url)
|
|
client.create_bank(
|
|
bank_id=bank_id,
|
|
name=name,
|
|
background=background,
|
|
)
|
|
if verbose:
|
|
import logging
|
|
logging.getLogger("hindsight_litellm").info(
|
|
f"Created/updated bank '{bank_id}' with background"
|
|
)
|
|
except ImportError:
|
|
if verbose:
|
|
import logging
|
|
logging.getLogger("hindsight_litellm").warning(
|
|
"hindsight_client not installed. Cannot create bank with background. "
|
|
"Install with: pip install hindsight-client"
|
|
)
|
|
except Exception as e:
|
|
if verbose:
|
|
import logging
|
|
logging.getLogger("hindsight_litellm").warning(
|
|
f"Failed to create/update bank: {e}"
|
|
)
|
|
|
|
|
|
def get_config() -> Optional[HindsightConfig]:
|
|
"""Get the current global configuration.
|
|
|
|
Returns:
|
|
The current HindsightConfig instance, or None if not configured
|
|
"""
|
|
return _global_config
|
|
|
|
|
|
def is_configured() -> bool:
|
|
"""Check if Hindsight has been configured.
|
|
|
|
Returns:
|
|
True if configure() has been called with a valid bank_id
|
|
"""
|
|
return (
|
|
_global_config is not None
|
|
and _global_config.enabled
|
|
and _global_config.bank_id is not None
|
|
)
|
|
|
|
|
|
def reset_config() -> None:
|
|
"""Reset the global configuration to None."""
|
|
global _global_config
|
|
_global_config = None
|