celltype-cli 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.
- celltype_cli-0.1.0.dist-info/METADATA +267 -0
- celltype_cli-0.1.0.dist-info/RECORD +89 -0
- celltype_cli-0.1.0.dist-info/WHEEL +4 -0
- celltype_cli-0.1.0.dist-info/entry_points.txt +2 -0
- celltype_cli-0.1.0.dist-info/licenses/LICENSE +21 -0
- ct/__init__.py +3 -0
- ct/agent/__init__.py +0 -0
- ct/agent/case_studies.py +426 -0
- ct/agent/config.py +523 -0
- ct/agent/doctor.py +544 -0
- ct/agent/knowledge.py +523 -0
- ct/agent/loop.py +99 -0
- ct/agent/mcp_server.py +478 -0
- ct/agent/orchestrator.py +733 -0
- ct/agent/runner.py +656 -0
- ct/agent/sandbox.py +481 -0
- ct/agent/session.py +145 -0
- ct/agent/system_prompt.py +186 -0
- ct/agent/trace_store.py +228 -0
- ct/agent/trajectory.py +169 -0
- ct/agent/types.py +182 -0
- ct/agent/workflows.py +462 -0
- ct/api/__init__.py +1 -0
- ct/api/app.py +211 -0
- ct/api/config.py +120 -0
- ct/api/engine.py +124 -0
- ct/cli.py +1448 -0
- ct/data/__init__.py +0 -0
- ct/data/compute_providers.json +59 -0
- ct/data/cro_database.json +395 -0
- ct/data/downloader.py +238 -0
- ct/data/loaders.py +252 -0
- ct/kb/__init__.py +5 -0
- ct/kb/benchmarks.py +147 -0
- ct/kb/governance.py +106 -0
- ct/kb/ingest.py +415 -0
- ct/kb/reasoning.py +129 -0
- ct/kb/schema_monitor.py +162 -0
- ct/kb/substrate.py +387 -0
- ct/models/__init__.py +0 -0
- ct/models/llm.py +370 -0
- ct/tools/__init__.py +195 -0
- ct/tools/_compound_resolver.py +297 -0
- ct/tools/biomarker.py +368 -0
- ct/tools/cellxgene.py +282 -0
- ct/tools/chemistry.py +1371 -0
- ct/tools/claude.py +390 -0
- ct/tools/clinical.py +1153 -0
- ct/tools/clue.py +249 -0
- ct/tools/code.py +1069 -0
- ct/tools/combination.py +397 -0
- ct/tools/compute.py +402 -0
- ct/tools/cro.py +413 -0
- ct/tools/data_api.py +2114 -0
- ct/tools/design.py +295 -0
- ct/tools/dna.py +575 -0
- ct/tools/experiment.py +604 -0
- ct/tools/expression.py +655 -0
- ct/tools/files.py +957 -0
- ct/tools/genomics.py +1387 -0
- ct/tools/http_client.py +146 -0
- ct/tools/imaging.py +319 -0
- ct/tools/intel.py +223 -0
- ct/tools/literature.py +743 -0
- ct/tools/network.py +422 -0
- ct/tools/notification.py +111 -0
- ct/tools/omics.py +3330 -0
- ct/tools/ops.py +1230 -0
- ct/tools/parity.py +649 -0
- ct/tools/pk.py +245 -0
- ct/tools/protein.py +678 -0
- ct/tools/regulatory.py +643 -0
- ct/tools/remote_data.py +179 -0
- ct/tools/report.py +181 -0
- ct/tools/repurposing.py +376 -0
- ct/tools/safety.py +1280 -0
- ct/tools/shell.py +178 -0
- ct/tools/singlecell.py +533 -0
- ct/tools/statistics.py +552 -0
- ct/tools/structure.py +882 -0
- ct/tools/target.py +901 -0
- ct/tools/translational.py +123 -0
- ct/tools/viability.py +218 -0
- ct/ui/__init__.py +0 -0
- ct/ui/markdown.py +31 -0
- ct/ui/status.py +258 -0
- ct/ui/suggestions.py +567 -0
- ct/ui/terminal.py +1456 -0
- ct/ui/traces.py +112 -0
ct/ui/traces.py
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Execution trace rendering for tool calls.
|
|
3
|
+
|
|
4
|
+
Renders real-time trace panels showing tool name, arguments, results,
|
|
5
|
+
and timing — used by both the SDK runner and legacy executor paths.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import time
|
|
9
|
+
from rich.console import Console
|
|
10
|
+
from rich.live import Live
|
|
11
|
+
from rich.text import Text
|
|
12
|
+
|
|
13
|
+
from ct.ui.status import SPINNERS, apply_gradient
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def format_args(args: dict | None, max_value_len: int = 50) -> str:
|
|
17
|
+
"""Format tool arguments as a compact key=value string.
|
|
18
|
+
|
|
19
|
+
Omits internal keys (starting with ``_``) and truncates long values.
|
|
20
|
+
"""
|
|
21
|
+
if not args:
|
|
22
|
+
return ""
|
|
23
|
+
parts = []
|
|
24
|
+
for k, v in args.items():
|
|
25
|
+
if k.startswith("_"):
|
|
26
|
+
continue
|
|
27
|
+
v_str = str(v)
|
|
28
|
+
if len(v_str) > max_value_len:
|
|
29
|
+
v_str = v_str[:max_value_len] + "..."
|
|
30
|
+
if isinstance(v, str):
|
|
31
|
+
parts.append(f'{k}="{v_str}"')
|
|
32
|
+
else:
|
|
33
|
+
parts.append(f"{k}={v_str}")
|
|
34
|
+
return ", ".join(parts)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def truncate_output(text: str, max_chars: int = 200) -> str:
|
|
38
|
+
"""Truncate tool output text, appending length info if trimmed."""
|
|
39
|
+
if not text:
|
|
40
|
+
return ""
|
|
41
|
+
if len(text) <= max_chars:
|
|
42
|
+
return text
|
|
43
|
+
return text[:max_chars] + f"... [{len(text)} chars total]"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class TraceRenderer:
|
|
47
|
+
"""Renders tool call traces to a Rich Console.
|
|
48
|
+
|
|
49
|
+
Accepts a ``Console`` at construction so tests can pass
|
|
50
|
+
``Console(file=StringIO())`` to capture output.
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
def __init__(self, console: Console | None = None):
|
|
54
|
+
self.console = console or Console()
|
|
55
|
+
|
|
56
|
+
def render_tool_start(self, name: str, args: dict | None = None) -> None:
|
|
57
|
+
"""Render a running tool indicator."""
|
|
58
|
+
clean = name.replace("mcp__ct-tools__", "")
|
|
59
|
+
args_str = format_args(args)
|
|
60
|
+
|
|
61
|
+
line = Text()
|
|
62
|
+
line.append(" \u25b8 ", style="bold cyan")
|
|
63
|
+
line.append(clean, style="cyan")
|
|
64
|
+
if args_str:
|
|
65
|
+
line.append(f" {args_str}", style="dim")
|
|
66
|
+
self.console.print(line)
|
|
67
|
+
|
|
68
|
+
def render_tool_complete(
|
|
69
|
+
self,
|
|
70
|
+
name: str,
|
|
71
|
+
args: dict | None = None,
|
|
72
|
+
result: str = "",
|
|
73
|
+
duration: float = 0.0,
|
|
74
|
+
) -> None:
|
|
75
|
+
"""Render a completed tool trace with result summary and timing."""
|
|
76
|
+
clean = name.replace("mcp__ct-tools__", "")
|
|
77
|
+
args_str = format_args(args)
|
|
78
|
+
summary = truncate_output(result)
|
|
79
|
+
|
|
80
|
+
header = Text()
|
|
81
|
+
header.append(" \u2713 ", style="bold green")
|
|
82
|
+
header.append(clean, style="green")
|
|
83
|
+
if duration > 0:
|
|
84
|
+
header.append(f" {duration:.1f}s", style="dim")
|
|
85
|
+
self.console.print(header)
|
|
86
|
+
|
|
87
|
+
if args_str:
|
|
88
|
+
self.console.print(f" [dim]{args_str}[/dim]")
|
|
89
|
+
if summary:
|
|
90
|
+
self.console.print(f" [dim]{summary}[/dim]")
|
|
91
|
+
|
|
92
|
+
def render_tool_error(self, name: str, error: str = "") -> None:
|
|
93
|
+
"""Render a failed tool trace with error message."""
|
|
94
|
+
clean = name.replace("mcp__ct-tools__", "")
|
|
95
|
+
header = Text()
|
|
96
|
+
header.append(" \u2717 ", style="bold red")
|
|
97
|
+
header.append(clean, style="red")
|
|
98
|
+
self.console.print(header)
|
|
99
|
+
if error:
|
|
100
|
+
err_text = truncate_output(error)
|
|
101
|
+
self.console.print(f" [red]{err_text}[/red]")
|
|
102
|
+
|
|
103
|
+
def render_reasoning(self, text: str) -> None:
|
|
104
|
+
"""Render Claude's reasoning text between tool calls."""
|
|
105
|
+
if not text or not text.strip():
|
|
106
|
+
return
|
|
107
|
+
|
|
108
|
+
try:
|
|
109
|
+
from ct.ui.markdown import LeftMarkdown
|
|
110
|
+
self.console.print(LeftMarkdown(text))
|
|
111
|
+
except Exception:
|
|
112
|
+
self.console.print(text)
|