agemem 0.1.0__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.
- agemem/LICENSE.raw-rag +21 -0
- agemem/RAW_RAG_ATTRIBUTION.md +22 -0
- agemem/__init__.py +2 -0
- agemem/cli.py +129 -0
- agemem/config.py +133 -0
- agemem/data/qsiv-linux-py312.lock +90 -0
- agemem/deciders.py +317 -0
- agemem/engine.py +311 -0
- agemem/evidence.py +116 -0
- agemem/hooks.py +157 -0
- agemem/mcp.py +83 -0
- agemem/mcp_install.py +101 -0
- agemem/notes/LICENSE.jevmem +21 -0
- agemem/notes/UPSTREAM.json +24 -0
- agemem/notes/__init__.py +1 -0
- agemem/notes/config.py +81 -0
- agemem/notes/consolidate.py +213 -0
- agemem/notes/decide.py +4 -0
- agemem/notes/decider.py +64 -0
- agemem/notes/questions.py +229 -0
- agemem/notes/retrieve.py +334 -0
- agemem/notes/screen.py +63 -0
- agemem/notes/store.py +490 -0
- agemem/notes/vectorindex.py +78 -0
- agemem/notes/write.py +164 -0
- agemem/project.py +87 -0
- agemem/providers.py +165 -0
- agemem/qsiv_shared.py +240 -0
- agemem/qsiv_worker.py +33 -0
- agemem/raw_rag.py +134 -0
- agemem/setup.py +118 -0
- agemem-0.1.0.dist-info/METADATA +127 -0
- agemem-0.1.0.dist-info/RECORD +39 -0
- agemem-0.1.0.dist-info/WHEEL +4 -0
- agemem-0.1.0.dist-info/entry_points.txt +2 -0
- agemem-0.1.0.dist-info/licenses/LICENSE +21 -0
- agemem-0.1.0.dist-info/licenses/THIRD_PARTY.md +70 -0
- agemem-0.1.0.dist-info/licenses/agemem/LICENSE.raw-rag +21 -0
- agemem-0.1.0.dist-info/licenses/agemem/notes/LICENSE.jevmem +21 -0
agemem/LICENSE.raw-rag
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 RAW-RAG contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# RAW-RAG attribution
|
|
2
|
+
|
|
3
|
+
`raw_rag.py` adapts the overlapping token-window algorithm and dense candidate /
|
|
4
|
+
reranking pipeline from RAW-RAG, MIT License, copyright 2026 RAW-RAG contributors.
|
|
5
|
+
Full upstream license: `LICENSE.raw-rag`, included in this package.
|
|
6
|
+
|
|
7
|
+
Upstream: https://github.com/Litmeb/RAW-RAG
|
|
8
|
+
Revision: `95639191e9547219b426710e50fe1a36235e26fc`
|
|
9
|
+
Reference: `methods/EverCore/evaluation/src/adapters/rag_adapter.py`
|
|
10
|
+
Reference file SHA256: `997c35db93feea77eed897b3d5640bd9cd6f114da40bff5128efae65a6466637`
|
|
11
|
+
|
|
12
|
+
This is a deliberate adaptation, not an upstream reproduction. Source records
|
|
13
|
+
are chunked separately (256 cl100k tokens, overlap32), with exact source IDs.
|
|
14
|
+
The original conversation headers, cross-turn windows, temporal filters,
|
|
15
|
+
remote embedding/reranking/answer clients, incremental conversation ingestion,
|
|
16
|
+
dynamic selection and optional PostgreSQL support are omitted. Agemem filters
|
|
17
|
+
project, branch and current snapshot visibility before calling this adapter.
|
|
18
|
+
BGE/MiniLM run locally; dense cosine top128 feeds rerank top15, followed by
|
|
19
|
+
Agemem's context budget. Model licenses remain separate from source licensing.
|
|
20
|
+
|
|
21
|
+
The live service uses only this adapted implementation; no upstream checkout or
|
|
22
|
+
comparison harness is required.
|
agemem/__init__.py
ADDED
agemem/cli.py
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"""User-facing project setup and live memory commands."""
|
|
2
|
+
import argparse
|
|
3
|
+
import json
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from .engine import Engine
|
|
8
|
+
from .project import initialize
|
|
9
|
+
from .config import initialize_user_config, doctor, provider_options
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def main():
|
|
13
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
14
|
+
parser.add_argument("--project", type=Path, default=Path.cwd(), help="Project checkout to use")
|
|
15
|
+
parser.add_argument("--offline", action="store_true", help="Never use hosted decisions or download embedding weights")
|
|
16
|
+
sub = parser.add_subparsers(dest="command", required=True)
|
|
17
|
+
p = sub.add_parser("project", help="Set up a project and its MCP connection")
|
|
18
|
+
project_init = p.add_subparsers(dest="project_command", required=True).add_parser("init", help="Ensure user config, project files, index and MCP registration")
|
|
19
|
+
clients = project_init.add_mutually_exclusive_group()
|
|
20
|
+
clients.add_argument("--client", choices=["codex", "cursor", "claude-code"], help="Register one client")
|
|
21
|
+
clients.add_argument("--mcp", nargs="+", choices=["codex", "cursor", "claude", "claude-code"], help="Register selected clients; claude means Claude Code")
|
|
22
|
+
project_init.add_argument("--model", choices=["jev", "qsiv"], help="Select the decision provider without prompting")
|
|
23
|
+
hook_options = project_init.add_mutually_exclusive_group()
|
|
24
|
+
hook_options.add_argument("--no-hooks", dest="hooks", action="store_false", help="Do not install lifecycle hooks")
|
|
25
|
+
hook_options.add_argument("--hooks", dest="hooks", action="store_true", help=argparse.SUPPRESS)
|
|
26
|
+
project_init.set_defaults(hooks=True)
|
|
27
|
+
project_init.add_argument("--executable", type=Path, help="Use an installed agemem executable instead of uvx (source testing)")
|
|
28
|
+
project_init.add_argument("--no-input", action="store_true", help="Never prompt; fail when required setup choices are missing")
|
|
29
|
+
project_init.add_argument("--retrieval", choices=["hybrid", "bm25", "raw-rag"], default="hybrid")
|
|
30
|
+
project_init.add_argument("--embedder", default="BAAI/bge-small-en-v1.5")
|
|
31
|
+
p = sub.add_parser("config", help="Manage user configuration")
|
|
32
|
+
p.add_subparsers(dest="config_command", required=True).add_parser("init", help="Create a private YAML template without overwriting existing settings")
|
|
33
|
+
p = sub.add_parser("provider", help="Set up optional local providers")
|
|
34
|
+
provider_sub = p.add_subparsers(dest="provider_command", required=True)
|
|
35
|
+
setup = provider_sub.add_parser("setup", help="Explicitly download models and install an isolated runtime")
|
|
36
|
+
setup.add_argument("provider_name", choices=["qsiv"])
|
|
37
|
+
setup.add_argument("--model-directory", type=Path)
|
|
38
|
+
setup.add_argument("--runtime-directory", type=Path)
|
|
39
|
+
setup.add_argument("--dry-run", action="store_true", help="Show actions without downloads or filesystem changes")
|
|
40
|
+
sub.add_parser("doctor", help="Check provider setup without inference or API calls")
|
|
41
|
+
p = sub.add_parser("init", help="Create missing bank/config files; preserve existing memory")
|
|
42
|
+
p.add_argument("--retrieval", choices=["hybrid", "bm25", "raw-rag"], default="hybrid")
|
|
43
|
+
p.add_argument("--embedder", default="BAAI/bge-small-en-v1.5")
|
|
44
|
+
sub.add_parser("index", help="Snapshot selected tracked project files; no hosted calls")
|
|
45
|
+
p = sub.add_parser("capture", help="Archive original text as untrusted source evidence")
|
|
46
|
+
p.add_argument("text")
|
|
47
|
+
p.add_argument("--label", default="event")
|
|
48
|
+
p.add_argument("--shared", action="store_true")
|
|
49
|
+
p = sub.add_parser("remember", help="Write a durable note through jev-mem's actual screens")
|
|
50
|
+
p.add_argument("text")
|
|
51
|
+
p.add_argument("--source-id")
|
|
52
|
+
p.add_argument("--shared", action="store_true")
|
|
53
|
+
p = sub.add_parser("recall", help="Read current bank, recall notes, and retrieve source evidence live")
|
|
54
|
+
p.add_argument("query")
|
|
55
|
+
p.add_argument("--budget", type=int)
|
|
56
|
+
p.add_argument("--history", action="store_true", help="Also search older file snapshots on this branch")
|
|
57
|
+
sub.add_parser("maintain", help="Screen pending notes and run jev-mem consolidation")
|
|
58
|
+
sub.add_parser("mcp", help="Run the project's MCP server over stdio")
|
|
59
|
+
p = sub.add_parser("mcp-install", help="Register this project with a coding client")
|
|
60
|
+
p.add_argument("--client", choices=["codex", "cursor", "claude-code"], help="Prompt when omitted")
|
|
61
|
+
p.add_argument("--dry-run", action="store_true", help="Preview registration without changing client configuration")
|
|
62
|
+
p.add_argument("--executable", type=Path, help="Use an installed agemem executable instead of uvx")
|
|
63
|
+
p = sub.add_parser("hooks-install", help="Install optional read-only lifecycle hooks")
|
|
64
|
+
p.add_argument("--client", nargs="+", choices=["codex", "claude", "claude-code"], required=True)
|
|
65
|
+
p.add_argument("--executable", type=Path)
|
|
66
|
+
p.add_argument("--dry-run", action="store_true")
|
|
67
|
+
p = sub.add_parser("hook", help="Handle client lifecycle JSON on stdin; local read-only context")
|
|
68
|
+
p.add_argument("event", choices=["session-start", "user-prompt"])
|
|
69
|
+
args = parser.parse_args()
|
|
70
|
+
try:
|
|
71
|
+
if args.command == "project":
|
|
72
|
+
from .setup import initialize_project
|
|
73
|
+
result = initialize_project(args.project, args.client, args.retrieval, args.embedder, args.offline, model=args.model, clients=args.mcp, no_input=args.no_input, hooks=args.hooks, executable=args.executable)
|
|
74
|
+
elif args.command == "config":
|
|
75
|
+
result = initialize_user_config()
|
|
76
|
+
elif args.command == "mcp-install":
|
|
77
|
+
from .mcp_install import install
|
|
78
|
+
result = install(args.project, args.client, args.dry_run, args.offline, args.executable)
|
|
79
|
+
elif args.command == "hooks-install":
|
|
80
|
+
from .hooks import install
|
|
81
|
+
result = install(args.project, args.client, args.executable, args.dry_run)
|
|
82
|
+
elif args.command == "hook":
|
|
83
|
+
from .hooks import run
|
|
84
|
+
run(args.project, args.event)
|
|
85
|
+
return
|
|
86
|
+
elif args.command == "provider":
|
|
87
|
+
from .providers import setup_qsiv
|
|
88
|
+
options = provider_options({})
|
|
89
|
+
if options["qsiv_runtime"] != "fp8":
|
|
90
|
+
raise ValueError("Automatic QSIV setup currently supports runtime fp8 only")
|
|
91
|
+
runtime_python = options.get("qsiv_python")
|
|
92
|
+
runtime_directory = args.runtime_directory or (Path(runtime_python).parent.parent if runtime_python else None)
|
|
93
|
+
result = setup_qsiv(directory=args.model_directory or options.get("qsiv_directory"),
|
|
94
|
+
runtime_directory=runtime_directory, dry_run=args.dry_run)
|
|
95
|
+
elif args.command == "doctor":
|
|
96
|
+
result = doctor(args.project)
|
|
97
|
+
elif args.command == "init":
|
|
98
|
+
result = initialize(args.project, args.retrieval, args.embedder)
|
|
99
|
+
elif args.command == "mcp":
|
|
100
|
+
from .mcp import serve
|
|
101
|
+
serve(args.project, args.offline)
|
|
102
|
+
return
|
|
103
|
+
else:
|
|
104
|
+
engine = Engine(args.project, args.offline)
|
|
105
|
+
try:
|
|
106
|
+
if args.command == "index":
|
|
107
|
+
result = engine.index()
|
|
108
|
+
elif args.command == "capture":
|
|
109
|
+
result = engine.capture(args.text, args.label, args.shared)
|
|
110
|
+
elif args.command == "remember":
|
|
111
|
+
result = engine.remember(args.text, args.source_id, args.shared)
|
|
112
|
+
elif args.command == "recall":
|
|
113
|
+
result = engine.recall(args.query, args.budget, args.history)
|
|
114
|
+
else:
|
|
115
|
+
result = engine.maintain()
|
|
116
|
+
finally:
|
|
117
|
+
engine.close()
|
|
118
|
+
print(json.dumps(result, indent=2, ensure_ascii=False))
|
|
119
|
+
if args.command == "doctor" and not result["ok"]:
|
|
120
|
+
raise SystemExit(1)
|
|
121
|
+
except Exception as exc:
|
|
122
|
+
# Do not echo SDK exception bodies, key-bearing URLs or supplied source text.
|
|
123
|
+
message = str(exc) if isinstance(exc, ValueError) else "See installation/runtime diagnostics; provider details omitted"
|
|
124
|
+
print(json.dumps({"error": type(exc).__name__, "message": message}), file=sys.stderr)
|
|
125
|
+
raise SystemExit(1) from None
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
if __name__ == "__main__":
|
|
129
|
+
main()
|
agemem/config.py
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"""User configuration, kept outside project checkouts and never written implicitly."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import os
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
import yaml
|
|
8
|
+
|
|
9
|
+
CONFIG_VERSION = 1
|
|
10
|
+
|
|
11
|
+
PROVIDERS = ("jev", "qsiv", "ollaya", "cascade")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def config_path():
|
|
15
|
+
explicit = os.environ.get("AGEMEM_CONFIG")
|
|
16
|
+
return Path(explicit).expanduser() if explicit else Path(os.environ.get("XDG_CONFIG_HOME", str(Path.home() / ".config"))) / "agemem/config.yaml"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def load_user_config():
|
|
20
|
+
path = config_path()
|
|
21
|
+
if not path.exists():
|
|
22
|
+
return {}
|
|
23
|
+
try:
|
|
24
|
+
data = yaml.safe_load(path.read_text())
|
|
25
|
+
if data is None:
|
|
26
|
+
data = {}
|
|
27
|
+
except yaml.YAMLError:
|
|
28
|
+
raise ValueError("Invalid YAML in agemem user configuration") from None
|
|
29
|
+
if not isinstance(data, dict):
|
|
30
|
+
raise ValueError("Agemem user configuration must be a YAML mapping")
|
|
31
|
+
version = data.get("version", CONFIG_VERSION)
|
|
32
|
+
if type(version) is not int or version != CONFIG_VERSION:
|
|
33
|
+
raise ValueError("Unsupported config.yaml version; this release supports version: 1. Use a compatible Agemem release or migrate the configuration")
|
|
34
|
+
if data.get("default_provider", "jev") not in PROVIDERS:
|
|
35
|
+
raise ValueError("Unsupported default_provider in agemem user configuration")
|
|
36
|
+
providers = data.get("providers", {})
|
|
37
|
+
if not isinstance(providers, dict) or any(not isinstance(value, dict) for value in providers.values()):
|
|
38
|
+
raise ValueError("providers must map provider names to option mappings")
|
|
39
|
+
return data
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def provider_options(project):
|
|
43
|
+
user = load_user_config()
|
|
44
|
+
providers = user.get("providers", {})
|
|
45
|
+
qsiv = providers.get("qsiv", {})
|
|
46
|
+
jev = providers.get("jev", {})
|
|
47
|
+
backend = os.environ.get("AGEMEM_PROVIDER") or project.get("decision_backend") or user.get("default_provider", "jev")
|
|
48
|
+
if backend not in PROVIDERS:
|
|
49
|
+
raise ValueError("Unsupported decision backend")
|
|
50
|
+
runtime = project.get("qsiv_runtime", qsiv.get("runtime", "fp8"))
|
|
51
|
+
if runtime not in ("fp8", "reference"):
|
|
52
|
+
raise ValueError("qsiv runtime must be fp8 or reference")
|
|
53
|
+
directory = os.environ.get("AGEMEM_QSIV_DIR") or project.get("qsiv_directory") or qsiv.get("model_directory")
|
|
54
|
+
if directory is not None and not isinstance(directory, str):
|
|
55
|
+
raise ValueError("QSIV model_directory must be a path string")
|
|
56
|
+
key = os.environ.get("AGEMEM_JEV_API_KEY") or os.environ.get("TYPESAFE_API_KEY") or os.environ.get("JEV_API_KEY") or jev.get("api_key")
|
|
57
|
+
if key is not None and not isinstance(key, str):
|
|
58
|
+
raise ValueError("Jev api_key must be a string")
|
|
59
|
+
data_root = Path(os.environ.get("XDG_DATA_HOME", str(Path.home() / ".local/share")))
|
|
60
|
+
directory = directory or str(data_root / "agemem/models/qsiv")
|
|
61
|
+
default_python = data_root / "agemem/runtimes/qsiv/bin/python"
|
|
62
|
+
runtime_python = os.environ.get("AGEMEM_QSIV_PYTHON") or qsiv.get("python")
|
|
63
|
+
if runtime_python is not None and not isinstance(runtime_python, str):
|
|
64
|
+
raise ValueError("QSIV python must be a path string")
|
|
65
|
+
if runtime_python is None and default_python.is_file():
|
|
66
|
+
runtime_python = str(default_python)
|
|
67
|
+
return {"decision_backend": backend, "qsiv_python": str(Path(runtime_python).expanduser()) if runtime_python else None, "qsiv_runtime": runtime,
|
|
68
|
+
"qsiv_directory": str(Path(directory).expanduser()) if directory else None,
|
|
69
|
+
"jev_api_key": key}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def initialize_user_config(default_provider="jev", api_key=None):
|
|
73
|
+
if default_provider not in PROVIDERS:
|
|
74
|
+
raise ValueError("Unsupported default provider")
|
|
75
|
+
path = config_path()
|
|
76
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
77
|
+
data_root = Path(os.environ.get("XDG_DATA_HOME", str(Path.home() / ".local/share")))
|
|
78
|
+
template = """# Configuration schema version (independent of the Agemem package version).
|
|
79
|
+
version: 1
|
|
80
|
+
# Provider selection is global; projects can explicitly override it.
|
|
81
|
+
# Options: jev, qsiv, cascade (or ollaya for the local Ollaya backend).
|
|
82
|
+
default_provider: jev
|
|
83
|
+
providers:
|
|
84
|
+
jev:
|
|
85
|
+
# Prefer AGEMEM_JEV_API_KEY, TYPESAFE_API_KEY or JEV_API_KEY.
|
|
86
|
+
api_key: null
|
|
87
|
+
qsiv:
|
|
88
|
+
runtime: fp8
|
|
89
|
+
model_directory: MODEL_DIRECTORY
|
|
90
|
+
# python: ~/.local/share/agemem/runtimes/qsiv/bin/python
|
|
91
|
+
"""
|
|
92
|
+
template = template.replace("default_provider: jev", "default_provider: " + default_provider)
|
|
93
|
+
if api_key is not None:
|
|
94
|
+
template = template.replace("api_key: null", "api_key: " + yaml.safe_dump(api_key, default_style='"').strip())
|
|
95
|
+
template = template.replace("MODEL_DIRECTORY", yaml.safe_dump(str(data_root / "agemem/models/qsiv"), default_style='"').strip())
|
|
96
|
+
try:
|
|
97
|
+
descriptor = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
|
|
98
|
+
except FileExistsError:
|
|
99
|
+
return {"path": str(path), "created": False}
|
|
100
|
+
with os.fdopen(descriptor, "w") as stream:
|
|
101
|
+
stream.write(template)
|
|
102
|
+
return {"path": str(path), "created": True}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def doctor(project):
|
|
106
|
+
"""Inspect configuration without opening stores, downloading or calling providers."""
|
|
107
|
+
from .project import configuration
|
|
108
|
+
path = Path(project).expanduser().resolve()
|
|
109
|
+
options = configuration(path) if (path / ".agemem/config.json").exists() else provider_options({})
|
|
110
|
+
backend = options["decision_backend"]
|
|
111
|
+
checks = {"user_config": str(config_path()), "user_config_exists": config_path().exists(),
|
|
112
|
+
"provider": backend, "project_initialized": (path / ".agemem/config.json").exists()}
|
|
113
|
+
issues = []
|
|
114
|
+
if backend in ("jev", "cascade"):
|
|
115
|
+
checks["jev_credentials_present"] = bool(options.get("jev_api_key"))
|
|
116
|
+
if not checks["jev_credentials_present"]:
|
|
117
|
+
issues.append("Set a Jev API key in the user configuration or environment")
|
|
118
|
+
if backend in ("qsiv", "cascade"):
|
|
119
|
+
directory = options.get("qsiv_directory")
|
|
120
|
+
checks["qsiv_model_directory"] = directory
|
|
121
|
+
checks["qsiv_model_directory_exists"] = bool(directory and Path(directory).is_dir())
|
|
122
|
+
if not checks["qsiv_model_directory_exists"]:
|
|
123
|
+
issues.append("Configure and install the QSIV model directory")
|
|
124
|
+
from .providers import qsiv_doctor
|
|
125
|
+
import sys
|
|
126
|
+
runtime_python = options.get("qsiv_python") or sys.executable
|
|
127
|
+
runtime_directory = Path(runtime_python).parent.parent if runtime_python else None
|
|
128
|
+
diagnostic = qsiv_doctor(directory=directory, runtime_directory=runtime_directory, runtime_python=runtime_python, runtime=options["qsiv_runtime"])
|
|
129
|
+
checks["qsiv"] = diagnostic
|
|
130
|
+
if not diagnostic.get("ready", False):
|
|
131
|
+
issues.append("QSIV runtime diagnostics require attention; see checks.qsiv")
|
|
132
|
+
return {"ok": not issues, "checks": checks, "issues": issues,
|
|
133
|
+
"note": "Read-only diagnostics; no model inference or API calls performed"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
annotated-doc==0.0.5
|
|
2
|
+
annotated-types==0.8.0
|
|
3
|
+
anyio==4.15.1
|
|
4
|
+
attrs==26.1.0
|
|
5
|
+
certifi==2026.10.23
|
|
6
|
+
cffi==2.1.1
|
|
7
|
+
charset-normalizer==3.5.2
|
|
8
|
+
click==8.5.0
|
|
9
|
+
cryptography==50.0.2
|
|
10
|
+
cuda-bindings==13.4.4
|
|
11
|
+
cuda-pathfinder==1.8.4
|
|
12
|
+
cuda-toolkit==13.0.2
|
|
13
|
+
fastembed==0.9.1
|
|
14
|
+
filelock==4.2.4
|
|
15
|
+
flatbuffers==25.12.19
|
|
16
|
+
fsspec==2026.9.0
|
|
17
|
+
h11==0.16.0
|
|
18
|
+
hf-xet==1.7.0
|
|
19
|
+
httpcore==1.0.9
|
|
20
|
+
httpcore2==2.16.0
|
|
21
|
+
httpx==0.28.1
|
|
22
|
+
httpx2==2.16.0
|
|
23
|
+
huggingface-hub==1.33.0
|
|
24
|
+
idna==3.20
|
|
25
|
+
jinja2==3.1.6
|
|
26
|
+
jsonschema==4.26.0
|
|
27
|
+
jsonschema-specifications==2025.9.1
|
|
28
|
+
loguru==0.7.3
|
|
29
|
+
markdown-it-py==4.2.0
|
|
30
|
+
markupsafe==3.0.4
|
|
31
|
+
mcp==2.3.0
|
|
32
|
+
mcp-types==2.3.0
|
|
33
|
+
mdurl==0.1.2
|
|
34
|
+
mmh3==5.3.1
|
|
35
|
+
mpmath==1.3.0
|
|
36
|
+
networkx==3.7
|
|
37
|
+
numpy==2.5.4
|
|
38
|
+
nvidia-cublas==13.1.0.3
|
|
39
|
+
nvidia-cuda-cupti==13.0.85
|
|
40
|
+
nvidia-cuda-nvrtc==13.0.88
|
|
41
|
+
nvidia-cuda-runtime==13.0.96
|
|
42
|
+
nvidia-cudnn-cu13==9.19.0.56
|
|
43
|
+
nvidia-cufft==12.0.0.61
|
|
44
|
+
nvidia-cufile==1.15.1.6
|
|
45
|
+
nvidia-curand==10.4.0.35
|
|
46
|
+
nvidia-cusolver==12.0.4.66
|
|
47
|
+
nvidia-cusparse==12.6.3.3
|
|
48
|
+
nvidia-cusparselt-cu13==0.8.0
|
|
49
|
+
nvidia-nccl-cu13==2.28.9
|
|
50
|
+
nvidia-nvjitlink==13.0.88
|
|
51
|
+
nvidia-nvshmem-cu13==3.4.5
|
|
52
|
+
nvidia-nvtx==13.0.85
|
|
53
|
+
onnxruntime==1.31.0
|
|
54
|
+
opentelemetry-api==1.45.1
|
|
55
|
+
packaging==26.3
|
|
56
|
+
pillow==13.0.0
|
|
57
|
+
protobuf==7.36.2
|
|
58
|
+
py-rust-stemmers==0.1.8
|
|
59
|
+
pycparser==3.12
|
|
60
|
+
pydantic==2.14.1
|
|
61
|
+
pydantic-core==2.50.1
|
|
62
|
+
pygments==2.21.0
|
|
63
|
+
pyjwt==2.15.1
|
|
64
|
+
python-multipart==0.0.32
|
|
65
|
+
pyyaml==6.0.3
|
|
66
|
+
referencing==0.37.0
|
|
67
|
+
regex==2026.9.29
|
|
68
|
+
requests==2.34.2
|
|
69
|
+
rich==15.0.0
|
|
70
|
+
rpds-py==2026.9.1
|
|
71
|
+
safetensors==0.8.0
|
|
72
|
+
setuptools==81.0.0
|
|
73
|
+
shellingham==1.5.4
|
|
74
|
+
sqlite-vec==0.1.9
|
|
75
|
+
sse-starlette==3.6.0
|
|
76
|
+
starlette==1.10.0
|
|
77
|
+
sympy==1.14.0
|
|
78
|
+
tenacity==9.2.1
|
|
79
|
+
tokenizers==0.22.2
|
|
80
|
+
torch==2.11.0
|
|
81
|
+
tqdm==4.70.1
|
|
82
|
+
transformers==5.14.1
|
|
83
|
+
triton==3.6.0
|
|
84
|
+
truststore==0.10.5
|
|
85
|
+
typer==0.27.3
|
|
86
|
+
typesafe-sdk==0.7.5
|
|
87
|
+
typing-extensions==4.16.0
|
|
88
|
+
typing-inspection==0.4.4
|
|
89
|
+
urllib3==2.8.0
|
|
90
|
+
uvicorn==0.54.0
|