hipcortex 0.2.0__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,108 @@
1
+ Metadata-Version: 2.4
2
+ Name: hipcortex
3
+ Version: 0.2.0
4
+ Summary: Persistent causal memory for AI agents — LangChain, LlamaIndex, AutoGen, CrewAI
5
+ Author: HipCortex Contributors
6
+ License: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/farmountain/HipCortex
8
+ Project-URL: Repository, https://github.com/farmountain/HipCortex
9
+ Project-URL: Issues, https://github.com/farmountain/HipCortex/issues
10
+ Project-URL: Benchmark, https://github.com/farmountain/HipCortex/blob/main/BENCHMARK.md
11
+ Keywords: ai,memory,langchain,autogen,crewai,llm,agents,rag
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: License :: OSI Approved :: Apache Software License
14
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
15
+ Classifier: Intended Audience :: Developers
16
+ Requires-Python: >=3.9
17
+ Description-Content-Type: text/markdown
18
+ Requires-Dist: requests>=2.28
19
+ Requires-Dist: httpx>=0.27
20
+ Provides-Extra: langchain
21
+ Requires-Dist: langchain-core>=0.1; extra == "langchain"
22
+ Provides-Extra: llamaindex
23
+ Requires-Dist: llama-index-core>=0.10; extra == "llamaindex"
24
+ Provides-Extra: crewai
25
+ Requires-Dist: crewai>=0.28; extra == "crewai"
26
+ Requires-Dist: crewai-tools>=0.1; extra == "crewai"
27
+ Provides-Extra: autogen
28
+ Requires-Dist: pyautogen>=0.2; extra == "autogen"
29
+ Provides-Extra: benchmark
30
+ Requires-Dist: mem0ai>=0.1; extra == "benchmark"
31
+ Requires-Dist: tabulate>=0.9; extra == "benchmark"
32
+ Provides-Extra: all
33
+ Requires-Dist: langchain-core>=0.1; extra == "all"
34
+ Requires-Dist: llama-index-core>=0.10; extra == "all"
35
+ Requires-Dist: crewai>=0.28; extra == "all"
36
+ Requires-Dist: crewai-tools>=0.1; extra == "all"
37
+ Requires-Dist: pyautogen>=0.2; extra == "all"
38
+ Requires-Dist: mem0ai>=0.1; extra == "all"
39
+ Requires-Dist: tabulate>=0.9; extra == "all"
40
+ Dynamic: requires-python
41
+
42
+ # hipcortex
43
+
44
+ **Persistent causal memory for AI agents — LangChain, LlamaIndex, AutoGen, CrewAI.**
45
+
46
+ 1.74ms p50 write latency. Temporal decay. Causal world model. Merkle-chained audit log. GDPR right-to-forget.
47
+
48
+ ## Install
49
+
50
+ ```bash
51
+ pip install hipcortex
52
+ ```
53
+
54
+ ## Quick start
55
+
56
+ ```python
57
+ from hipcortex import HipCortexClient
58
+
59
+ client = HipCortexClient("http://localhost:3030")
60
+
61
+ # Store memory
62
+ client.add_memory(actor="alice", action="said", target="The meeting is at 3pm")
63
+
64
+ # Search (keyword or cosine similarity)
65
+ results = client.search("meeting time", limit=5)
66
+
67
+ # Stats
68
+ print(client.stats())
69
+
70
+ # GDPR forget
71
+ client.forget("alice")
72
+ ```
73
+
74
+ ## Framework integrations
75
+
76
+ ```python
77
+ # LangChain — drop-in for ConversationBufferMemory
78
+ from hipcortex.langchain_memory import HipCortexMemory
79
+ memory = HipCortexMemory(session_id="user-42", url="http://localhost:3030")
80
+
81
+ # LlamaIndex
82
+ from hipcortex.llamaindex_storage import HipCortexChatStore
83
+ store = HipCortexChatStore(client=client)
84
+
85
+ # AutoGen
86
+ from hipcortex.adapters.autogen import HipCortexAutoGenMemory
87
+ mem = HipCortexAutoGenMemory(client=client, agent_id="researcher")
88
+ agent.register_hook("process_message_before_send", mem.on_message_sent)
89
+
90
+ # CrewAI
91
+ from hipcortex.adapters.crewai import HipCortexRememberTool, HipCortexRecallTool
92
+ tools = [HipCortexRememberTool(client=client), HipCortexRecallTool(client=client)]
93
+ ```
94
+
95
+ ## Start the server
96
+
97
+ ```bash
98
+ # Self-hosted (single binary, zero deps)
99
+ cargo run --bin webserver --no-default-features --features "web-server,petgraph_backend"
100
+
101
+ # Fly.io
102
+ fly deploy
103
+
104
+ # Live demo
105
+ https://hipcortex.fly.dev
106
+ ```
107
+
108
+ **Full docs:** https://github.com/farmountain/HipCortex
@@ -0,0 +1,67 @@
1
+ # hipcortex
2
+
3
+ **Persistent causal memory for AI agents — LangChain, LlamaIndex, AutoGen, CrewAI.**
4
+
5
+ 1.74ms p50 write latency. Temporal decay. Causal world model. Merkle-chained audit log. GDPR right-to-forget.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pip install hipcortex
11
+ ```
12
+
13
+ ## Quick start
14
+
15
+ ```python
16
+ from hipcortex import HipCortexClient
17
+
18
+ client = HipCortexClient("http://localhost:3030")
19
+
20
+ # Store memory
21
+ client.add_memory(actor="alice", action="said", target="The meeting is at 3pm")
22
+
23
+ # Search (keyword or cosine similarity)
24
+ results = client.search("meeting time", limit=5)
25
+
26
+ # Stats
27
+ print(client.stats())
28
+
29
+ # GDPR forget
30
+ client.forget("alice")
31
+ ```
32
+
33
+ ## Framework integrations
34
+
35
+ ```python
36
+ # LangChain — drop-in for ConversationBufferMemory
37
+ from hipcortex.langchain_memory import HipCortexMemory
38
+ memory = HipCortexMemory(session_id="user-42", url="http://localhost:3030")
39
+
40
+ # LlamaIndex
41
+ from hipcortex.llamaindex_storage import HipCortexChatStore
42
+ store = HipCortexChatStore(client=client)
43
+
44
+ # AutoGen
45
+ from hipcortex.adapters.autogen import HipCortexAutoGenMemory
46
+ mem = HipCortexAutoGenMemory(client=client, agent_id="researcher")
47
+ agent.register_hook("process_message_before_send", mem.on_message_sent)
48
+
49
+ # CrewAI
50
+ from hipcortex.adapters.crewai import HipCortexRememberTool, HipCortexRecallTool
51
+ tools = [HipCortexRememberTool(client=client), HipCortexRecallTool(client=client)]
52
+ ```
53
+
54
+ ## Start the server
55
+
56
+ ```bash
57
+ # Self-hosted (single binary, zero deps)
58
+ cargo run --bin webserver --no-default-features --features "web-server,petgraph_backend"
59
+
60
+ # Fly.io
61
+ fly deploy
62
+
63
+ # Live demo
64
+ https://hipcortex.fly.dev
65
+ ```
66
+
67
+ **Full docs:** https://github.com/farmountain/HipCortex
@@ -0,0 +1,15 @@
1
+ """HipCortex Python SDK — AI memory engine client."""
2
+
3
+ from .client import HipCortexClient
4
+ from .async_client import AsyncHipCortexClient
5
+ from .langchain_memory import HipCortexMemory, AsyncHipCortexMemory
6
+ from .llamaindex_storage import HipCortexStorageContext
7
+
8
+ __version__ = "0.2.0"
9
+ __all__ = [
10
+ "HipCortexClient",
11
+ "AsyncHipCortexClient",
12
+ "HipCortexMemory",
13
+ "AsyncHipCortexMemory",
14
+ "HipCortexStorageContext",
15
+ ]
@@ -0,0 +1 @@
1
+ """Framework adapters for HipCortex — AutoGen and CrewAI."""
@@ -0,0 +1,156 @@
1
+ """HipCortex AutoGen adapter — targets AutoGen 0.4+ (autogen-agentchat >= 0.4).
2
+
3
+ AutoGen 0.4 changed from register_hook() to the Memory protocol.
4
+
5
+ Usage (AutoGen 0.4+):
6
+ from autogen_agentchat.agents import AssistantAgent
7
+ from hipcortex import HipCortexClient
8
+ from hipcortex.adapters.autogen import HipCortexAutoGenMemory
9
+
10
+ client = HipCortexClient(base_url="http://localhost:3030")
11
+ memory = HipCortexAutoGenMemory(client=client, agent_id="researcher")
12
+ agent = AssistantAgent(name="researcher", model_client=..., memory=[memory])
13
+
14
+ Usage (AutoGen 0.3 — legacy):
15
+ agent.register_hook("process_message_before_send", memory.on_message_sent_v03)
16
+ agent.register_hook("process_all_messages_before_reply", memory.on_messages_received_v03)
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ from typing import Any, Dict, List, Optional
22
+
23
+ from ..client import HipCortexClient
24
+
25
+ try:
26
+ from autogen_core.memory import Memory, MemoryContent, MemoryMimeType, MemoryQueryResult
27
+ from autogen_core import CancellationToken
28
+ _AUTOGEN4_AVAILABLE = True
29
+ except ImportError:
30
+ _AUTOGEN4_AVAILABLE = False
31
+ class Memory: # type: ignore[no-redef]
32
+ pass
33
+ class CancellationToken: # type: ignore[no-redef]
34
+ pass
35
+
36
+
37
+ class HipCortexAutoGenMemory(Memory): # type: ignore[misc]
38
+ """AutoGen 0.4 Memory protocol backed by HipCortex."""
39
+
40
+ def __init__(
41
+ self,
42
+ client: HipCortexClient,
43
+ agent_id: str = "autogen-agent",
44
+ top_k: int = 10,
45
+ ) -> None:
46
+ self._client = client
47
+ self._agent_id = agent_id
48
+ self._top_k = top_k
49
+
50
+ # AutoGen 0.4 Memory protocol -------------------------------------------
51
+
52
+ async def add(
53
+ self,
54
+ content: Any,
55
+ cancellation_token: Optional[CancellationToken] = None,
56
+ ) -> None:
57
+ if _AUTOGEN4_AVAILABLE and hasattr(content, "content"):
58
+ text = str(content.content)
59
+ role = getattr(content, "role", None)
60
+ mime = getattr(content, "mime_type", None)
61
+ action = "ai_message" if (
62
+ (role and role in ("assistant", "ai")) or
63
+ (mime and "assistant" in str(mime).lower())
64
+ ) else "observation"
65
+ else:
66
+ text = str(content)
67
+ action = "observation"
68
+ self._client.add_memory(
69
+ actor=self._agent_id, action=action,
70
+ target=text, record_type="Temporal",
71
+ )
72
+
73
+ async def query(
74
+ self,
75
+ query: Any,
76
+ cancellation_token: Optional[CancellationToken] = None,
77
+ ) -> Any:
78
+ query_text = str(getattr(query, "content", query))
79
+ try:
80
+ search_results = self._client.search(query=query_text, limit=self._top_k)
81
+ except Exception:
82
+ search_results = [
83
+ {"record": r, "score": 1.0}
84
+ for r in self._client.get_conversation_history(self._agent_id, limit=self._top_k)
85
+ ]
86
+ if not _AUTOGEN4_AVAILABLE:
87
+ return search_results
88
+ memories = []
89
+ for item in search_results:
90
+ rec = item.get("record", item)
91
+ memories.append(MemoryContent(
92
+ content=rec.get("target", ""),
93
+ mime_type=MemoryMimeType.TEXT,
94
+ metadata={"score": item.get("score", 1.0), "actor": rec.get("actor", ""),
95
+ "action": rec.get("action", ""), "timestamp": rec.get("timestamp", "")},
96
+ ))
97
+ return MemoryQueryResult(results=memories)
98
+
99
+ async def update_context(
100
+ self,
101
+ model_context: Any,
102
+ cancellation_token: Optional[CancellationToken] = None,
103
+ ) -> Any:
104
+ records = self._client.get_conversation_history(self._agent_id, limit=self._top_k)
105
+ records.sort(key=lambda r: r.get("timestamp", ""))
106
+ if not records:
107
+ return {"memories_added": 0}
108
+ lines = [f"[{r.get('action','memory')}] {r.get('target','')}" for r in records]
109
+ system_msg = {"role": "system", "content": "[HipCortex memory]\n" + "\n".join(lines)}
110
+ if hasattr(model_context, "add_message"):
111
+ await model_context.add_message(system_msg)
112
+ elif hasattr(model_context, "messages"):
113
+ model_context.messages.insert(0, system_msg)
114
+ return {"memories_added": len(records)}
115
+
116
+ async def clear(self) -> None:
117
+ self._client.forget(self._agent_id)
118
+
119
+ # AutoGen 0.3 legacy hooks -----------------------------------------------
120
+
121
+ def on_message_sent_v03(self, message: Dict[str, Any], **kwargs: Any) -> Dict[str, Any]:
122
+ """AutoGen 0.3 hook: process_message_before_send."""
123
+ content = message.get("content", "")
124
+ role = message.get("role", "assistant")
125
+ action = "ai_message" if role == "assistant" else "human_message"
126
+ self._client.add_memory(actor=self._agent_id, action=action, target=str(content),
127
+ record_type="Reflexion" if role == "assistant" else "Temporal")
128
+ return message
129
+
130
+ def on_messages_received_v03(
131
+ self, messages: List[Dict[str, Any]], **kwargs: Any
132
+ ) -> List[Dict[str, Any]]:
133
+ """AutoGen 0.3 hook: process_all_messages_before_reply."""
134
+ history = self._client.get_conversation_history(self._agent_id, limit=20)
135
+ if not history:
136
+ return messages
137
+ history.sort(key=lambda r: r.get("timestamp", ""))
138
+ lines = [
139
+ f"{'AI' if r.get('action') == 'ai_message' else 'Human'}: {r.get('target','')}"
140
+ for r in history
141
+ ]
142
+ return [{"role": "system", "content": "[HipCortex memory]\n" + "\n".join(lines)}] + list(messages)
143
+
144
+ # Sync helpers (no AutoGen needed) ---------------------------------------
145
+
146
+ def store(self, content: str, action: str = "observation") -> Dict[str, Any]:
147
+ return self._client.add_memory(actor=self._agent_id, action=action,
148
+ target=content, record_type="Temporal")
149
+
150
+ def recall(self, limit: int = 20) -> str:
151
+ records = self._client.get_conversation_history(self._agent_id, limit=limit)
152
+ records.sort(key=lambda r: r.get("timestamp", ""))
153
+ return "\n".join(f"[{r.get('action','?')}] {r.get('target','')}" for r in records)
154
+
155
+ def forget_all(self) -> Dict[str, Any]:
156
+ return self._client.forget(self._agent_id)
@@ -0,0 +1,153 @@
1
+ """CrewAI tool adapter for HipCortex.
2
+
3
+ Exposes HipCortex memory operations as CrewAI ``BaseTool`` subclasses
4
+ so agents can store and retrieve memories as tool calls during task execution.
5
+
6
+ Usage::
7
+
8
+ from crewai import Agent, Task, Crew
9
+ from hipcortex import HipCortexClient
10
+ from hipcortex.adapters.crewai import (
11
+ HipCortexRememberTool,
12
+ HipCortexRecallTool,
13
+ HipCortexForgetTool,
14
+ )
15
+
16
+ client = HipCortexClient(base_url="http://localhost:3000")
17
+ tools = [
18
+ HipCortexRememberTool(client=client, agent_id="researcher"),
19
+ HipCortexRecallTool(client=client, agent_id="researcher"),
20
+ HipCortexForgetTool(client=client, agent_id="researcher"),
21
+ ]
22
+
23
+ researcher = Agent(
24
+ role="Senior Researcher",
25
+ goal="Research and remember findings",
26
+ tools=tools,
27
+ ...
28
+ )
29
+ """
30
+
31
+ from __future__ import annotations
32
+
33
+ from typing import Any, Optional, Type
34
+
35
+ from ..client import HipCortexClient
36
+
37
+ try:
38
+ from crewai_tools import BaseTool
39
+ from pydantic import BaseModel, Field
40
+ _CREWAI_AVAILABLE = True
41
+ except ImportError:
42
+ _CREWAI_AVAILABLE = False
43
+
44
+ class BaseModel: # type: ignore[no-redef]
45
+ pass
46
+
47
+ class Field: # type: ignore[no-redef]
48
+ def __init__(self, *a: Any, **kw: Any) -> None: ...
49
+
50
+ class BaseTool: # type: ignore[no-redef]
51
+ name: str = ""
52
+ description: str = ""
53
+ args_schema: Any = None
54
+ def _run(self, *a: Any, **kw: Any) -> str: ...
55
+
56
+
57
+ # ---------------------------------------------------------------------------
58
+ # Input schemas
59
+ # ---------------------------------------------------------------------------
60
+
61
+ if _CREWAI_AVAILABLE:
62
+ class RememberInput(BaseModel):
63
+ content: str = Field(..., description="Observation or fact to remember.")
64
+ action: str = Field(default="observation", description="Action tag (e.g. 'finding', 'decision').")
65
+
66
+ class RecallInput(BaseModel):
67
+ limit: int = Field(default=20, description="Max number of memories to return.")
68
+
69
+ class ForgetInput(BaseModel):
70
+ confirm: bool = Field(default=False, description="Set to True to confirm deletion.")
71
+
72
+
73
+ # ---------------------------------------------------------------------------
74
+ # Tools
75
+ # ---------------------------------------------------------------------------
76
+
77
+ class HipCortexRememberTool(BaseTool): # type: ignore[misc]
78
+ """CrewAI tool: store an observation in HipCortex memory."""
79
+
80
+ name: str = "hipcortex_remember"
81
+ description: str = (
82
+ "Store an important observation, finding, or decision in persistent memory. "
83
+ "Use this whenever you discover information worth remembering for future tasks."
84
+ )
85
+ if _CREWAI_AVAILABLE:
86
+ args_schema: Type[BaseModel] = RememberInput
87
+
88
+ def __init__(self, client: HipCortexClient, agent_id: str = "crewai-agent") -> None:
89
+ super().__init__()
90
+ self._client = client
91
+ self._agent_id = agent_id
92
+
93
+ def _run(self, content: str, action: str = "observation") -> str:
94
+ result = self._client.add_memory(
95
+ actor=self._agent_id,
96
+ action=action,
97
+ target=content,
98
+ record_type="Temporal",
99
+ )
100
+ if result.get("success"):
101
+ return f"Stored memory with id={result.get('record_id', '?')}"
102
+ return f"Failed to store memory: {result.get('error', 'unknown error')}"
103
+
104
+
105
+ class HipCortexRecallTool(BaseTool): # type: ignore[misc]
106
+ """CrewAI tool: retrieve recent memories from HipCortex."""
107
+
108
+ name: str = "hipcortex_recall"
109
+ description: str = (
110
+ "Retrieve recent memories and observations stored in HipCortex. "
111
+ "Use this to recall past findings before starting a new research task."
112
+ )
113
+ if _CREWAI_AVAILABLE:
114
+ args_schema: Type[BaseModel] = RecallInput
115
+
116
+ def __init__(self, client: HipCortexClient, agent_id: str = "crewai-agent") -> None:
117
+ super().__init__()
118
+ self._client = client
119
+ self._agent_id = agent_id
120
+
121
+ def _run(self, limit: int = 20) -> str:
122
+ records = self._client.get_conversation_history(self._agent_id, limit=limit)
123
+ if not records:
124
+ return "No memories found."
125
+ records.sort(key=lambda r: r.get("timestamp", ""))
126
+ lines = []
127
+ for i, rec in enumerate(records, 1):
128
+ lines.append(f"{i}. [{rec.get('action', '?')}] {rec.get('target', '')}")
129
+ return "\n".join(lines)
130
+
131
+
132
+ class HipCortexForgetTool(BaseTool): # type: ignore[misc]
133
+ """CrewAI tool: delete all memories for this agent (GDPR / session reset)."""
134
+
135
+ name: str = "hipcortex_forget"
136
+ description: str = (
137
+ "Delete all memories stored for this agent. "
138
+ "Only use this when explicitly asked to clear memory or start fresh."
139
+ )
140
+ if _CREWAI_AVAILABLE:
141
+ args_schema: Type[BaseModel] = ForgetInput
142
+
143
+ def __init__(self, client: HipCortexClient, agent_id: str = "crewai-agent") -> None:
144
+ super().__init__()
145
+ self._client = client
146
+ self._agent_id = agent_id
147
+
148
+ def _run(self, confirm: bool = False) -> str:
149
+ if not confirm:
150
+ return "Deletion not confirmed. Pass confirm=True to proceed."
151
+ result = self._client.forget(self._agent_id)
152
+ deleted = result.get("records_deleted", 0)
153
+ return f"Deleted {deleted} memory records for agent '{self._agent_id}'."