hipcortex 0.3.0__tar.gz → 0.3.2__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.
Files changed (26) hide show
  1. {hipcortex-0.3.0 → hipcortex-0.3.2}/PKG-INFO +1 -1
  2. {hipcortex-0.3.0 → hipcortex-0.3.2}/hipcortex/cli.py +83 -16
  3. {hipcortex-0.3.0 → hipcortex-0.3.2}/hipcortex/client.py +60 -0
  4. hipcortex-0.3.2/hipcortex/indexer.py +219 -0
  5. {hipcortex-0.3.0 → hipcortex-0.3.2}/hipcortex.egg-info/PKG-INFO +1 -1
  6. {hipcortex-0.3.0 → hipcortex-0.3.2}/hipcortex.egg-info/SOURCES.txt +1 -0
  7. {hipcortex-0.3.0 → hipcortex-0.3.2}/pyproject.toml +49 -49
  8. {hipcortex-0.3.0 → hipcortex-0.3.2}/README.md +0 -0
  9. {hipcortex-0.3.0 → hipcortex-0.3.2}/hipcortex/__init__.py +0 -0
  10. {hipcortex-0.3.0 → hipcortex-0.3.2}/hipcortex/adapters/__init__.py +0 -0
  11. {hipcortex-0.3.0 → hipcortex-0.3.2}/hipcortex/adapters/autogen.py +0 -0
  12. {hipcortex-0.3.0 → hipcortex-0.3.2}/hipcortex/adapters/crewai.py +0 -0
  13. {hipcortex-0.3.0 → hipcortex-0.3.2}/hipcortex/async_client.py +0 -0
  14. {hipcortex-0.3.0 → hipcortex-0.3.2}/hipcortex/install/SKILL.md +0 -0
  15. {hipcortex-0.3.0 → hipcortex-0.3.2}/hipcortex/install/__init__.py +0 -0
  16. {hipcortex-0.3.0 → hipcortex-0.3.2}/hipcortex/langchain_memory.py +0 -0
  17. {hipcortex-0.3.0 → hipcortex-0.3.2}/hipcortex/llamaindex_storage.py +0 -0
  18. {hipcortex-0.3.0 → hipcortex-0.3.2}/hipcortex.egg-info/dependency_links.txt +0 -0
  19. {hipcortex-0.3.0 → hipcortex-0.3.2}/hipcortex.egg-info/entry_points.txt +0 -0
  20. {hipcortex-0.3.0 → hipcortex-0.3.2}/hipcortex.egg-info/requires.txt +0 -0
  21. {hipcortex-0.3.0 → hipcortex-0.3.2}/hipcortex.egg-info/top_level.txt +0 -0
  22. {hipcortex-0.3.0 → hipcortex-0.3.2}/setup.cfg +0 -0
  23. {hipcortex-0.3.0 → hipcortex-0.3.2}/setup.py +0 -0
  24. {hipcortex-0.3.0 → hipcortex-0.3.2}/tests/test_async_client.py +0 -0
  25. {hipcortex-0.3.0 → hipcortex-0.3.2}/tests/test_async_langchain.py +0 -0
  26. {hipcortex-0.3.0 → hipcortex-0.3.2}/tests/test_cli_install.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hipcortex
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: Persistent causal memory for AI agents -- LangChain, LlamaIndex, AutoGen, CrewAI
5
5
  Author: HipCortex Contributors
6
6
  License: Apache-2.0
@@ -696,22 +696,29 @@ def _getch() -> str:
696
696
 
697
697
  def _run_wizard(agents: list) -> list:
698
698
  """Interactive multi-select. Skips section headers. Returns selected agent dicts."""
699
- # Separate selectable items from section dividers
699
+ import re as _re
700
700
  selectable = [i for i, a in enumerate(agents) if a["type"] != "section"]
701
701
  n_all = len(agents)
702
702
  selected: set = set()
703
- sel_cursor = 0 # index into selectable list
703
+ sel_cursor = 0
704
704
 
705
705
  def _display_name(a: dict) -> str:
706
- """Strip ANSI from name for width calculation."""
707
- import re
708
- return re.sub(r'\033\[[^m]*m', '', a["name"])
706
+ return _re.sub(r'\033\[[^m]*m', '', a["name"])
707
+
708
+ # On Windows, cursor-up ANSI codes corrupt the display.
709
+ # Use cls-style redraw: print a blank separator then full list.
710
+ _is_windows = platform.system() == "Windows"
709
711
 
710
712
  def render():
