cortex-local 2.1.0__tar.gz → 2.1.12__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.
- {cortex_local-2.1.0 → cortex_local-2.1.12}/PKG-INFO +1 -1
- {cortex_local-2.1.0 → cortex_local-2.1.12}/cortex/config.py +2 -0
- {cortex_local-2.1.0 → cortex_local-2.1.12}/cortex/core/chunker.py +92 -5
- {cortex_local-2.1.0 → cortex_local-2.1.12}/cortex/mcp_server.py +2 -2
- {cortex_local-2.1.0 → cortex_local-2.1.12}/pyproject.toml +6 -1
- {cortex_local-2.1.0 → cortex_local-2.1.12}/README.md +0 -0
- {cortex_local-2.1.0 → cortex_local-2.1.12}/cortex/__init__.py +0 -0
- {cortex_local-2.1.0 → cortex_local-2.1.12}/cortex/cli.py +0 -0
- {cortex_local-2.1.0 → cortex_local-2.1.12}/cortex/core/__init__.py +0 -0
- {cortex_local-2.1.0 → cortex_local-2.1.12}/cortex/core/cache.py +0 -0
- {cortex_local-2.1.0 → cortex_local-2.1.12}/cortex/core/code_graph.py +0 -0
- {cortex_local-2.1.0 → cortex_local-2.1.12}/cortex/core/global_graph.py +0 -0
- {cortex_local-2.1.0 → cortex_local-2.1.12}/cortex/core/graph.py +0 -0
- {cortex_local-2.1.0 → cortex_local-2.1.12}/cortex/core/notes_graph.py +0 -0
- {cortex_local-2.1.0 → cortex_local-2.1.12}/cortex/embedder.py +0 -0
- {cortex_local-2.1.0 → cortex_local-2.1.12}/cortex/indexer.py +0 -0
- {cortex_local-2.1.0 → cortex_local-2.1.12}/cortex/state.py +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Paths and constants for cortex local mode."""
|
|
2
2
|
|
|
3
|
+
import os
|
|
3
4
|
import shutil
|
|
4
5
|
from pathlib import Path
|
|
5
6
|
|
|
@@ -9,6 +10,7 @@ ACTIVE_WORKSPACE_FILE = CORTEX_DIR / "active_workspace"
|
|
|
9
10
|
|
|
10
11
|
EMBED_MODEL = "nomic-ai/nomic-embed-text-v1.5"
|
|
11
12
|
VECTOR_SIZE = 768
|
|
13
|
+
PPR_THRESHOLD = float(os.environ.get("PPR_THRESHOLD", "0.03"))
|
|
12
14
|
|
|
13
15
|
try:
|
|
14
16
|
from importlib.metadata import version
|
|
@@ -17,6 +17,86 @@ CHUNK_LINES = 30
|
|
|
17
17
|
OVERLAP_LINES = 5
|
|
18
18
|
MAX_CHUNK_LINES = 80
|
|
19
19
|
|
|
20
|
+
_FRAMEWORK_FILENAMES = {
|
|
21
|
+
"hooks.server": "sveltekit server hooks handle",
|
|
22
|
+
"hooks.client": "sveltekit client hooks",
|
|
23
|
+
"+page": "sveltekit page component",
|
|
24
|
+
"+layout": "sveltekit layout component",
|
|
25
|
+
"+server": "sveltekit api route endpoint",
|
|
26
|
+
"+page.server": "sveltekit page server load action",
|
|
27
|
+
"+layout.server": "sveltekit layout server load",
|
|
28
|
+
"+error": "sveltekit error page",
|
|
29
|
+
"svelte.config": "sveltekit",
|
|
30
|
+
"next.config": "nextjs",
|
|
31
|
+
"nuxt.config": "nuxt",
|
|
32
|
+
"astro.config": "astro",
|
|
33
|
+
"remix.config": "remix",
|
|
34
|
+
"_app": "nextjs",
|
|
35
|
+
"_document": "nextjs",
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
_FRAMEWORK_IMPORTS = [
|
|
39
|
+
("@sveltejs/kit", "sveltekit"),
|
|
40
|
+
("from 'react'", "react"),
|
|
41
|
+
('from "react"', "react"),
|
|
42
|
+
("from 'next/", "nextjs"),
|
|
43
|
+
('from "next/', "nextjs"),
|
|
44
|
+
("from 'vue'", "vue"),
|
|
45
|
+
('from "vue"', "vue"),
|
|
46
|
+
("@angular/core", "angular"),
|
|
47
|
+
("from 'express'", "express"),
|
|
48
|
+
('from "express"', "express"),
|
|
49
|
+
("from 'fastify'", "fastify"),
|
|
50
|
+
('from "fastify"', "fastify"),
|
|
51
|
+
("from 'solid-js'", "solidjs"),
|
|
52
|
+
('from "solid-js"', "solidjs"),
|
|
53
|
+
("@remix-run/", "remix"),
|
|
54
|
+
("from 'astro'", "astro"),
|
|
55
|
+
('from "astro"', "astro"),
|
|
56
|
+
("from fastapi", "fastapi"),
|
|
57
|
+
("import fastapi", "fastapi"),
|
|
58
|
+
("from django", "django"),
|
|
59
|
+
("import django", "django"),
|
|
60
|
+
("from flask", "flask"),
|
|
61
|
+
("import flask", "flask"),
|
|
62
|
+
("from starlette", "starlette"),
|
|
63
|
+
("from pydantic", "pydantic"),
|
|
64
|
+
("from sqlalchemy", "sqlalchemy"),
|
|
65
|
+
("import torch", "pytorch"),
|
|
66
|
+
("from torch", "pytorch"),
|
|
67
|
+
("import tensorflow", "tensorflow"),
|
|
68
|
+
("from tensorflow", "tensorflow"),
|
|
69
|
+
("import numpy", "numpy"),
|
|
70
|
+
("import pandas", "pandas"),
|
|
71
|
+
("from sklearn", "scikit-learn"),
|
|
72
|
+
("from transformers", "huggingface"),
|
|
73
|
+
("from qdrant_client", "qdrant"),
|
|
74
|
+
("from fastembed", "fastembed"),
|
|
75
|
+
("import io.ktor", "ktor"),
|
|
76
|
+
("import org.springframework", "spring"),
|
|
77
|
+
("import androidx", "android"),
|
|
78
|
+
("gin-gonic/gin", "gin"),
|
|
79
|
+
("gofiber/fiber", "fiber"),
|
|
80
|
+
("use actix", "actix"),
|
|
81
|
+
("use axum", "axum"),
|
|
82
|
+
("use tokio", "tokio"),
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _extra_tokens(rel: str, lines: list) -> str:
|
|
87
|
+
stem = Path(rel).stem
|
|
88
|
+
parts = []
|
|
89
|
+
if stem in _FRAMEWORK_FILENAMES:
|
|
90
|
+
parts.append(_FRAMEWORK_FILENAMES[stem])
|
|
91
|
+
header = "\n".join(lines[:50])
|
|
92
|
+
seen = set(parts)
|
|
93
|
+
for pattern, framework in _FRAMEWORK_IMPORTS:
|
|
94
|
+
if pattern in header and framework not in seen:
|
|
95
|
+
parts.append(framework)
|
|
96
|
+
seen.add(framework)
|
|
97
|
+
return " ".join(parts)
|
|
98
|
+
|
|
99
|
+
|
|
20
100
|
try:
|
|
21
101
|
from tree_sitter import Language, Parser as _TSParser
|
|
22
102
|
import tree_sitter_python as _tspy
|
|
@@ -49,7 +129,7 @@ except Exception:
|
|
|
49
129
|
_TS_SEMANTIC = {}
|
|
50
130
|
|
|
51
131
|
|
|
52
|
-
def _sliding_window(lines: list, start: int, end: int, repo_name: str, rel: str, language: str, github_url_base: str = "") -> list:
|
|
132
|
+
def _sliding_window(lines: list, start: int, end: int, repo_name: str, rel: str, language: str, github_url_base: str = "", extra_tokens: str = "") -> list:
|
|
53
133
|
step = CHUNK_LINES - OVERLAP_LINES
|
|
54
134
|
chunks = []
|
|
55
135
|
i = start
|
|
@@ -58,10 +138,13 @@ def _sliding_window(lines: list, start: int, end: int, repo_name: str, rel: str,
|
|
|
58
138
|
body = "\n".join(lines[i:j]).strip()
|
|
59
139
|
if body:
|
|
60
140
|
url = f"{github_url_base}/{rel}#L{i+1}-L{j}" if github_url_base else ""
|
|
141
|
+
header = f"# {repo_name}/{rel} (lines {i+1}-{j})"
|
|
142
|
+
if extra_tokens:
|
|
143
|
+
header += f"\n# {extra_tokens}"
|
|
61
144
|
chunks.append({
|
|
62
145
|
"repo": repo_name, "file": rel, "language": language,
|
|
63
146
|
"start_line": i + 1, "end_line": j,
|
|
64
|
-
"text": f"
|
|
147
|
+
"text": f"{header}\n\n{body}",
|
|
65
148
|
"github_url": url,
|
|
66
149
|
})
|
|
67
150
|
if j == end:
|
|
@@ -110,6 +193,7 @@ def chunk_file(path: Path, repo_name: str, base_dir: Path | None = None, github_
|
|
|
110
193
|
except ValueError:
|
|
111
194
|
rel = path.name
|
|
112
195
|
language = LANG_MAP.get(ext, ext.lstrip("."))
|
|
196
|
+
extra = _extra_tokens(rel, lines)
|
|
113
197
|
|
|
114
198
|
if _TS_AVAILABLE and ext in _TS_LANGUAGES:
|
|
115
199
|
try:
|
|
@@ -123,19 +207,22 @@ def chunk_file(path: Path, repo_name: str, base_dir: Path | None = None, github_
|
|
|
123
207
|
s = node.start_point[0]
|
|
124
208
|
e = node.end_point[0] + 1
|
|
125
209
|
if e - s > MAX_CHUNK_LINES:
|
|
126
|
-
chunks.extend(_sliding_window(lines, s, e, repo_name, rel, language, github_url_base))
|
|
210
|
+
chunks.extend(_sliding_window(lines, s, e, repo_name, rel, language, github_url_base, extra))
|
|
127
211
|
else:
|
|
128
212
|
body = "\n".join(lines[s:e]).strip()
|
|
129
213
|
if body:
|
|
130
214
|
url = f"{github_url_base}/{rel}#L{s+1}-L{e}" if github_url_base else ""
|
|
215
|
+
header = f"# {repo_name}/{rel} (lines {s+1}-{e})"
|
|
216
|
+
if extra:
|
|
217
|
+
header += f"\n# {extra}"
|
|
131
218
|
chunks.append({
|
|
132
219
|
"repo": repo_name, "file": rel, "language": language,
|
|
133
220
|
"start_line": s + 1, "end_line": e,
|
|
134
|
-
"text": f"
|
|
221
|
+
"text": f"{header}\n\n{body}",
|
|
135
222
|
"github_url": url,
|
|
136
223
|
})
|
|
137
224
|
return chunks
|
|
138
225
|
except Exception:
|
|
139
226
|
pass
|
|
140
227
|
|
|
141
|
-
return _sliding_window(lines, 0, len(lines), repo_name, rel, language, github_url_base)
|
|
228
|
+
return _sliding_window(lines, 0, len(lines), repo_name, rel, language, github_url_base, extra)
|
|
@@ -13,7 +13,7 @@ from qdrant_client.models import Prefetch, Fusion, SparseVector
|
|
|
13
13
|
from .config import (
|
|
14
14
|
qdrant_path, data_dir, VERSION, VECTOR_SIZE,
|
|
15
15
|
WORKSPACES_DIR, get_active_workspace, set_active_workspace,
|
|
16
|
-
get_workspace_dir,
|
|
16
|
+
get_workspace_dir, PPR_THRESHOLD,
|
|
17
17
|
)
|
|
18
18
|
from .embedder import embed, sparse_embed
|
|
19
19
|
from .state import _stats, get_graph_meta, save_stats, invalidate_graph_cache
|
|
@@ -59,7 +59,7 @@ def _ppr_block(matched_files: list, matched_scores: list) -> str | None:
|
|
|
59
59
|
except Exception:
|
|
60
60
|
return None
|
|
61
61
|
graph_path = data_dir() / "graph_notes.json"
|
|
62
|
-
extras, reason = ppr_augment(matched_files, matched_scores, graph_path, _return_reason=True)
|
|
62
|
+
extras, reason = ppr_augment(matched_files, matched_scores, graph_path, threshold=PPR_THRESHOLD, _return_reason=True)
|
|
63
63
|
if extras:
|
|
64
64
|
_stats["ppr_fires"] += 1
|
|
65
65
|
_stats["ppr_results_added"] += len(extras)
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "cortex-local"
|
|
7
|
-
|
|
7
|
+
dynamic = ["version"]
|
|
8
8
|
description = "Local semantic search MCP server — notes + code, embedded Qdrant, fastembed"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -25,5 +25,10 @@ cortex = "cortex.cli:cli"
|
|
|
25
25
|
[project.entry-points."mcp.servers"]
|
|
26
26
|
cortex = "cortex.mcp_server:run"
|
|
27
27
|
|
|
28
|
+
[tool.hatch.version]
|
|
29
|
+
source = "regex"
|
|
30
|
+
path = "../VERSION"
|
|
31
|
+
pattern = "^(?P<version>[0-9]+\\.[0-9]+\\.[0-9]+)"
|
|
32
|
+
|
|
28
33
|
[tool.hatch.build.targets.wheel]
|
|
29
34
|
packages = ["cortex"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|