basic-memory 0.23.1.dev20__py3-none-any.whl → 0.23.1.dev27__py3-none-any.whl
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.
- basic_memory/alembic/versions/7f6a2b8c9d10_index_full_postgres_note_content.py +56 -0
- basic_memory/api/v2/routers/project_router.py +22 -0
- basic_memory/cli/commands/doctor.py +19 -3
- basic_memory/mcp/clients/project.py +7 -0
- basic_memory/repository/search_repository.py +4 -0
- basic_memory/repository/search_repository_base.py +15 -0
- basic_memory/services/project_service.py +36 -22
- basic_memory/services/search_service.py +11 -3
- {basic_memory-0.23.1.dev20.dist-info → basic_memory-0.23.1.dev27.dist-info}/METADATA +1 -1
- {basic_memory-0.23.1.dev20.dist-info → basic_memory-0.23.1.dev27.dist-info}/RECORD +13 -13
- {basic_memory-0.23.1.dev20.dist-info → basic_memory-0.23.1.dev27.dist-info}/WHEEL +0 -0
- {basic_memory-0.23.1.dev20.dist-info → basic_memory-0.23.1.dev27.dist-info}/entry_points.txt +0 -0
- {basic_memory-0.23.1.dev20.dist-info → basic_memory-0.23.1.dev27.dist-info}/licenses/LICENSE +0 -0
|
@@ -22,6 +22,62 @@ def upgrade() -> None:
|
|
|
22
22
|
"""Index complete note bodies as bounded PostgreSQL FTS chunks."""
|
|
23
23
|
connection = op.get_bind()
|
|
24
24
|
if connection.dialect.name == "postgresql":
|
|
25
|
+
# --- Repair: recreate search_index if a destructive reindex removed it ---
|
|
26
|
+
# Trigger: search_index does not exist. Through v0.23.0, the per-project
|
|
27
|
+
# search reindex ran DROP TABLE IF EXISTS search_index, and on Postgres
|
|
28
|
+
# nothing outside migrations recreates that table.
|
|
29
|
+
# Why: the chunk backfill below reads search_index and the chunks table
|
|
30
|
+
# declares a foreign key to it, so without repair this migration fails
|
|
31
|
+
# permanently and blocks the database from ever reaching head.
|
|
32
|
+
# Outcome: healthy databases no-op on IF NOT EXISTS; a repaired database
|
|
33
|
+
# gets an empty index that the next full reindex repopulates. The DDL
|
|
34
|
+
# mirrors the current schema in models/search.py.
|
|
35
|
+
op.execute("""
|
|
36
|
+
CREATE TABLE IF NOT EXISTS search_index (
|
|
37
|
+
id INTEGER NOT NULL,
|
|
38
|
+
project_id INTEGER NOT NULL,
|
|
39
|
+
title TEXT,
|
|
40
|
+
content_stems TEXT,
|
|
41
|
+
content_snippet TEXT,
|
|
42
|
+
permalink VARCHAR,
|
|
43
|
+
file_path VARCHAR,
|
|
44
|
+
type VARCHAR,
|
|
45
|
+
from_id INTEGER,
|
|
46
|
+
to_id INTEGER,
|
|
47
|
+
relation_type VARCHAR,
|
|
48
|
+
entity_id INTEGER,
|
|
49
|
+
category VARCHAR,
|
|
50
|
+
metadata JSONB,
|
|
51
|
+
created_at TIMESTAMP WITH TIME ZONE,
|
|
52
|
+
updated_at TIMESTAMP WITH TIME ZONE,
|
|
53
|
+
textsearchable_index_col tsvector GENERATED ALWAYS AS (
|
|
54
|
+
to_tsvector(
|
|
55
|
+
'english',
|
|
56
|
+
coalesce(title, '') || ' ' ||
|
|
57
|
+
coalesce(content_stems, '')
|
|
58
|
+
)
|
|
59
|
+
) STORED,
|
|
60
|
+
PRIMARY KEY (id, type, project_id),
|
|
61
|
+
FOREIGN KEY (project_id) REFERENCES project(id) ON DELETE CASCADE
|
|
62
|
+
)
|
|
63
|
+
""")
|
|
64
|
+
op.execute("""
|
|
65
|
+
CREATE INDEX IF NOT EXISTS ix_search_index_project_id
|
|
66
|
+
ON search_index (project_id)
|
|
67
|
+
""")
|
|
68
|
+
op.execute("""
|
|
69
|
+
CREATE INDEX IF NOT EXISTS idx_search_index_fts
|
|
70
|
+
ON search_index USING gin(textsearchable_index_col)
|
|
71
|
+
""")
|
|
72
|
+
op.execute("""
|
|
73
|
+
CREATE INDEX IF NOT EXISTS idx_search_index_metadata_gin
|
|
74
|
+
ON search_index USING gin(metadata jsonb_path_ops)
|
|
75
|
+
""")
|
|
76
|
+
op.execute("""
|
|
77
|
+
CREATE UNIQUE INDEX IF NOT EXISTS uix_search_index_permalink_project
|
|
78
|
+
ON search_index (permalink, project_id)
|
|
79
|
+
WHERE permalink IS NOT NULL
|
|
80
|
+
""")
|
|
25
81
|
op.execute("""
|
|
26
82
|
CREATE TABLE search_index_fts_chunks (
|
|
27
83
|
project_id INTEGER NOT NULL,
|
|
@@ -221,6 +221,28 @@ async def add_project(
|
|
|
221
221
|
raise HTTPException(status_code=400, detail=str(e))
|
|
222
222
|
|
|
223
223
|
|
|
224
|
+
@router.post("/doctor", response_model=ProjectStatusResponse, status_code=201)
|
|
225
|
+
async def add_doctor_project(project_service: ProjectServiceDep) -> ProjectStatusResponse:
|
|
226
|
+
"""Create a server-generated disposable project for the local doctor check."""
|
|
227
|
+
try:
|
|
228
|
+
new_project = await project_service.add_doctor_project()
|
|
229
|
+
except ValueError as e:
|
|
230
|
+
raise HTTPException(status_code=400, detail=str(e))
|
|
231
|
+
|
|
232
|
+
return ProjectStatusResponse(
|
|
233
|
+
message=f"Project '{new_project.name}' added successfully",
|
|
234
|
+
status="success",
|
|
235
|
+
default=new_project.is_default or False,
|
|
236
|
+
new_project=ProjectItem(
|
|
237
|
+
id=new_project.id,
|
|
238
|
+
external_id=new_project.external_id,
|
|
239
|
+
name=new_project.name,
|
|
240
|
+
path=new_project.path,
|
|
241
|
+
is_default=new_project.is_default or False,
|
|
242
|
+
),
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
|
|
224
246
|
@router.post("/config/sync", response_model=ProjectStatusResponse)
|
|
225
247
|
async def synchronize_projects(
|
|
226
248
|
project_service: ProjectServiceDep,
|
|
@@ -5,6 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
import tempfile
|
|
6
6
|
import uuid
|
|
7
7
|
from pathlib import Path
|
|
8
|
+
from typing import Protocol
|
|
8
9
|
|
|
9
10
|
from loguru import logger
|
|
10
11
|
from rich.console import Console
|
|
@@ -23,6 +24,14 @@ from basic_memory.schemas import ProjectIndexRunResponse
|
|
|
23
24
|
console = Console()
|
|
24
25
|
|
|
25
26
|
|
|
27
|
+
class DoctorProjectClient(Protocol):
|
|
28
|
+
"""Project-client capability required to clean up doctor state."""
|
|
29
|
+
|
|
30
|
+
async def delete_project(
|
|
31
|
+
self, project_external_id: str, delete_notes: bool = False
|
|
32
|
+
) -> object: ...
|
|
33
|
+
|
|
34
|
+
|
|
26
35
|
def _is_default_project_delete_error(error: Exception) -> bool:
|
|
27
36
|
"""Return True only for the API guard that blocks deleting the default project."""
|
|
28
37
|
error_text = str(error)
|
|
@@ -61,14 +70,14 @@ async def _delete_doctor_project_locally(project_name: str, project_id: str) ->
|
|
|
61
70
|
|
|
62
71
|
|
|
63
72
|
async def _delete_doctor_project(
|
|
64
|
-
project_client:
|
|
73
|
+
project_client: DoctorProjectClient, project_name: str, project_id: str
|
|
65
74
|
) -> None:
|
|
66
75
|
"""Delete the generated doctor project without weakening the public API guard."""
|
|
67
76
|
# Deferred: ToolError lives in FastMCP's runtime, which must not load at CLI startup (#886).
|
|
68
77
|
from fastmcp.exceptions import ToolError
|
|
69
78
|
|
|
70
79
|
try:
|
|
71
|
-
await project_client.delete_project(project_id)
|
|
80
|
+
await project_client.delete_project(project_id, delete_notes=True)
|
|
72
81
|
except ToolError as exc:
|
|
73
82
|
if not _is_default_project_delete_error(exc):
|
|
74
83
|
raise
|
|
@@ -127,9 +136,16 @@ async def run_doctor() -> None:
|
|
|
127
136
|
project_id: str | None = None
|
|
128
137
|
|
|
129
138
|
try:
|
|
130
|
-
|
|
139
|
+
from basic_memory.config import ConfigManager
|
|
140
|
+
|
|
141
|
+
status = (
|
|
142
|
+
await project_client.create_doctor_project()
|
|
143
|
+
if ConfigManager().config.project_root
|
|
144
|
+
else await project_client.create_project(project_request.model_dump())
|
|
145
|
+
)
|
|
131
146
|
if not status.new_project:
|
|
132
147
|
raise ValueError("Failed to create doctor project")
|
|
148
|
+
project_name = status.new_project.name
|
|
133
149
|
project_id = status.new_project.external_id
|
|
134
150
|
# Use the resolved path from the server — when project_root is configured,
|
|
135
151
|
# the actual project directory differs from the requested temp_path
|
|
@@ -78,6 +78,13 @@ class ProjectClient:
|
|
|
78
78
|
)
|
|
79
79
|
return ProjectStatusResponse.model_validate(response.json())
|
|
80
80
|
|
|
81
|
+
async def create_doctor_project(self) -> ProjectStatusResponse:
|
|
82
|
+
"""Create the server-generated disposable project used by doctor."""
|
|
83
|
+
from basic_memory.mcp.tools.utils import call_post
|
|
84
|
+
|
|
85
|
+
response = await call_post(self.http_client, "/v2/projects/doctor")
|
|
86
|
+
return ProjectStatusResponse.model_validate(response.json())
|
|
87
|
+
|
|
81
88
|
async def delete_project(
|
|
82
89
|
self, project_external_id: str, delete_notes: bool = False
|
|
83
90
|
) -> ProjectStatusResponse:
|
|
@@ -129,6 +129,10 @@ class SearchRepository(Protocol):
|
|
|
129
129
|
"""Delete item by permalink."""
|
|
130
130
|
...
|
|
131
131
|
|
|
132
|
+
async def delete_project_search_rows(self) -> None:
|
|
133
|
+
"""Delete every full-text search row owned by this project."""
|
|
134
|
+
...
|
|
135
|
+
|
|
132
136
|
async def delete_by_entity_id(self, entity_id: int) -> None:
|
|
133
137
|
"""Delete items by entity ID."""
|
|
134
138
|
...
|
|
@@ -1143,6 +1143,21 @@ class SearchRepositoryBase(ABC):
|
|
|
1143
1143
|
)
|
|
1144
1144
|
await session.commit()
|
|
1145
1145
|
|
|
1146
|
+
async def delete_project_search_rows(self) -> None:
|
|
1147
|
+
"""Delete every full-text search row owned by this repository's project.
|
|
1148
|
+
|
|
1149
|
+
Shared across backends: both store rows in `search_index` keyed by
|
|
1150
|
+
project_id, and a project-scoped DELETE leaves sibling projects in the
|
|
1151
|
+
same database untouched. On Postgres the bounded FTS chunk rows follow
|
|
1152
|
+
via their ON DELETE CASCADE foreign key.
|
|
1153
|
+
"""
|
|
1154
|
+
async with db.scoped_session(self.session_maker) as session:
|
|
1155
|
+
await session.execute(
|
|
1156
|
+
text("DELETE FROM search_index WHERE project_id = :project_id"),
|
|
1157
|
+
{"project_id": self.project_id},
|
|
1158
|
+
)
|
|
1159
|
+
await session.commit()
|
|
1160
|
+
|
|
1146
1161
|
async def execute_query(
|
|
1147
1162
|
self,
|
|
1148
1163
|
query: Executable,
|
|
@@ -4,6 +4,7 @@ import asyncio
|
|
|
4
4
|
import json
|
|
5
5
|
import os
|
|
6
6
|
import shutil
|
|
7
|
+
import uuid
|
|
7
8
|
from collections.abc import Callable
|
|
8
9
|
from datetime import datetime
|
|
9
10
|
from pathlib import Path
|
|
@@ -190,7 +191,9 @@ class ProjectService:
|
|
|
190
191
|
# Not nested in either direction
|
|
191
192
|
return False
|
|
192
193
|
|
|
193
|
-
async def add_project(
|
|
194
|
+
async def add_project(
|
|
195
|
+
self, name: str, path: str, set_default: bool = False, *, allow_nested: bool = False
|
|
196
|
+
) -> None:
|
|
194
197
|
"""Add a new project to the configuration and database.
|
|
195
198
|
|
|
196
199
|
Args:
|
|
@@ -240,27 +243,25 @@ class ProjectService:
|
|
|
240
243
|
f"In cloud mode, paths are normalized to lowercase to prevent case-sensitivity issues."
|
|
241
244
|
) # pragma: no cover
|
|
242
245
|
|
|
243
|
-
#
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
f"Projects cannot share directory trees."
|
|
263
|
-
)
|
|
246
|
+
# Doctor creates a disposable project inside the configured project root.
|
|
247
|
+
# It must be allowed to coexist with the existing root project.
|
|
248
|
+
if not allow_nested:
|
|
249
|
+
for existing in existing_projects:
|
|
250
|
+
if self._check_nested_paths(resolved_path, existing.path):
|
|
251
|
+
p_new = Path(resolved_path).resolve()
|
|
252
|
+
p_existing = Path(existing.path).resolve()
|
|
253
|
+
if p_new.is_relative_to(p_existing):
|
|
254
|
+
raise ValueError(
|
|
255
|
+
f"Cannot create project at '{resolved_path}': "
|
|
256
|
+
f"path is nested within existing project '{existing.name}' at '{existing.path}'. "
|
|
257
|
+
f"Projects cannot share directory trees."
|
|
258
|
+
)
|
|
259
|
+
else:
|
|
260
|
+
raise ValueError(
|
|
261
|
+
f"Cannot create project at '{resolved_path}': "
|
|
262
|
+
f"existing project '{existing.name}' at '{existing.path}' is nested within this path. "
|
|
263
|
+
f"Projects cannot share directory trees."
|
|
264
|
+
)
|
|
264
265
|
|
|
265
266
|
# Ensure the project directory exists on disk.
|
|
266
267
|
# Trigger: project_root not set means local filesystem mode (not S3/cloud)
|
|
@@ -332,6 +333,19 @@ class ProjectService:
|
|
|
332
333
|
|
|
333
334
|
logger.info(f"Project '{name}' added at {resolved_path}")
|
|
334
335
|
|
|
336
|
+
async def add_doctor_project(self) -> Project:
|
|
337
|
+
"""Create a server-generated disposable project under the configured root."""
|
|
338
|
+
project_root = self.config_manager.config.project_root
|
|
339
|
+
if not project_root:
|
|
340
|
+
raise ValueError("Doctor projects require BASIC_MEMORY_PROJECT_ROOT")
|
|
341
|
+
|
|
342
|
+
project_name = f"doctor-{uuid.uuid4().hex[:8]}"
|
|
343
|
+
await self.add_project(project_name, project_root, allow_nested=True)
|
|
344
|
+
project = await self.get_project(project_name)
|
|
345
|
+
if project is None: # pragma: no cover
|
|
346
|
+
raise ValueError("Failed to retrieve doctor project")
|
|
347
|
+
return project
|
|
348
|
+
|
|
335
349
|
async def remove_project(self, name: str, delete_notes: bool = False) -> None:
|
|
336
350
|
"""Remove a project from configuration and database.
|
|
337
351
|
|
|
@@ -11,7 +11,6 @@ from typing import Any, List, Optional, Set, Dict
|
|
|
11
11
|
from dateparser import parse
|
|
12
12
|
from fastapi import BackgroundTasks
|
|
13
13
|
from loguru import logger
|
|
14
|
-
from sqlalchemy import text
|
|
15
14
|
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
|
|
16
15
|
|
|
17
16
|
import logfire
|
|
@@ -152,11 +151,20 @@ class SearchService:
|
|
|
152
151
|
logger.info("Starting full reindex")
|
|
153
152
|
# Trigger: a full search rebuild removes every derived row.
|
|
154
153
|
# Why: vector storage may live outside SQL, so cleanup must cross the
|
|
155
|
-
# repository boundary before the full-text
|
|
154
|
+
# repository boundary before the full-text rows are rebuilt.
|
|
156
155
|
# Outcome: built-in and extension indexes follow the same lifecycle.
|
|
157
156
|
await self.repository.delete_project_vector_rows()
|
|
158
|
-
|
|
157
|
+
# Trigger: this service reindexes exactly one project, but search_index
|
|
158
|
+
# is shared by every project in the database (local SQLite consolidated
|
|
159
|
+
# into one memory.db; cloud tenants share one Postgres DB across
|
|
160
|
+
# projects). The historical DROP TABLE here dated from the one-database-
|
|
161
|
+
# per-project era and destroyed sibling projects' rows — on Postgres it
|
|
162
|
+
# also left nothing behind, since only migrations recreate the table.
|
|
163
|
+
# Why: a project-scoped DELETE clears only rows this rebuild will
|
|
164
|
+
# repopulate, and on Postgres the FTS chunk rows cascade with them.
|
|
165
|
+
# Outcome: sibling projects keep serving search while this one rebuilds.
|
|
159
166
|
await self.init_search_index()
|
|
167
|
+
await self.repository.delete_project_search_rows()
|
|
160
168
|
|
|
161
169
|
# Reindex all entities
|
|
162
170
|
logger.debug("Indexing entities")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: basic-memory
|
|
3
|
-
Version: 0.23.1.
|
|
3
|
+
Version: 0.23.1.dev27
|
|
4
4
|
Summary: Local-first knowledge management combining Zettelkasten with knowledge graphs
|
|
5
5
|
Project-URL: Homepage, https://github.com/basicmachines-co/basic-memory
|
|
6
6
|
Project-URL: Repository, https://github.com/basicmachines-co/basic-memory
|
|
@@ -23,7 +23,7 @@ basic_memory/alembic/versions/502b60eaa905_remove_required_from_entity_permalink
|
|
|
23
23
|
basic_memory/alembic/versions/5fe1ab1ccebe_add_projects_table.py,sha256=xTSVvB-caYl_CdVfzhj-eqdQEOxQ12NIHOc8dBSqCMQ,4779
|
|
24
24
|
basic_memory/alembic/versions/647e7a75e2cd_project_constraint_fix.py,sha256=oFtjzJd37HUMezuCUonK-yRc867_9L5zxd4CnLhFIi4,4655
|
|
25
25
|
basic_memory/alembic/versions/6830751f5fb6_merge_multiple_heads.py,sha256=8bO4yg_v6klCJz0E15sDI2pDtsmAL2nNO5ACpKGLYQo,499
|
|
26
|
-
basic_memory/alembic/versions/7f6a2b8c9d10_index_full_postgres_note_content.py,sha256=
|
|
26
|
+
basic_memory/alembic/versions/7f6a2b8c9d10_index_full_postgres_note_content.py,sha256=0Ipk-T-7LiA8-ExBr-mz-zqKHvH9QI0G33zdWtnREHo,5414
|
|
27
27
|
basic_memory/alembic/versions/9d9c1cb7d8f5_add_mtime_and_size_columns_to_entity_.py,sha256=DYlXlRYO3Ms6x9GbrFGWgj1QEzsdKHx-4AA4lSVM7y0,1587
|
|
28
28
|
basic_memory/alembic/versions/a1b2c3d4e5f6_fix_project_foreign_keys.py,sha256=i42eQyO08RWf4exnH1q1PKw_EJFsHAG-T4pdLTMSpiA,1818
|
|
29
29
|
basic_memory/alembic/versions/a2b3c4d5e6f7_add_search_index_entity_cascade.py,sha256=Oh_J5Jw85J3LvknfizFP7_1SoelZM_A7IjBau8lRpfk,1671
|
|
@@ -56,7 +56,7 @@ basic_memory/api/v2/routers/importer_router.py,sha256=LHdi0q7FKKTeynMl4qg4itOw51
|
|
|
56
56
|
basic_memory/api/v2/routers/inspect_router.py,sha256=4QDM89AzWShF1UTE6CDjX1R8_4aNs3DIm4SpUUsbWzA,8637
|
|
57
57
|
basic_memory/api/v2/routers/knowledge_router.py,sha256=-irLLXtYTUtlbqjHUwN6OhWn1jG8SN9mbeUp3uOUpwk,49572
|
|
58
58
|
basic_memory/api/v2/routers/memory_router.py,sha256=2BvV7zA_39Ld3ySjY5twy7AzaMncn70fUVN7IdhGX_o,7308
|
|
59
|
-
basic_memory/api/v2/routers/project_router.py,sha256=
|
|
59
|
+
basic_memory/api/v2/routers/project_router.py,sha256=LGXW0ijvz68jZw0I5AWpXKfAOUgu2egDQymMFGJql88,25737
|
|
60
60
|
basic_memory/api/v2/routers/prompt_router.py,sha256=QE69XMKE6MB-yhzvr1mONkkeBZwKA_Ui9Kt-5ZVKvdY,10449
|
|
61
61
|
basic_memory/api/v2/routers/resource_router.py,sha256=t_tXxqGgxYJqcPFKU9jbFBhJzSIjTnfzo6SQMGFV2Mo,7571
|
|
62
62
|
basic_memory/api/v2/routers/schema_router.py,sha256=B_T2OXXFKvC-VaBzzDa2IbBmIHnJr_fPN43_8n9rMYo,22254
|
|
@@ -77,7 +77,7 @@ basic_memory/cli/commands/ci.py,sha256=MW4pepm9472iMzbryA4p-r-SG-OPnFftshB-0S8LB
|
|
|
77
77
|
basic_memory/cli/commands/command_utils.py,sha256=9_xUeeg1-nsnUw3MdNXOc_rhVROqhXqEDcTD3E_ga3A,5008
|
|
78
78
|
basic_memory/cli/commands/config.py,sha256=8IBqPrcgklhvHkVFG8v9laO0PqZkvfLsZ_jgbPkFCb4,8700
|
|
79
79
|
basic_memory/cli/commands/db.py,sha256=aQcjHpff15pfpDTKKpV-zz38TIJNfkOFQsCWggqbbU8,22596
|
|
80
|
-
basic_memory/cli/commands/doctor.py,sha256=
|
|
80
|
+
basic_memory/cli/commands/doctor.py,sha256=51fp0Keazaid-KPaIKaR9xKU9ELSALxFurvXKNuVnVo,11324
|
|
81
81
|
basic_memory/cli/commands/format.py,sha256=pgXkk0ptU2quN0XzjURuapA5AqrIBu1y4j6J1t52ovI,6753
|
|
82
82
|
basic_memory/cli/commands/hook.py,sha256=tNtGzf4E40bhZQL6-SJwQpq8ehQmxm7EIae7O7-3jJg,60641
|
|
83
83
|
basic_memory/cli/commands/import_chatgpt.py,sha256=7SUGG_mmme0BuL4ov0lhb98VkTUldunCv-ehQirtwZE,3870
|
|
@@ -224,7 +224,7 @@ basic_memory/mcp/clients/directory.py,sha256=C_fY7xo300ceF-heRBAktv7OffEnNAuPWx1
|
|
|
224
224
|
basic_memory/mcp/clients/inspect.py,sha256=TtiEOiJITDuFLtrdwMcoY-XBNuCK4C3NobzpQHdHoRU,2311
|
|
225
225
|
basic_memory/mcp/clients/knowledge.py,sha256=DtEsAkqCtZFc-v93KIuPyOFCRLFbbOQGPqEwOSMJytw,13757
|
|
226
226
|
basic_memory/mcp/clients/memory.py,sha256=qKSjKS7jJOKu7y-Lldsm561KU0G9OpRzA0tLf7l9FmI,4794
|
|
227
|
-
basic_memory/mcp/clients/project.py,sha256=
|
|
227
|
+
basic_memory/mcp/clients/project.py,sha256=0er3M6QMjepuKpbn4G6oz7IuVf4veQhDTHJL6iUE09c,7955
|
|
228
228
|
basic_memory/mcp/clients/resource.py,sha256=_FI7bOBAQwlEuv24wU1tsGIFR-riHcemgZSMJqOLBN4,2218
|
|
229
229
|
basic_memory/mcp/clients/schema.py,sha256=OnLDJnh-8OkELdMVDRBObjOsGfgaDzroryjzSP8aWyc,3618
|
|
230
230
|
basic_memory/mcp/clients/search.py,sha256=I7mJxVaQ8-igJzuMzxYaZgHGCwJAkjMHf2QIgYuZBjI,3030
|
|
@@ -317,8 +317,8 @@ basic_memory/repository/rerank_provider.py,sha256=JnMXexhMOv93gJ3UQkkUE6tQyJWdph
|
|
|
317
317
|
basic_memory/repository/rerank_provider_factory.py,sha256=JlPHD0YdAWSima7gGkheiTnGhEn2j5JPB09MZDuhoj0,4735
|
|
318
318
|
basic_memory/repository/search_index_row.py,sha256=bTF7-tiz91HySchZfdP1dZbUNW7WU2KNgG1s1mnRBWc,5335
|
|
319
319
|
basic_memory/repository/search_query.py,sha256=0Kh1IDMXCUza-uTKej5wCu-TjHKhA8j-MCzQ0-abvpA,13949
|
|
320
|
-
basic_memory/repository/search_repository.py,sha256=
|
|
321
|
-
basic_memory/repository/search_repository_base.py,sha256=
|
|
320
|
+
basic_memory/repository/search_repository.py,sha256=Cpgn1feacMtxbm7BhaWf_FMS__Gn7WiIAnovYJX7-Ao,9695
|
|
321
|
+
basic_memory/repository/search_repository_base.py,sha256=7olsUTL0nI-4vkspTViJZbvqIfDPxGho34D3vmILpdo,120702
|
|
322
322
|
basic_memory/repository/search_trace.py,sha256=OLcUJ-4GBva1zgNPBlNA1BThpUJo77YsW5H-0j3zqy4,20613
|
|
323
323
|
basic_memory/repository/semantic_chunking.py,sha256=7xTmL7vt_6vBSYJYeio6s7nTkvW8AdQ9sok1HIY5GWE,8427
|
|
324
324
|
basic_memory/repository/semantic_errors.py,sha256=1v0jz9aBkephpVc4FcX3xIQvgk5jnkO9VpZhPM7AdIc,996
|
|
@@ -385,14 +385,14 @@ basic_memory/services/note_content_reads.py,sha256=3o6GI2VJFkA5PScQD4IlZDO_4rcXL
|
|
|
385
385
|
basic_memory/services/note_content_writes.py,sha256=wqnPnaUII2k_xlTBYMZAVlrc7zGX13M3el334F6z6hY,20530
|
|
386
386
|
basic_memory/services/note_preparation.py,sha256=POGmk0L_9a-eLIMmXmuKtN81QRabF0JyipZiIz0eNqY,38262
|
|
387
387
|
basic_memory/services/project_deletes.py,sha256=bnq8la1ZKsZEkcAg3Ew2onXHku9CWChr-BWDZA6lvuI,6010
|
|
388
|
-
basic_memory/services/project_service.py,sha256=
|
|
388
|
+
basic_memory/services/project_service.py,sha256=E6rpEwKz6ihynZjXxBlvxUbG69YqE8jxOgBI3zT1XWQ,62460
|
|
389
389
|
basic_memory/services/retrieval_inspect.py,sha256=gJq94oYV6ISeh-JeUAB8srMw8K3oGeMgzVXEOWAEzxA,23844
|
|
390
|
-
basic_memory/services/search_service.py,sha256=
|
|
390
|
+
basic_memory/services/search_service.py,sha256=8A1vXo5IIpKXL2gxEsCEP_tcKyRcnz4R5xb6zijRuW0,40254
|
|
391
391
|
basic_memory/services/service.py,sha256=V-d_8gOV07zGIQDpL-Ksqs3ZN9l3qf3HZOK1f_YNTag,336
|
|
392
392
|
basic_memory/templates/prompts/continue_conversation.hbs,sha256=trrDHSXA5S0JCbInMoUJL04xvCGRB_ku1RHNQHtl6ZI,3076
|
|
393
393
|
basic_memory/templates/prompts/search.hbs,sha256=H1cCIsHKp4VC1GrH2KeUB8pGe5vXFPqb2VPotypmeCA,3098
|
|
394
|
-
basic_memory-0.23.1.
|
|
395
|
-
basic_memory-0.23.1.
|
|
396
|
-
basic_memory-0.23.1.
|
|
397
|
-
basic_memory-0.23.1.
|
|
398
|
-
basic_memory-0.23.1.
|
|
394
|
+
basic_memory-0.23.1.dev27.dist-info/METADATA,sha256=j0HNhCqLZhDGmlKdwxHIf7eWLNDXeKyhOgF8UEzKrPI,26848
|
|
395
|
+
basic_memory-0.23.1.dev27.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
396
|
+
basic_memory-0.23.1.dev27.dist-info/entry_points.txt,sha256=wvE2mRF6-Pg4weIYcfQ-86NOLZD4WJg7F7TIsRVFLb8,90
|
|
397
|
+
basic_memory-0.23.1.dev27.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
|
|
398
|
+
basic_memory-0.23.1.dev27.dist-info/RECORD,,
|
|
File without changes
|
{basic_memory-0.23.1.dev20.dist-info → basic_memory-0.23.1.dev27.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{basic_memory-0.23.1.dev20.dist-info → basic_memory-0.23.1.dev27.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|