711
- print(f"\033[{n_all + 3}A", end="")
713
+ cur_real = selectable[sel_cursor] if selectable else -1
714
+ if _is_windows:
715
+ # Windows: no cursor-up — just reprint with blank line separator
716
+ print()
717
+ else:
718
+ # Unix: move cursor up to overwrite previous render
719
+ print(f"\033[{n_all + 3}A", end="")
712
720
  print(f" {_BOLD}Select what to configure:{_RESET} {_GRAY}(Space toggle · Enter confirm · q quit){_RESET}")
713
721
  print()
714
- cur_real = selectable[sel_cursor] if selectable else -1
715
722
  for i, agent in enumerate(agents):
716
723
  if agent["type"] == "section":
717
724
  print(f" {_DIM}{agent['name']}{_RESET}")
@@ -734,15 +741,17 @@ def _run_wizard(agents: list) -> list:
734
741
  count = len(selected)
735
742
  print(f"\n {_GREEN}{count} selected{_RESET}" if count else f"\n {_GRAY}none selected{_RESET}")
736
743
 
737
- # Initial draw (reserve lines for all rows + header + footer)
738
- print(f" {_BOLD}Select what to configure:{_RESET}")
739
- print()
740
- for agent in agents:
741
- if agent["type"] == "section":
742
- print(f" {_DIM}{agent['name']}{_RESET}")
743
- else:
744
- print(f" ○ {_display_name(agent):<20} {_DIM}{agent['desc']}{_RESET}")
745
- print()
744
+ # Initial draw
745
+ if not _is_windows:
746
+ # Reserve lines for cursor-up redraw on Unix
747
+ print(f" {_BOLD}Select what to configure:{_RESET}")
748
+ print()
749
+ for agent in agents:
750
+ if agent["type"] == "section":
751
+ print(f" {_DIM}{agent['name']}{_RESET}")
752
+ else:
753
+ print(f" ○ {_display_name(agent):<20} {_DIM}{agent['desc']}{_RESET}")
754
+ print()
746
755
 
747
756
  render()
748
757
 
@@ -1087,6 +1096,55 @@ def cmd_restore(args: argparse.Namespace) -> None:
1087
1096
  __import__('sys').exit(1)
1088
1097
 
1089
1098
 
1099
+ def cmd_index(args: argparse.Namespace) -> None:
1100
+ """Index a codebase into HipCortex symbolic knowledge graph."""
1101
+ url = args.url or os.environ.get("HIPCORTEX_URL", DEFAULT_URL)
1102
+ path = args.path or "."
1103
+ actor = args.actor or "codebase"
1104
+
1105
+ # Check server is reachable
1106
+ try:
1107
+ with urllib.request.urlopen(f"{url}/health", timeout=5) as r:
1108
+ if r.status != 200:
1109
+ print(f"✗ Server not reachable at {url}")
1110
+ sys.exit(1)
1111
+ except Exception:
1112
+ print(f"✗ Server not reachable at {url}")
1113
+ print(f" Start it with: hipcortex start")
1114
+ sys.exit(1)
1115
+
1116
+ try:
1117
+ from .client import HipCortexClient
1118
+ from .indexer import CodeIndexer
1119
+ except ImportError:
1120
+ from hipcortex.client import HipCortexClient
1121
+ from hipcortex.indexer import CodeIndexer
1122
+
1123
+ client = HipCortexClient(base_url=url)
1124
+ indexer = CodeIndexer(client=client)
1125
+
1126
+ extensions = None
1127
+ if args.extensions:
1128
+ extensions = [e if e.startswith(".") else f".{e}" for e in args.extensions.split(",")]
1129
+
1130
+ print(f"Indexing {path} into HipCortex symbolic graph...")
1131
+ print(f" Server: {url}")
1132
+ print(f" Actor: {actor}")
1133
+ if extensions:
1134
+ print(f" File types: {extensions}")
1135
+ print()
1136
+
1137
+ stats = indexer.index(path=path, actor=actor, extensions=extensions)
1138
+
1139
+ print(f" ✓ {stats['files']} files processed")
1140
+ print(f" ✓ {stats['nodes']} symbol nodes created")
1141
+ print(f" ✓ {stats['edges']} relationships created")
1142
+ print()
1143
+ print(f"Query code graph: GET {url}/graph")
1144
+ print(f"Search symbols: GET {url}/graph/search?q=<name>")
1145
+ print(f"In Claude Code: /hipcortex recall validate_token")
1146
+
1147
+
1090
1148
  # ─── Argument parser ──────────────────────────────────────────────────────────
