onex-cli 1.16.2__tar.gz → 1.16.4__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.
- {onex_cli-1.16.2/onex_cli.egg-info → onex_cli-1.16.4}/PKG-INFO +1 -1
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/__init__.py +1 -1
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/mcp/tools/rocket_tools.py +147 -13
- {onex_cli-1.16.2 → onex_cli-1.16.4/onex_cli.egg-info}/PKG-INFO +1 -1
- {onex_cli-1.16.2 → onex_cli-1.16.4}/CHANGELOG.md +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/LICENSE +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/MANIFEST.in +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/README.md +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/__main__.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/__init__.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/create.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/create_e2e.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/debug.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/deploy.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/dev.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/env.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/es.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/init.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/invoke.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/login.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/logout.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/logs.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/mcp.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/platform.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/provision.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/reload.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/replay.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/s3.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/status.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/switch.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/test.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/trace.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/undeploy.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/validate.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/commands/vpn.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/config.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/mcp/__init__.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/mcp/server.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/mcp/tools/__init__.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/runtime/__init__.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/runtime/local_runtime.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/schema/__init__.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/schema/service_descriptor.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/schema/validator.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/crud-service/README.md.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/crud-service/__init__.py.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/crud-service/service.yml.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/crud-service/src/__init__.py.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/crud-service/src/apis/__init__.py.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/crud-service/src/models/__init__.py.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/crud-service/src/models/schemas.py.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/crud-service/src/repositories/__init__.py.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/crud-service/src/services/__init__.py.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/e2e/data_service.yml.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/e2e/test_service_e2e.py.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/event-driven/README.md.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/event-driven/__init__.py.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/event-driven/service.yml.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/event-driven/src/__init__.py.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/event-driven/src/triggers/__init__.py.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/event-driven/src/triggers/events.py.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/event-driven/src/triggers/schedules.py.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/go-minimal/README.md.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/go-minimal/go.mod.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/go-minimal/main.go.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/go-minimal/service.yml.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/go-rest-api/README.md.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/go-rest-api/go.mod.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/go-rest-api/handlers/items.go.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/go-rest-api/main.go.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/go-rest-api/service.yml.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/minimal/README.md.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/minimal/__init__.py.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/minimal/service.yml.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/minimal/src/__init__.py.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/minimal/src/apis/__init__.py.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/minimal/src/apis/hello.py.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/rest-api/README.md.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/rest-api/__init__.py.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/rest-api/service.yml.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/rest-api/src/__init__.py.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/rest-api/src/apis/__init__.py.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/rest-api/src/apis/handlers.py.j2 +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/utils/__init__.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/utils/auth.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/utils/crypto.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/utils/email.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/utils/helpers.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/vpn/__init__.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/vpn/platform_detector.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/vpn/setup_vpn.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex/vpn/wireguard_manager.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex_cli.egg-info/SOURCES.txt +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex_cli.egg-info/dependency_links.txt +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex_cli.egg-info/entry_points.txt +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex_cli.egg-info/requires.txt +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/onex_cli.egg-info/top_level.txt +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/setup.cfg +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/setup.py +0 -0
- {onex_cli-1.16.2 → onex_cli-1.16.4}/tests/test_mcp_logs_e2e.py +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# OneXEOS Services CLI
|
|
2
|
-
__version__ = "1.16.
|
|
2
|
+
__version__ = "1.16.4"
|
|
@@ -130,11 +130,25 @@ def _detect_git_repo() -> Optional[dict]:
|
|
|
130
130
|
|
|
131
131
|
def register_rocket_tools(mcp, api_url: Optional[str] = None):
|
|
132
132
|
"""Register all onex-rocket tools on an existing FastMCP server."""
|
|
133
|
+
import time as _time
|
|
134
|
+
|
|
133
135
|
base_url = _resolve_rocket_url(api_url)
|
|
134
136
|
client = httpx.Client(base_url=base_url, timeout=10.0)
|
|
135
137
|
_indexed_repos: set = set() # track repos already indexed this session
|
|
136
138
|
_indexing_in_progress: set = set() # repos currently being indexed
|
|
137
139
|
|
|
140
|
+
# Session tracking for savings estimation
|
|
141
|
+
_session_start = _time.time()
|
|
142
|
+
_call_counts: dict = {} # tool_name -> count
|
|
143
|
+
_total_response_tokens = 0 # approximate tokens from MCP responses
|
|
144
|
+
|
|
145
|
+
def _track_call(tool_name: str, response_len: int):
|
|
146
|
+
"""Track a tool call for session savings estimation."""
|
|
147
|
+
nonlocal _total_response_tokens
|
|
148
|
+
_call_counts[tool_name] = _call_counts.get(tool_name, 0) + 1
|
|
149
|
+
# Rough estimate: 1 token ≈ 4 chars
|
|
150
|
+
_total_response_tokens += response_len // 4
|
|
151
|
+
|
|
138
152
|
def _check_index_status() -> Optional[dict]:
|
|
139
153
|
"""Check server-side indexing status for repos in progress.
|
|
140
154
|
Returns status dict if indexing, None if all done."""
|
|
@@ -167,6 +181,7 @@ def register_rocket_tools(mcp, api_url: Optional[str] = None):
|
|
|
167
181
|
resp = client.get(f"/api/v1/{path}", params=params or {})
|
|
168
182
|
resp.raise_for_status()
|
|
169
183
|
result = resp.text
|
|
184
|
+
_track_call(path.split("/")[0], len(result))
|
|
170
185
|
if result in ("null", "[]", "{}"):
|
|
171
186
|
active = _check_index_status()
|
|
172
187
|
if active:
|
|
@@ -183,7 +198,9 @@ def register_rocket_tools(mcp, api_url: Optional[str] = None):
|
|
|
183
198
|
try:
|
|
184
199
|
resp = client.post(f"/api/v1/{path}", json=data)
|
|
185
200
|
resp.raise_for_status()
|
|
186
|
-
|
|
201
|
+
result = resp.text
|
|
202
|
+
_track_call(path, len(result))
|
|
203
|
+
return result
|
|
187
204
|
except httpx.HTTPError as e:
|
|
188
205
|
return f'{{"error": "{str(e)}"}}'
|
|
189
206
|
|
|
@@ -254,6 +271,75 @@ def register_rocket_tools(mcp, api_url: Optional[str] = None):
|
|
|
254
271
|
return None
|
|
255
272
|
return repo_info["graph_name"]
|
|
256
273
|
|
|
274
|
+
# GitHub org used to construct clone URLs for auto-indexing
|
|
275
|
+
GITHUB_ORG = "OneXApis"
|
|
276
|
+
|
|
277
|
+
# Map of known repo folder names to GitHub repo names
|
|
278
|
+
KNOWN_REPOS = {
|
|
279
|
+
"onexerp-platform": "onex-platform",
|
|
280
|
+
"onexerp-services": "onex-services",
|
|
281
|
+
"onexeos-graph": "onex-rocket",
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
def _ensure_repo_by_name(repo_name: str):
|
|
285
|
+
"""Auto-index a repo by name if not already in the graph.
|
|
286
|
+
|
|
287
|
+
Constructs the GitHub URL from the known org and triggers
|
|
288
|
+
async indexing on the server. Non-blocking.
|
|
289
|
+
"""
|
|
290
|
+
if not repo_name or repo_name in _indexed_repos or repo_name in _indexing_in_progress:
|
|
291
|
+
return
|
|
292
|
+
|
|
293
|
+
# Check if already in graph via index/status
|
|
294
|
+
try:
|
|
295
|
+
resp = client.get(f"/api/v1/index/status/{repo_name}", timeout=3)
|
|
296
|
+
if resp.status_code == 200:
|
|
297
|
+
status = resp.json()
|
|
298
|
+
if status.get("status") == "done":
|
|
299
|
+
_indexed_repos.add(repo_name)
|
|
300
|
+
return
|
|
301
|
+
if status.get("status") == "indexing":
|
|
302
|
+
_indexing_in_progress.add(repo_name)
|
|
303
|
+
return
|
|
304
|
+
except Exception:
|
|
305
|
+
pass
|
|
306
|
+
|
|
307
|
+
# Check graph stats as fallback
|
|
308
|
+
try:
|
|
309
|
+
resp = client.get("/api/v1/stats", timeout=3)
|
|
310
|
+
if resp.status_code == 200:
|
|
311
|
+
by_repo = resp.json().get("by_repo", {})
|
|
312
|
+
if repo_name in by_repo:
|
|
313
|
+
_indexed_repos.add(repo_name)
|
|
314
|
+
return
|
|
315
|
+
except Exception:
|
|
316
|
+
return
|
|
317
|
+
|
|
318
|
+
# Not in graph — construct URL and trigger async index
|
|
319
|
+
# Extract branch from name: "repo@branch" -> branch, "repo" -> "main"
|
|
320
|
+
if "@" in repo_name:
|
|
321
|
+
base_name = repo_name.split("@")[0]
|
|
322
|
+
branch = repo_name.split("@")[1]
|
|
323
|
+
else:
|
|
324
|
+
base_name = repo_name
|
|
325
|
+
branch = "main"
|
|
326
|
+
|
|
327
|
+
# Resolve GitHub repo name
|
|
328
|
+
github_name = KNOWN_REPOS.get(base_name, base_name)
|
|
329
|
+
url = f"https://github.com/{GITHUB_ORG}/{github_name}.git"
|
|
330
|
+
|
|
331
|
+
try:
|
|
332
|
+
resp = client.post("/api/v1/index", json={
|
|
333
|
+
"url": url,
|
|
334
|
+
"name": repo_name,
|
|
335
|
+
"branch": branch,
|
|
336
|
+
"async": True,
|
|
337
|
+
}, timeout=5)
|
|
338
|
+
if resp.status_code == 200:
|
|
339
|
+
_indexing_in_progress.add(repo_name)
|
|
340
|
+
except Exception:
|
|
341
|
+
pass
|
|
342
|
+
|
|
257
343
|
# ================================================================
|
|
258
344
|
# IMPORTANT: Graph context for AI agents
|
|
259
345
|
# The code graph indexes the MAIN branch only. Results do not reflect
|
|
@@ -294,36 +380,40 @@ def register_rocket_tools(mcp, api_url: Optional[str] = None):
|
|
|
294
380
|
def rocket_find_dead_code(repo: str = "") -> str:
|
|
295
381
|
"""Find functions/methods never called anywhere in the codebase.
|
|
296
382
|
BEST FOR: "what code can I safely delete?". Grep can't do this — only a graph can determine zero callers.
|
|
297
|
-
If repo is omitted, auto-detects from current git repo and branch.
|
|
298
|
-
|
|
383
|
+
If repo is omitted, auto-detects from current git repo and branch.
|
|
384
|
+
Auto-indexes the repo if not already in the graph."""
|
|
299
385
|
repo = repo or _get_current_graph_name() or "unknown"
|
|
386
|
+
_ensure_repo_by_name(repo)
|
|
300
387
|
return _get(f"repo/{repo}/dead-code")
|
|
301
388
|
|
|
302
389
|
@mcp.tool()
|
|
303
390
|
def rocket_find_hotspots(repo: str = "", limit: int = 20) -> str:
|
|
304
391
|
"""Find the most depended-on symbols, ranked by caller count.
|
|
305
392
|
BEST FOR: "what are the riskiest parts?", "what should we test most?".
|
|
306
|
-
If repo is omitted, auto-detects from current git repo and branch.
|
|
307
|
-
|
|
393
|
+
If repo is omitted, auto-detects from current git repo and branch.
|
|
394
|
+
Auto-indexes the repo if not already in the graph."""
|
|
308
395
|
repo = repo or _get_current_graph_name() or "unknown"
|
|
396
|
+
_ensure_repo_by_name(repo)
|
|
309
397
|
return _get(f"repo/{repo}/hotspots", {"limit": limit})
|
|
310
398
|
|
|
311
399
|
@mcp.tool()
|
|
312
400
|
def rocket_find_cycles(repo: str = "") -> str:
|
|
313
401
|
"""Find circular dependencies in the codebase.
|
|
314
402
|
BEST FOR: "are there any import cycles?", architectural analysis.
|
|
315
|
-
If repo is omitted, auto-detects from current git repo and branch.
|
|
316
|
-
|
|
403
|
+
If repo is omitted, auto-detects from current git repo and branch.
|
|
404
|
+
Auto-indexes the repo if not already in the graph."""
|
|
317
405
|
repo = repo or _get_current_graph_name() or "unknown"
|
|
406
|
+
_ensure_repo_by_name(repo)
|
|
318
407
|
return _get(f"repo/{repo}/cycles")
|
|
319
408
|
|
|
320
409
|
@mcp.tool()
|
|
321
410
|
def rocket_get_repo_map(repo: str = "") -> str:
|
|
322
411
|
"""Get a bird's-eye view of the entire repo: all files with their key symbols.
|
|
323
412
|
BEST FOR: understanding project structure, onboarding. Much faster than reading files one by one.
|
|
324
|
-
If repo is omitted, auto-detects from current git repo and branch.
|
|
325
|
-
|
|
413
|
+
If repo is omitted, auto-detects from current git repo and branch.
|
|
414
|
+
Auto-indexes the repo if not already in the graph."""
|
|
326
415
|
repo = repo or _get_current_graph_name() or "unknown"
|
|
416
|
+
_ensure_repo_by_name(repo)
|
|
327
417
|
return _get(f"repo/{repo}/map")
|
|
328
418
|
|
|
329
419
|
@mcp.tool()
|
|
@@ -396,16 +486,17 @@ def register_rocket_tools(mcp, api_url: Optional[str] = None):
|
|
|
396
486
|
@mcp.tool()
|
|
397
487
|
def rocket_get_file_churn(repo: str = "", limit: int = 20) -> str:
|
|
398
488
|
"""Get files ranked by change frequency. BEST FOR: identifying unstable/buggy code.
|
|
399
|
-
If repo is omitted, auto-detects from current git repo and branch.
|
|
400
|
-
|
|
489
|
+
If repo is omitted, auto-detects from current git repo and branch.
|
|
490
|
+
Auto-indexes the repo if not already in the graph."""
|
|
401
491
|
repo = repo or _get_current_graph_name() or "unknown"
|
|
492
|
+
_ensure_repo_by_name(repo)
|
|
402
493
|
return _get(f"repo/{repo}/churn", {"limit": limit})
|
|
403
494
|
|
|
404
495
|
@mcp.tool()
|
|
405
496
|
def rocket_stats() -> str:
|
|
406
497
|
"""Get graph statistics: total nodes/edges, breakdown by kind and repo.
|
|
407
|
-
Auto-indexes the current repo if not already in the graph (non-blocking)."""
|
|
408
|
-
_ensure_repo_indexed()
|
|
498
|
+
Auto-indexes the current git repo if not already in the graph (non-blocking)."""
|
|
499
|
+
_ensure_repo_indexed() # index cwd repo if possible
|
|
409
500
|
return _get("stats")
|
|
410
501
|
|
|
411
502
|
@mcp.tool()
|
|
@@ -451,6 +542,7 @@ def register_rocket_tools(mcp, api_url: Optional[str] = None):
|
|
|
451
542
|
data["name"] = name
|
|
452
543
|
return _post("index", data)
|
|
453
544
|
|
|
545
|
+
@mcp.tool()
|
|
454
546
|
@mcp.tool()
|
|
455
547
|
def rocket_index_status(repo: str = "") -> str:
|
|
456
548
|
"""Check indexing status for a repo or all repos.
|
|
@@ -459,3 +551,45 @@ def register_rocket_tools(mcp, api_url: Optional[str] = None):
|
|
|
459
551
|
if repo:
|
|
460
552
|
return _get(f"index/status/{repo}")
|
|
461
553
|
return _get("index/status")
|
|
554
|
+
|
|
555
|
+
@mcp.tool()
|
|
556
|
+
def rocket_session_savings() -> str:
|
|
557
|
+
"""Show how many tokens and time the code graph saved in this session.
|
|
558
|
+
Call at the end of a conversation to report savings.
|
|
559
|
+
Returns: total calls, tokens used via MCP, estimated tokens without MCP, savings percentage."""
|
|
560
|
+
elapsed = _time.time() - _session_start
|
|
561
|
+
total_calls = sum(_call_counts.values())
|
|
562
|
+
|
|
563
|
+
# Estimation: without the graph, each query would require reading ~5 files
|
|
564
|
+
# averaging ~200 lines = ~1000 tokens per file = ~5000 tokens per query.
|
|
565
|
+
# The graph returns structured data at ~1/4 of that cost.
|
|
566
|
+
est_without_mcp = total_calls * 5000
|
|
567
|
+
est_with_mcp = _total_response_tokens
|
|
568
|
+
est_saved = max(0, est_without_mcp - est_with_mcp)
|
|
569
|
+
savings_pct = (est_saved / est_without_mcp * 100) if est_without_mcp > 0 else 0
|
|
570
|
+
|
|
571
|
+
# Cost estimates (Opus pricing: ~$15/M input, ~$75/M output)
|
|
572
|
+
cost_per_token = 15.0 / 1_000_000 # input token cost
|
|
573
|
+
est_cost_mcp = est_with_mcp * cost_per_token
|
|
574
|
+
est_cost_without = est_without_mcp * cost_per_token
|
|
575
|
+
est_cost_saved = est_cost_without - est_cost_mcp
|
|
576
|
+
|
|
577
|
+
# Time estimate: ~2s per file read avoided
|
|
578
|
+
est_time_saved_sec = total_calls * 5 * 2 # 5 files * 2s each
|
|
579
|
+
|
|
580
|
+
minutes = int(elapsed // 60)
|
|
581
|
+
seconds = int(elapsed % 60)
|
|
582
|
+
|
|
583
|
+
return json.dumps({
|
|
584
|
+
"session_duration": f"{minutes}m{seconds}s",
|
|
585
|
+
"total_calls": total_calls,
|
|
586
|
+
"calls_by_tool": _call_counts,
|
|
587
|
+
"mcp_tokens_used": est_with_mcp,
|
|
588
|
+
"est_without_mcp": est_without_mcp,
|
|
589
|
+
"est_tokens_saved": est_saved,
|
|
590
|
+
"est_savings_percent": round(savings_pct, 1),
|
|
591
|
+
"est_cost_mcp_usd": round(est_cost_mcp, 5),
|
|
592
|
+
"est_cost_without_usd": round(est_cost_without, 5),
|
|
593
|
+
"est_cost_saved_usd": round(est_cost_saved, 5),
|
|
594
|
+
"est_time_saved": f"{est_time_saved_sec // 60}m{est_time_saved_sec % 60}s" if est_time_saved_sec >= 60 else f"{est_time_saved_sec}s",
|
|
595
|
+
})
|
|
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
|
|
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
|
|
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
|
|
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
|
{onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/crud-service/src/repositories/__init__.py.j2
RENAMED
|
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
|
{onex_cli-1.16.2 → onex_cli-1.16.4}/onex/templates/event-driven/src/triggers/schedules.py.j2
RENAMED
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|