hindsight-langgraph 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,59 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+ .mcp.json
9
+ .osgrep
10
+ # Virtual environments
11
+ .venv
12
+
13
+ # Node
14
+ node_modules/
15
+
16
+ # Environment variables and local config
17
+ .env
18
+ docker-compose.yml
19
+ docker-compose.override.yml
20
+
21
+ # IDE
22
+ .idea/
23
+ .vscode/
24
+ *.swp
25
+ *.swo
26
+
27
+ # NLTK data (will be downloaded automatically)
28
+ nltk_data/
29
+
30
+ # Monitoring stack (Prometheus/Grafana binaries and data)
31
+ .monitoring/
32
+ .pgbouncer/
33
+
34
+ # Large benchmark datasets (will be downloaded automatically)
35
+ **/longmemeval_s_cleaned.json
36
+
37
+ # Debug logs
38
+ logs/
39
+
40
+ .DS_Store
41
+
42
+ # Generated docs files
43
+ hindsight-docs/static/llms-full.txt
44
+
45
+
46
+ hindsight-dev/benchmarks/locomo/results/
47
+ hindsight-dev/benchmarks/longmemeval/results/
48
+ hindsight-dev/benchmarks/consolidation/results/
49
+ hindsight-dev/benchmarks/perf/results/
50
+ benchmarks/results/
51
+ hindsight-cli/target
52
+ hindsight-clients/rust/target
53
+ .claude
54
+ whats-next.md
55
+ TASK.md
56
+ # Changelog is now tracked in hindsight-docs/src/pages/changelog.md
57
+ # CHANGELOG.md
58
+
59
+ blog-post*
@@ -0,0 +1,25 @@
1
+ Metadata-Version: 2.4
2
+ Name: hindsight-langgraph
3
+ Version: 0.1.1
4
+ Summary: LangGraph integration for Hindsight - persistent memory tools, nodes, and store for AI agents
5
+ Project-URL: Homepage, https://github.com/vectorize-io/hindsight
6
+ Project-URL: Documentation, https://github.com/vectorize-io/hindsight/tree/main/hindsight-integrations/langgraph
7
+ Project-URL: Repository, https://github.com/vectorize-io/hindsight
8
+ Author-email: Vectorize <support@vectorize.io>
9
+ License: MIT
10
+ Keywords: agents,ai,hindsight,langchain,langgraph,memory
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
19
+ Requires-Python: >=3.10
20
+ Requires-Dist: hindsight-client>=0.4.0
21
+ Requires-Dist: langchain-core>=0.3.0
22
+ Provides-Extra: all
23
+ Requires-Dist: langgraph>=0.3.0; extra == 'all'
24
+ Provides-Extra: langgraph
25
+ Requires-Dist: langgraph>=0.3.0; extra == 'langgraph'
@@ -0,0 +1,144 @@
1
+ # hindsight-langgraph
2
+
3
+ LangGraph and LangChain integration for [Hindsight](https://github.com/vectorize-io/hindsight) — persistent long-term memory for AI agents.
4
+
5
+ Provides three integration patterns:
6
+ - **Tools** — retain/recall/reflect as LangChain `@tool` functions for agent-driven memory. Works with **both LangChain and LangGraph**.
7
+ - **Nodes** *(LangGraph)* — pre-built graph nodes for automatic memory injection and storage
8
+ - **BaseStore** *(LangGraph)* — drop-in `BaseStore` adapter for LangGraph's built-in memory system
9
+
10
+ ## Prerequisites
11
+
12
+ - A running Hindsight instance ([self-hosted via Docker](https://github.com/vectorize-io/hindsight#quick-start) or [Hindsight Cloud](https://ui.hindsight.vectorize.io/signup))
13
+ - Python 3.10+
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ pip install hindsight-langgraph
19
+ ```
20
+
21
+ ## Quick Start: Tools
22
+
23
+ Bind Hindsight memory tools to your LangGraph agent so it can store and retrieve memories on demand.
24
+
25
+ ```python
26
+ from hindsight_client import Hindsight
27
+ from hindsight_langgraph import create_hindsight_tools
28
+ from langchain_openai import ChatOpenAI
29
+ from langgraph.prebuilt import create_react_agent
30
+
31
+ client = Hindsight(base_url="http://localhost:8888")
32
+ tools = create_hindsight_tools(client=client, bank_id="user-123")
33
+
34
+ agent = create_react_agent(
35
+ ChatOpenAI(model="gpt-4o"),
36
+ tools=tools,
37
+ )
38
+
39
+ result = await agent.ainvoke(
40
+ {"messages": [{"role": "user", "content": "Remember that I prefer dark mode"}]}
41
+ )
42
+ ```
43
+
44
+ ## Quick Start: Memory Nodes
45
+
46
+ Add recall and retain nodes to your graph for automatic memory injection before LLM calls and storage after responses.
47
+
48
+ ```python
49
+ from hindsight_client import Hindsight
50
+ from hindsight_langgraph import create_recall_node, create_retain_node
51
+ from langgraph.graph import StateGraph, MessagesState, START, END
52
+
53
+ client = Hindsight(base_url="http://localhost:8888")
54
+
55
+ recall = create_recall_node(client=client, bank_id="user-123")
56
+ retain = create_retain_node(client=client, bank_id="user-123")
57
+
58
+ builder = StateGraph(MessagesState)
59
+ builder.add_node("recall", recall)
60
+ builder.add_node("agent", agent_node) # your LLM node
61
+ builder.add_node("retain", retain)
62
+
63
+ builder.add_edge(START, "recall")
64
+ builder.add_edge("recall", "agent")
65
+ builder.add_edge("agent", "retain")
66
+ builder.add_edge("retain", END)
67
+
68
+ graph = builder.compile()
69
+ ```
70
+
71
+ ### Dynamic Bank IDs
72
+
73
+ Use `bank_id_from_config` to resolve the bank per-request from the graph's config:
74
+
75
+ ```python
76
+ recall = create_recall_node(client=client, bank_id_from_config="user_id")
77
+ retain = create_retain_node(client=client, bank_id_from_config="user_id")
78
+
79
+ # Bank ID resolved at runtime
80
+ result = await graph.ainvoke(
81
+ {"messages": [{"role": "user", "content": "hello"}]},
82
+ config={"configurable": {"user_id": "user-456"}},
83
+ )
84
+ ```
85
+
86
+ ## Quick Start: BaseStore
87
+
88
+ Use Hindsight as a LangGraph `BaseStore` for cross-thread persistent memory with semantic search.
89
+
90
+ ```python
91
+ from hindsight_client import Hindsight
92
+ from hindsight_langgraph import HindsightStore
93
+
94
+ client = Hindsight(base_url="http://localhost:8888")
95
+ store = HindsightStore(client=client)
96
+
97
+ graph = builder.compile(checkpointer=checkpointer, store=store)
98
+
99
+ # Store and search memories via the store API
100
+ await store.aput(("user", "123", "prefs"), "theme", {"value": "dark mode"})
101
+ results = await store.asearch(("user", "123", "prefs"), query="theme preference")
102
+ ```
103
+
104
+ ## Configuration
105
+
106
+ ### Global config
107
+
108
+ ```python
109
+ from hindsight_langgraph import configure
110
+
111
+ configure(
112
+ hindsight_api_url="http://localhost:8888",
113
+ api_key="your-api-key", # or set HINDSIGHT_API_KEY env var
114
+ budget="mid",
115
+ tags=["source:langgraph"],
116
+ )
117
+ ```
118
+
119
+ ### Per-call overrides
120
+
121
+ All factory functions accept `client`, `hindsight_api_url`, and `api_key` to override the global config.
122
+
123
+ | Parameter | Description | Default |
124
+ |-----------|-------------|---------|
125
+ | `hindsight_api_url` | Hindsight API URL | `https://api.hindsight.vectorize.io` |
126
+ | `api_key` | API key (or `HINDSIGHT_API_KEY` env var) | `None` |
127
+ | `budget` | Recall budget: `low`, `mid`, `high` | `mid` |
128
+ | `max_tokens` | Max tokens for recall results | `4096` |
129
+ | `tags` | Tags applied to retain operations | `None` |
130
+ | `recall_tags` | Tags to filter recall results | `None` |
131
+ | `recall_tags_match` | Tag matching: `any`, `all`, `any_strict`, `all_strict` | `any` |
132
+
133
+ ## Requirements
134
+
135
+ - Python 3.10+
136
+ - `langchain-core >= 0.3.0`
137
+ - `hindsight-client >= 0.4.0`
138
+ - `langgraph >= 0.3.0` *(only for nodes and store patterns — install with `pip install hindsight-langgraph[langgraph]`)*
139
+
140
+ ## Documentation
141
+
142
+ - [Integration docs](https://docs.hindsight.vectorize.io/docs/sdks/integrations/langgraph)
143
+ - [Cookbook: ReAct agent with memory](https://docs.hindsight.vectorize.io/cookbook/recipes/langgraph-react-agent)
144
+ - [Hindsight API docs](https://docs.hindsight.vectorize.io)
@@ -0,0 +1,93 @@
1
+ """Hindsight-LangGraph: Persistent memory for LangGraph and LangChain agents.
2
+
3
+ Provides Hindsight-backed tools, nodes, and a BaseStore adapter,
4
+ giving agents long-term memory across conversations.
5
+
6
+ The **tools** pattern works with both LangChain and LangGraph — only
7
+ ``langchain-core`` is required. The **nodes** and **store** patterns
8
+ require ``langgraph`` (install with ``pip install hindsight-langgraph[langgraph]``).
9
+
10
+ Basic usage with tools (LangChain or LangGraph)::
11
+
12
+ from hindsight_client import Hindsight
13
+ from hindsight_langgraph import create_hindsight_tools
14
+
15
+ client = Hindsight(base_url="http://localhost:8888")
16
+ tools = create_hindsight_tools(client=client, bank_id="user-123")
17
+
18
+ # Bind tools to your model
19
+ model = ChatOpenAI(model="gpt-4o").bind_tools(tools)
20
+
21
+ Usage with memory nodes (requires langgraph)::
22
+
23
+ from hindsight_langgraph import create_recall_node, create_retain_node
24
+
25
+ recall = create_recall_node(client=client, bank_id="user-123")
26
+ retain = create_retain_node(client=client, bank_id="user-123")
27
+
28
+ builder.add_node("recall", recall)
29
+ builder.add_node("agent", agent_node)
30
+ builder.add_node("retain", retain)
31
+ builder.add_edge("recall", "agent")
32
+ builder.add_edge("agent", "retain")
33
+
34
+ Usage with BaseStore (requires langgraph)::
35
+
36
+ from hindsight_langgraph import HindsightStore
37
+
38
+ store = HindsightStore(client=client)
39
+ graph = builder.compile(checkpointer=checkpointer, store=store)
40
+ """
41
+
42
+ from .config import (
43
+ HindsightLangGraphConfig,
44
+ configure,
45
+ get_config,
46
+ reset_config,
47
+ )
48
+ from .errors import HindsightError
49
+ from .tools import create_hindsight_tools
50
+
51
+
52
+ def __getattr__(name: str):
53
+ """Lazy-import LangGraph-specific modules so langgraph is optional."""
54
+ if name == "create_recall_node" or name == "create_retain_node":
55
+ try:
56
+ from .nodes import create_recall_node, create_retain_node
57
+ except ImportError:
58
+ raise ImportError(
59
+ f"'{name}' requires langgraph. Install with: pip install hindsight-langgraph[langgraph]"
60
+ ) from None
61
+ return (
62
+ create_recall_node if name == "create_recall_node" else create_retain_node
63
+ )
64
+
65
+ if name == "HindsightStore":
66
+ try:
67
+ from .store import HindsightStore
68
+ except ImportError:
69
+ raise ImportError(
70
+ "HindsightStore requires langgraph. Install with: pip install hindsight-langgraph[langgraph]"
71
+ ) from None
72
+ return HindsightStore
73
+
74
+ raise AttributeError(f"module 'hindsight_langgraph' has no attribute {name!r}")
75
+
76
+
77
+ __version__ = "0.1.0"
78
+
79
+ __all__ = [
80
+ "configure",
81
+ "get_config",
82
+ "reset_config",
83
+ "HindsightLangGraphConfig",
84
+ "HindsightError",
85
+ "create_hindsight_tools",
86
+ ]
87
+
88
+ try:
89
+ import langgraph # noqa: F401
90
+
91
+ __all__ += ["create_recall_node", "create_retain_node", "HindsightStore"]
92
+ except ImportError:
93
+ pass
@@ -0,0 +1,32 @@
1
+ """Shared Hindsight client resolution logic."""
2
+
3
+ from typing import Any, Optional
4
+
5
+ from hindsight_client import Hindsight
6
+
7
+ from .config import get_config
8
+ from .errors import HindsightError
9
+
10
+
11
+ def resolve_client(
12
+ client: Optional[Hindsight],
13
+ hindsight_api_url: Optional[str],
14
+ api_key: Optional[str],
15
+ ) -> Hindsight:
16
+ """Resolve a Hindsight client from explicit args or global config."""
17
+ if client is not None:
18
+ return client
19
+
20
+ config = get_config()
21
+ url = hindsight_api_url or (config.hindsight_api_url if config else None)
22
+ key = api_key or (config.api_key if config else None)
23
+
24
+ if url is None:
25
+ raise HindsightError(
26
+ "No Hindsight API URL configured. Pass client= or hindsight_api_url=, or call configure() first."
27
+ )
28
+
29
+ kwargs: dict[str, Any] = {"base_url": url, "timeout": 30.0}
30
+ if key:
31
+ kwargs["api_key"] = key
32
+ return Hindsight(**kwargs)
@@ -0,0 +1,91 @@
1
+ """Global configuration for Hindsight-LangGraph integration."""
2
+
3
+ import os
4
+ from dataclasses import dataclass
5
+ from typing import Optional
6
+
7
+ DEFAULT_HINDSIGHT_API_URL = "https://api.hindsight.vectorize.io"
8
+ HINDSIGHT_API_KEY_ENV = "HINDSIGHT_API_KEY"
9
+
10
+
11
+ @dataclass
12
+ class HindsightLangGraphConfig:
13
+ """Connection and default settings for the LangGraph integration.
14
+
15
+ Attributes:
16
+ hindsight_api_url: URL of the Hindsight API server.
17
+ api_key: API key for Hindsight authentication.
18
+ budget: Default recall budget level (low/mid/high).
19
+ max_tokens: Default maximum tokens for recall results.
20
+ tags: Default tags applied when storing memories.
21
+ recall_tags: Default tags to filter when searching memories.
22
+ recall_tags_match: Tag matching mode (any/all/any_strict/all_strict).
23
+ verbose: Enable verbose logging.
24
+ """
25
+
26
+ hindsight_api_url: str = DEFAULT_HINDSIGHT_API_URL
27
+ api_key: Optional[str] = None
28
+ budget: str = "mid"
29
+ max_tokens: int = 4096
30
+ tags: Optional[list[str]] = None
31
+ recall_tags: Optional[list[str]] = None
32
+ recall_tags_match: str = "any"
33
+ verbose: bool = False
34
+
35
+
36
+ _global_config: Optional[HindsightLangGraphConfig] = None
37
+
38
+
39
+ def configure(
40
+ hindsight_api_url: Optional[str] = None,
41
+ api_key: Optional[str] = None,
42
+ budget: str = "mid",
43
+ max_tokens: int = 4096,
44
+ tags: Optional[list[str]] = None,
45
+ recall_tags: Optional[list[str]] = None,
46
+ recall_tags_match: str = "any",
47
+ verbose: bool = False,
48
+ ) -> HindsightLangGraphConfig:
49
+ """Configure Hindsight connection and default settings.
50
+
51
+ Args:
52
+ hindsight_api_url: Hindsight API URL (default: production).
53
+ api_key: API key. Falls back to HINDSIGHT_API_KEY env var.
54
+ budget: Default recall budget (low/mid/high).
55
+ max_tokens: Default max tokens for recall.
56
+ tags: Default tags for retain operations.
57
+ recall_tags: Default tags to filter recall/search.
58
+ recall_tags_match: Tag matching mode.
59
+ verbose: Enable verbose logging.
60
+
61
+ Returns:
62
+ The configured HindsightLangGraphConfig.
63
+ """
64
+ global _global_config
65
+
66
+ resolved_url = hindsight_api_url or DEFAULT_HINDSIGHT_API_URL
67
+ resolved_key = api_key or os.environ.get(HINDSIGHT_API_KEY_ENV)
68
+
69
+ _global_config = HindsightLangGraphConfig(
70
+ hindsight_api_url=resolved_url,
71
+ api_key=resolved_key,
72
+ budget=budget,
73
+ max_tokens=max_tokens,
74
+ tags=tags,
75
+ recall_tags=recall_tags,
76
+ recall_tags_match=recall_tags_match,
77
+ verbose=verbose,
78
+ )
79
+
80
+ return _global_config
81
+
82
+
83
+ def get_config() -> Optional[HindsightLangGraphConfig]:
84
+ """Get the current global configuration."""
85
+ return _global_config
86
+
87
+
88
+ def reset_config() -> None:
89
+ """Reset global configuration to None."""
90
+ global _global_config
91
+ _global_config = None
@@ -0,0 +1,7 @@
1
+ """Hindsight-LangGraph error types."""
2
+
3
+
4
+ class HindsightError(Exception):
5
+ """Exception raised when a Hindsight memory operation fails."""
6
+
7
+ pass