1091
1149
 
1092
1150
  def build_parser() -> argparse.ArgumentParser:
@@ -1126,6 +1184,13 @@ def build_parser() -> argparse.ArgumentParser:
1126
1184
  p_restore.add_argument("file", help="Backup file path (.json)")
1127
1185
  p_restore.add_argument("--url", help="Server URL")
1128
1186
 
1187
+ # index
1188
+ p_index = sub.add_parser("index", help="Index a codebase into the HipCortex knowledge graph")
1189
+ p_index.add_argument("path", nargs="?", default=".", help="Directory or file to index (default: current dir)")
1190
+ p_index.add_argument("--url", help="Server URL")
1191
+ p_index.add_argument("--actor", help="Actor label for this codebase (default: codebase)")
1192
+ p_index.add_argument("--extensions", help="Comma-separated file extensions (default: .py,.ts,.js)")
1193
+
1129
1194
  return parser
1130
1195
 
1131
1196
 
@@ -1145,6 +1210,8 @@ def main() -> None:
1145
1210
  cmd_backup(args)
1146
1211
  elif args.command == "restore":
1147
1212
  cmd_restore(args)
1213
+ elif args.command == "index":
1214
+ cmd_index(args)
1148
1215
  else:
1149
1216
  parser.print_help()
1150
1217
  sys.exit(1)
@@ -203,6 +203,66 @@ class HipCortexClient:
203
203
  resp.raise_for_status()
204
204
  return resp.json()
205
205
 
206
+ def set_state(
207
+ self,
208
+ actor: str,
209
+ key: str,
210
+ value: str,
211
+ confidence: float = 1.0,
212
+ ) -> Dict[str, Any]:
213
+ """Store a structured state value for an actor.
214
+
215
+ Structured state is permanent (no TTL), high-confidence, pinned.
216
+ Use for: current goal, chosen stack, constraints, key decisions.
217
+
218
+ Args:
219
+ actor: Scope identifier (e.g. project name)
220
+ key: State key (e.g. "goal", "stack", "constraint:no-redis")
221
+ value: State value (free text or JSON string)
222
+ confidence: How confident (default 1.0)
223
+
224
+ Returns: stored record info
225
+ """
226
+ return self.add_memory(
227
+ actor=actor,
228
+ action=f"state:{key}",
229
+ target=value,
230
+ record_type="Symbolic",
231
+ priority="pinned",
232
+ metadata={"confidence": str(confidence), "source": "user-state"},
233
+ )
234
+
235
+ def get_state(
236
+ self,
237
+ actor: str,
238
+ key: Optional[str] = None,
239
+ ) -> Dict[str, Any]:
240
+ """Retrieve structured state for an actor.
241
+
242
+ Args:
243
+ actor: Scope identifier
244
+ key: Optional specific key (e.g. "goal"). If None, returns all state.
245
+
246
+ Returns: dict of {key: value} or latest value string if key specified
247
+ """
248
+ action_filter = f"state:{key}" if key else None
249
+ records = self.query_memory(actor=actor, action=action_filter, limit=50)
250
+
251
+ if key:
252
+ # Return latest value for this specific key
253
+ if records:
254
+ return {"key": key, "value": records[-1].get("target", ""), "actor": actor}
255
+ return {"key": key, "value": None, "actor": actor}
256
+
257
+ # Return all state as dict
258
+ state: Dict[str, Any] = {}
259
+ for rec in records:
260
+ action = rec.get("action", "")
261
+ if action.startswith("state:"):
262
+ k = action[len("state:"):]
263
+ state[k] = rec.get("target", "")
264
+ return state
265
+
206
266
  def consolidate(self, actor: Optional[str] = None, threshold: float = 0.8, dry_run: bool = True) -> Dict[str, Any]:
207
267
  """Find near-duplicate memories and optionally merge them."""
208
268
  params: Dict[str, Any] = {"threshold": threshold, "dry_run": dry_run}
@@ -0,0 +1,219 @@
1
+ """
2
+ HipCortex Code Intelligence Indexer
3
+ Uses Python stdlib ast + optional tree-sitter for multi-language support.
4
+ No external deps required for Python files.
5
+ """
6
+ from __future__ import annotations
7
+ import ast
8
+ import os
9
+ from pathlib import Path
10
+ from typing import Optional, Dict, List, Any
11
+
12
+
13
+ class CodeIndexer:
14
+ """Walks a codebase, extracts symbols, feeds into HipCortex symbolic graph."""
15
+
16
+ def __init__(self, client, base_url: str = "http://localhost:3030", api_key: Optional[str] = None):
17
+ """
18
+ Args:
19
+ client: HipCortexClient instance
20
+ base_url: HipCortex server URL (only needed if client not provided)
21
+ api_key: optional API key
22
+ """
23
+ self._client = client
24
+ self._node_cache: Dict[str, str] = {} # qualified_name -> node_id
25
+
26
+ def index(self, path: str, actor: str = "codebase",
27
+ extensions: Optional[List[str]] = None,
28
+ exclude_dirs: Optional[List[str]] = None) -> Dict[str, int]:
29
+ """
30
+ Index a directory or file into HipCortex symbolic graph.
31
+
32
+ Returns: {"nodes": N, "edges": N, "files": N}
33
+ """
34
+ if extensions is None:
35
+ extensions = [".py", ".ts", ".js"]
36
+ if exclude_dirs is None:
37
+ exclude_dirs = ["node_modules", ".git", "__pycache__", ".venv", "venv", "dist", "build"]
38
+
39
+ stats = {"nodes": 0, "edges": 0, "files": 0}
40
+ root = Path(path).resolve()
41
+
42
+ if root.is_file():
43
+ files = [root]
44
+ else:
45
+ files = [
46
+ f for f in root.rglob("*")
47
+ if f.suffix in extensions
48
+ and not any(ex in f.parts for ex in exclude_dirs)
49
+ ]
50
+
51
+ for f in files:
52
+ try:
53
+ n = self._index_file(f, root, actor)
54
+ stats["files"] += 1
55
+ stats["nodes"] += n.get("nodes", 0)
56
+ stats["edges"] += n.get("edges", 0)
57
+ except Exception:
58
+ pass # skip unparseable files
59
+
60
+ return stats
61
+
62
+ def _make_node(self, label: str, props: Dict[str, str]) -> Optional[str]:
63
+ """Create a node, return its ID. Cache by label to avoid duplicates."""
64
+ if label in self._node_cache:
65
+ return self._node_cache[label]
66
+ try:
67
+ result = self._client.create_node(label=label, properties=props)
68
+ node_id = result.get("id")
69
+ if node_id:
70
+ self._node_cache[label] = node_id
71
+ return node_id
72
+ except Exception:
73
+ return None
74
+
75
+ def _make_edge(self, from_id: str, to_id: str, relation: str) -> bool:
76
+ try:
77
+ self._client.create_edge(from_id=from_id, to_id=to_id, relation=relation)
78
+ return True
79
+ except Exception:
80
+ return False
81
+
82
+ def _index_file(self, file: Path, root: Path, actor: str) -> Dict[str, int]:
83
+ """Index a single file. Returns {"nodes": N, "edges": N}."""
84
+ rel = str(file.relative_to(root))
85
+ suffix = file.suffix
86
+
87
+ if suffix == ".py":
88
+ return self._index_python(file, rel, actor)
89
+ elif suffix in (".ts", ".js"):
90
+ return self._index_js_simple(file, rel, actor)
91
+ return {"nodes": 0, "edges": 0}
92
+
93
+ def _index_python(self, file: Path, rel_path: str, actor: str) -> Dict[str, int]:
94
+ """Parse Python file with ast, extract classes + functions + imports."""
95
+ try:
96
+ source = file.read_text(encoding="utf-8", errors="ignore")
97
+ tree = ast.parse(source, filename=str(file))
98
+ except SyntaxError:
99
+ return {"nodes": 0, "edges": 0}
100
+
101
+ nodes = 0
102
+ edges = 0
103
+
104
+ # File node
105
+ file_label = f"file:{rel_path}"
106
+ file_id = self._make_node(file_label, {
107
+ "type": "file", "path": rel_path, "language": "python"
108
+ })
109
+ if file_id:
110
+ nodes += 1
111
+
112
+ for node in ast.walk(tree):
113
+ # Class definitions
114
+ if isinstance(node, ast.ClassDef):
115
+ label = f"class:{rel_path}:{node.name}"
116
+ props = {
117
+ "type": "class",
118
+ "name": node.name,
119
+ "file": rel_path,
120
+ "line": str(node.lineno),
121
+ }
122
+ # Base classes
123
+ bases = [ast.unparse(b) for b in node.bases if isinstance(b, (ast.Name, ast.Attribute))]
124
+ if bases:
125
+ props["bases"] = ", ".join(bases[:3])
126
+
127
+ class_id = self._make_node(label, props)
128
+ if class_id:
129
+ nodes += 1
130
+ if file_id:
131
+ if self._make_edge(file_id, class_id, "defines"):
132
+ edges += 1
133
+ # Inheritance edges
134
+ for base in bases:
135
+ base_label = f"class:*:{base}"
136
+ # try to find existing base node
137
+ if base_label in self._node_cache:
138
+ if self._make_edge(class_id, self._node_cache[base_label], "inherits"):
139
+ edges += 1
140
+
141
+ # Function / method definitions
142
+ elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
143
+ # Get parent context by checking if this is inside a class
144
+ label = f"fn:{rel_path}:{node.name}"
145
+
146
+ # Build signature
147
+ args = []
148
+ for a in node.args.args:
149
+ if a.annotation:
150
+ args.append(f"{a.arg}: {ast.unparse(a.annotation)}")
151
+ else:
152
+ args.append(a.arg)
153
+
154
+ return_ann = ""
155
+ if node.returns:
156
+ return_ann = ast.unparse(node.returns)
157
+
158
+ props = {
159
+ "type": "function",
160
+ "name": node.name,
161
+ "file": rel_path,
162
+ "line": str(node.lineno),
163
+ "signature": f"def {node.name}({', '.join(args[:5])})" + (f" -> {return_ann}" if return_ann else ""),
164
+ }
165
+ if any(d.id == "property" if isinstance(d, ast.Name) else False for d in node.decorator_list):
166
+ props["is_property"] = "true"
167
+
168
+ fn_id = self._make_node(label, props)
169
+ if fn_id:
170
+ nodes += 1
171
+ if file_id:
172
+ if self._make_edge(file_id, fn_id, "defines"):
173
+ edges += 1
174
+
175
+ return {"nodes": nodes, "edges": edges}
176
+
177
+ def _index_js_simple(self, file: Path, rel_path: str, actor: str) -> Dict[str, int]:
178
+ """Simple regex-based JS/TS indexing (no AST parser for JS in stdlib)."""
179
+ import re
180
+ try:
181
+ source = file.read_text(encoding="utf-8", errors="ignore")
182
+ except Exception:
183
+ return {"nodes": 0, "edges": 0}
184
+
185
+ nodes = 0
186
+ edges = 0
187
+
188
+ file_label = f"file:{rel_path}"
189
+ file_id = self._make_node(file_label, {
190
+ "type": "file", "path": rel_path,
191
+ "language": "typescript" if rel_path.endswith(".ts") else "javascript"
192
+ })
193
+ if file_id:
194
+ nodes += 1
195
+
196
+ # Extract exported functions/classes
197
+ patterns = [
198
+ (r'export\s+(?:async\s+)?function\s+(\w+)', "function"),
199
+ (r'export\s+class\s+(\w+)', "class"),
200
+ (r'export\s+const\s+(\w+)\s*=\s*(?:async\s+)?\(', "function"),
201
+ (r'export\s+interface\s+(\w+)', "interface"),
202
+ (r'export\s+type\s+(\w+)', "type"),
203
+ ]
204
+
205
+ for pat, kind in patterns:
206
+ for m in re.finditer(pat, source):
207
+ name = m.group(1)
208
+ label = f"{kind}:{rel_path}:{name}"
209
+ sym_id = self._make_node(label, {
210
+ "type": kind, "name": name, "file": rel_path,
211
+ "line": str(source[:m.start()].count("\n") + 1),
212
+ })
213
+ if sym_id:
214
+ nodes += 1
215
+ if file_id:
216
+ if self._make_edge(file_id, sym_id, "defines"):
217
+ edges += 1
218
+
219
+ return {"nodes": nodes, "edges": edges}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hipcortex
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: Persistent causal memory for AI agents -- LangChain, LlamaIndex, AutoGen, CrewAI
5
5
  Author: HipCortex Contributors
6
6
  License: Apache-2.0
@@ -5,6 +5,7 @@ hipcortex/__init__.py
5
5
  hipcortex/async_client.py
6
6
  hipcortex/cli.py
7
7
  hipcortex/client.py
8
+ hipcortex/indexer.py
8
9
  hipcortex/langchain_memory.py
9
10
  hipcortex/llamaindex_storage.py
10
11
  hipcortex.egg-info/PKG-INFO
@@ -1,49 +1,49 @@
1
- [build-system]
2
- requires = ["setuptools>=68", "wheel"]
3
- build-backend = "setuptools.build_meta"
4
-
5
- [project]
6
- name = "hipcortex"
7
- version = "0.3.0"
8
- description = "Persistent causal memory for AI agents -- LangChain, LlamaIndex, AutoGen, CrewAI"
9
- readme = "README.md"
10
- license = {text = "Apache-2.0"}
11
- requires-python = ">=3.9"
12
- authors = [{name = "HipCortex Contributors"}]
13
- keywords = ["ai", "memory", "langchain", "autogen", "crewai", "llm", "agents", "rag"]
14
- classifiers = [
15
- "Programming Language :: Python :: 3",
16
- "License :: OSI Approved :: Apache Software License",
17
- "Topic :: Scientific/Engineering :: Artificial Intelligence",
18
- "Intended Audience :: Developers",
19
- ]
20
- dependencies = ["requests>=2.28", "httpx>=0.27"]
21
-
22
- [project.optional-dependencies]
23
- langchain = ["langchain-core>=0.1"]
24
- llamaindex = ["llama-index-core>=0.10"]
25
- crewai = ["crewai>=0.28", "crewai-tools>=0.1"]
26
- autogen = ["pyautogen>=0.2"]
27
- benchmark = ["mem0ai>=0.1", "tabulate>=0.9"]
28
- all = ["langchain-core>=0.1", "llama-index-core>=0.10",
29
- "crewai>=0.28", "crewai-tools>=0.1",
30
- "pyautogen>=0.2", "mem0ai>=0.1", "tabulate>=0.9"]
31
-
32
- [project.scripts]
33
- hipcortex = "hipcortex.cli:main"
34
-
35
- [project.urls]
36
- Homepage = "https://github.com/farmountain/HipCortex"
37
- Repository = "https://github.com/farmountain/HipCortex"
38
- Issues = "https://github.com/farmountain/HipCortex/issues"
39
- Benchmark = "https://github.com/farmountain/HipCortex/blob/main/BENCHMARK.md"
40
-
41
- [tool.setuptools.packages.find]
42
- where = ["."]
43
- include = ["hipcortex*"]
44
-
45
- [tool.setuptools.package-data]
46
- "hipcortex.install" = ["SKILL.md"]
47
-
48
- [tool.pytest.ini_options]
49
- asyncio_mode = "auto"
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "hipcortex"
7
+ version = "0.3.2"
8
+ description = "Persistent causal memory for AI agents -- LangChain, LlamaIndex, AutoGen, CrewAI"
9
+ readme = "README.md"
10
+ license = {text = "Apache-2.0"}
11
+ requires-python = ">=3.9"
12
+ authors = [{name = "HipCortex Contributors"}]
13
+ keywords = ["ai", "memory", "langchain", "autogen", "crewai", "llm", "agents", "rag"]
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "License :: OSI Approved :: Apache Software License",
17
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
18
+ "Intended Audience :: Developers",
19
+ ]
20
+ dependencies = ["requests>=2.28", "httpx>=0.27"]
21
+
22
+ [project.optional-dependencies]
23
+ langchain = ["langchain-core>=0.1"]
24
+ llamaindex = ["llama-index-core>=0.10"]
25
+ crewai = ["crewai>=0.28", "crewai-tools>=0.1"]
26
+ autogen = ["pyautogen>=0.2"]
27
+ benchmark = ["mem0ai>=0.1", "tabulate>=0.9"]
28
+ all = ["langchain-core>=0.1", "llama-index-core>=0.10",
29
+ "crewai>=0.28", "crewai-tools>=0.1",
30
+ "pyautogen>=0.2", "mem0ai>=0.1", "tabulate>=0.9"]
31
+
32
+ [project.scripts]
33
+ hipcortex = "hipcortex.cli:main"
34
+
35
+ [project.urls]
36
+ Homepage = "https://github.com/farmountain/HipCortex"
37
+ Repository = "https://github.com/farmountain/HipCortex"
38
+ Issues = "https://github.com/farmountain/HipCortex/issues"
39
+ Benchmark = "https://github.com/farmountain/HipCortex/blob/main/BENCHMARK.md"
40
+
41
+ [tool.setuptools.packages.find]
42
+ where = ["."]
43
+ include = ["hipcortex*"]
44
+
45
+ [tool.setuptools.package-data]
46
+ "hipcortex.install" = ["SKILL.md"]
47
+
48
+ [tool.pytest.ini_options]
49
+ asyncio_mode = "auto"
File without changes
File without changes
File without changes