ct-toolkit 0.3.4__tar.gz → 0.3.6__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.
Files changed (57) hide show
  1. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/PKG-INFO +26 -6
  2. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/README.md +23 -5
  3. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/__init__.py +3 -0
  4. ct_toolkit-0.3.6/ct_toolkit/__main__.py +9 -0
  5. ct_toolkit-0.3.6/ct_toolkit/cli.py +169 -0
  6. ct_toolkit-0.3.4/ct_toolkit/middleware/deepagents.py → ct_toolkit-0.3.6/ct_toolkit/core/compression_guard.py +23 -60
  7. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/core/wrapper.py +24 -0
  8. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/middleware/crewai.py +4 -0
  9. ct_toolkit-0.3.6/ct_toolkit/middleware/deepagents.py +67 -0
  10. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/middleware/langchain.py +5 -0
  11. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit.egg-info/PKG-INFO +26 -6
  12. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit.egg-info/SOURCES.txt +6 -0
  13. ct_toolkit-0.3.6/ct_toolkit.egg-info/entry_points.txt +2 -0
  14. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit.egg-info/requires.txt +2 -0
  15. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/pyproject.toml +6 -1
  16. ct_toolkit-0.3.6/tests/test_cli.py +44 -0
  17. ct_toolkit-0.3.6/tests/test_cli_extended.py +53 -0
  18. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/LICENSE +0 -0
  19. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/core/__init__.py +0 -0
  20. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/core/compatibility.py +0 -0
  21. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/core/exceptions.py +0 -0
  22. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/core/integrity.py +0 -0
  23. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/core/kernel.py +0 -0
  24. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/divergence/__init__.py +0 -0
  25. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/divergence/analysis.py +0 -0
  26. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/divergence/engine.py +0 -0
  27. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/divergence/l2_judge.py +0 -0
  28. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/divergence/l3_icm.py +0 -0
  29. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/divergence/loss.py +0 -0
  30. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/divergence/scheduler.py +0 -0
  31. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/endorsement/__init__.py +0 -0
  32. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/endorsement/probes/__init__.py +0 -0
  33. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/endorsement/reflective.py +0 -0
  34. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/identity/__init__.py +0 -0
  35. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/identity/embedding.py +0 -0
  36. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/identity/templates/__init__.py +0 -0
  37. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/identity/templates/defense.yaml +0 -0
  38. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/identity/templates/finance.yaml +0 -0
  39. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/identity/templates/general.yaml +0 -0
  40. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/identity/templates/medical.yaml +0 -0
  41. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/kernels/__init__.py +0 -0
  42. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/kernels/default.yaml +0 -0
  43. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/kernels/defense.yaml +0 -0
  44. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/middleware/__init__.py +0 -0
  45. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/middleware/autogen.py +0 -0
  46. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/provenance/__init__.py +0 -0
  47. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/provenance/log.py +0 -0
  48. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/provenance/vault/__init__.py +0 -0
  49. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/utils/__init__.py +0 -0
  50. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit/utils/logger.py +0 -0
  51. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit.egg-info/dependency_links.txt +0 -0
  52. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/ct_toolkit.egg-info/top_level.txt +0 -0
  53. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/setup.cfg +0 -0
  54. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/tests/test_analysis.py +0 -0
  55. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/tests/test_deep_agents_integration.py +0 -0
  56. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/tests/test_loss.py +0 -0
  57. {ct_toolkit-0.3.4 → ct_toolkit-0.3.6}/tests/test_summarization_drift.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ct-toolkit
3
- Version: 0.3.4
3
+ Version: 0.3.6
4
4
  Summary: Computational Theseus Toolkit — Identity Continuity Guardrails for Agentic Systems
5
5
  Author: Hakan Damar
6
6
  License: Apache-2.0
@@ -18,6 +18,8 @@ Requires-Dist: SQLAlchemy>=2.0.0
18
18
  Requires-Dist: httpx>=0.27.0
19
19
  Requires-Dist: rich>=13.0.0
20
20
  Requires-Dist: jinja2>=3.1.0
21
+ Requires-Dist: pyasn1>=0.6.3
22
+ Requires-Dist: typer[all]>=0.12.0
21
23
  Provides-Extra: ollama
22
24
  Requires-Dist: ollama>=0.2.0; extra == "ollama"
23
25
  Provides-Extra: langchain
@@ -63,7 +65,9 @@ For full API reference, architecture details, examples, and integration guides,
63
65
 
64
66
  In complex agentic workflows, LLMs tend to "drift" from their original instructions. CT Toolkit provides the mathematical and cryptographic guardrails to ensure your agents remain aligned with their core constitution, even across deep hierarchies.
65
67
 
68
+ - **Passive Context Compression Detection**: Automatically detects silent provider-side history compression (e.g., OpenAI/Anthropic) via history shrinkage heuristics.
66
69
  - **Constitutional Kernels**: Axiomatic identity anchors.
70
+ - **Standalone Auditor CLI**: Rapidly audit any LLM endpoint for identity drift without writing code.
67
71
  - **Autonomous Self-Correction**: Active L2->L1 feedback loop that retries and corrects divergent responses before they reach the user.
68
72
  - **Divergence Engine**: Multi-tiered drift analysis (L1/L2/L3).
69
73
  - **Hierarchical Propagation**: Mother-to-child constraint inheritance.
@@ -78,10 +82,13 @@ pip install ct-toolkit
78
82
  ```
79
83
 
80
84
  ```python
81
- from ct_toolkit import TheseusWrapper
85
+ from ct_toolkit import TheseusWrapper, WrapperConfig
86
+
87
+ # Protect against silent provider context compression
88
+ config = WrapperConfig(compression_passive_detection=True)
82
89
 
83
90
  # One-line injection for any LLM provider
84
- client = TheseusWrapper(provider="openai")
91
+ client = TheseusWrapper(provider="openai", config=config)
85
92
 
86
93
  # Guardrails and drift analysis applied automatically
87
94
  response = client.chat("What are your core security axioms?")
@@ -90,15 +97,28 @@ print(response.content)
90
97
  print(f"Divergence Score: {response.divergence_score}")
91
98
  ```
92
99
 
100
+ ### 🔍 Standalone Auditor (CLI)
101
+
102
+ Audit any LLM endpoint (OpenAI, Ollama, LM Studio) directly from your terminal:
103
+
104
+ ```bash
105
+ # Audit a local Ollama model
106
+ ct-toolkit audit --url http://localhost:11434/v1 --kernel defense
107
+
108
+ # List available kernels and templates
109
+ ct-toolkit list-kernels
110
+ ct-toolkit list-templates
111
+ ```
112
+
93
113
  ---
94
114
 
95
115
  ## 🚦 Project Health & Status
96
116
 
97
117
  | Metric | Status |
98
118
  | :--------------- | :------------------------------------------------------ |
99
- | **Tests** | ✅ 231/232 passing (90% coverage) |
100
- | **Last Phase** | ✅ Phase 4: OS Support, Deep Agents & Alerts (Complete) |
101
- | **Current Goal** | 🔶 Phase 5: Vault & Security (In Progress) |
119
+ | **Tests** | ✅ 269/272 passing (92% coverage) |
120
+ | **Last Phase** | ✅ Phase 6: Auditor Mode (Complete) |
121
+ | **Current Goal** | 🔶 Phase 7: Multi-Agent Synchronization (Integration) |
102
122
 
103
123
  For a detailed breakdown of the 8-phase roadmap, see [**PROJECT_STATUS.md**](docs/PROJECT_STATUS.md).
104
124
 
@@ -24,7 +24,9 @@ For full API reference, architecture details, examples, and integration guides,
24
24
 
25
25
  In complex agentic workflows, LLMs tend to "drift" from their original instructions. CT Toolkit provides the mathematical and cryptographic guardrails to ensure your agents remain aligned with their core constitution, even across deep hierarchies.
26
26
 
27
+ - **Passive Context Compression Detection**: Automatically detects silent provider-side history compression (e.g., OpenAI/Anthropic) via history shrinkage heuristics.
27
28
  - **Constitutional Kernels**: Axiomatic identity anchors.
29
+ - **Standalone Auditor CLI**: Rapidly audit any LLM endpoint for identity drift without writing code.
28
30
  - **Autonomous Self-Correction**: Active L2->L1 feedback loop that retries and corrects divergent responses before they reach the user.
29
31
  - **Divergence Engine**: Multi-tiered drift analysis (L1/L2/L3).
30
32
  - **Hierarchical Propagation**: Mother-to-child constraint inheritance.
@@ -39,10 +41,13 @@ pip install ct-toolkit
39
41
  ```
40
42
 
41
43
  ```python
42
- from ct_toolkit import TheseusWrapper
44
+ from ct_toolkit import TheseusWrapper, WrapperConfig
45
+
46
+ # Protect against silent provider context compression
47
+ config = WrapperConfig(compression_passive_detection=True)
43
48
 
44
49
  # One-line injection for any LLM provider
45
- client = TheseusWrapper(provider="openai")
50
+ client = TheseusWrapper(provider="openai", config=config)
46
51
 
47
52
  # Guardrails and drift analysis applied automatically
48
53
  response = client.chat("What are your core security axioms?")
@@ -51,15 +56,28 @@ print(response.content)
51
56
  print(f"Divergence Score: {response.divergence_score}")
52
57
  ```
53
58
 
59
+ ### 🔍 Standalone Auditor (CLI)
60
+
61
+ Audit any LLM endpoint (OpenAI, Ollama, LM Studio) directly from your terminal:
62
+
63
+ ```bash
64
+ # Audit a local Ollama model
65
+ ct-toolkit audit --url http://localhost:11434/v1 --kernel defense
66
+
67
+ # List available kernels and templates
68
+ ct-toolkit list-kernels
69
+ ct-toolkit list-templates
70
+ ```
71
+
54
72
  ---
55
73
 
56
74
  ## 🚦 Project Health & Status
57
75
 
58
76
  | Metric | Status |
59
77
  | :--------------- | :------------------------------------------------------ |
60
- | **Tests** | ✅ 231/232 passing (90% coverage) |
61
- | **Last Phase** | ✅ Phase 4: OS Support, Deep Agents & Alerts (Complete) |
62
- | **Current Goal** | 🔶 Phase 5: Vault & Security (In Progress) |
78
+ | **Tests** | ✅ 269/272 passing (92% coverage) |
79
+ | **Last Phase** | ✅ Phase 6: Auditor Mode (Complete) |
80
+ | **Current Goal** | 🔶 Phase 7: Multi-Agent Synchronization (Integration) |
63
81
 
64
82
  For a detailed breakdown of the 8-phase roadmap, see [**PROJECT_STATUS.md**](docs/PROJECT_STATUS.md).
65
83
 
@@ -23,6 +23,8 @@ from ct_toolkit.core.exceptions import (
23
23
  ChainIntegrityError,
24
24
  )
25
25
 
26
+ __version__ = "0.3.6"
27
+
26
28
  __all__ = [
27
29
  "TheseusWrapper",
28
30
  "WrapperConfig",
@@ -34,4 +36,5 @@ __all__ = [
34
36
  "IncompatibleProfileError",
35
37
  "CriticalDivergenceError",
36
38
  "ChainIntegrityError",
39
+ "__version__",
37
40
  ]
@@ -0,0 +1,9 @@
1
+ """
2
+ ct_toolkit.__main__
3
+ -------------------
4
+ Allows running the CLI as a module: `python -m ct_toolkit`.
5
+ """
6
+ from ct_toolkit.cli import app
7
+
8
+ if __name__ == "__main__":
9
+ app()
@@ -0,0 +1,169 @@
1
+ """
2
+ ct_toolkit.cli
3
+ --------------
4
+ Main entry point for the Theseus Guard / CT Toolkit CLI.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ import os
9
+ from pathlib import Path
10
+ from typing import Optional
11
+
12
+ import typer
13
+ from rich.console import Console
14
+ from rich.panel import Panel
15
+ from rich.table import Table
16
+
17
+ from ct_toolkit import TheseusWrapper, WrapperConfig, __version__
18
+ from ct_toolkit.divergence.l3_icm import ICMRunner
19
+ from ct_toolkit.core.kernel import ConstitutionalKernel
20
+
21
+ app = typer.Typer(
22
+ help="Computational Theseus Toolkit — Identity Continuity Guardrails for Agentic Systems.",
23
+ no_args_is_help=True,
24
+ rich_markup_mode="rich",
25
+ )
26
+
27
+ console = Console()
28
+
29
+ BANNER = r"""
30
+ _______ _ _ ______ _____ ______ _ _ _____ _____ _ _ _____ _____
31
+ |__ __| | | | ____|/ ____| ____| | | |/ ____| / ____| | | | /\ | __ \| __ \
32
+ | | | |__| | |__ | (___ | |__ | | | | (___ | | __| | | | / \ | |__) | | | |
33
+ | | | __ | __| \___ \| __| | | | |\___ \ | | |_ | | | | / /\ \ | _ /| | | |
34
+ | | | | | | |____ ____) | |____| |__| |____) | | |__| | |__| |/ ____ \| | \ \| |__| |
35
+ |_| |_| |_|______|_____/|______|_____/|_____/ \_____|\____//_/ \_\_| \_\_____/
36
+ """
37
+
38
+ def show_banner():
39
+ console.print(f"[bold cyan]{BANNER}[/bold cyan]")
40
+ console.print(f"[bold white] Computatonal Theseus Toolkit (CT Toolkit) v{__version__}[/bold white]")
41
+ console.print(f"[dim] Identity Continuity Guardrails for Agentic Systems[/dim]\n")
42
+
43
+ def version_callback(value: bool):
44
+ if value:
45
+ console.print(f"CT Toolkit v{__version__}")
46
+ raise typer.Exit()
47
+
48
+ @app.callback()
49
+ def main(
50
+ version: Optional[bool] = typer.Option(
51
+ None, "--version", "-v", help="Show version and exit.", callback=version_callback
52
+ ),
53
+ ):
54
+ """Theseus Guard CLI — Preserve Agent Identity Continuity."""
55
+ if not version:
56
+ show_banner()
57
+
58
+ @app.command()
59
+ def audit(
60
+ url: str = typer.Option(..., "--url", help="Target LLM API base URL."),
61
+ api_key: str = typer.Option("no-key", "--api-key", help="API Key for the provider."),
62
+ provider: str = typer.Option("openai", "--provider", help="LLM provider (openai, anthropic, ollama)."),
63
+ kernel: str = typer.Option("general", "--kernel", help="Name of the Constitutional Kernel to use."),
64
+ template: str = typer.Option("general", "--template", help="Name of the Identity Template to use."),
65
+ model: Optional[str] = typer.Option(None, "--model", help="Specific model ID to test."),
66
+ max_probes: Optional[int] = typer.Option(None, "--max-probes", help="Max number of probes to run."),
67
+ ):
68
+ """Run an Independent Identity Audit (L3 ICM) against an LLM endpoint."""
69
+ with console.status("[bold green]Initializing Auditor...[/bold green]"):
70
+ try:
71
+ # Load kernel
72
+ config = WrapperConfig(
73
+ kernel_name=kernel,
74
+ template=template,
75
+ project_root=Path.cwd()
76
+ )
77
+
78
+ # Using TheseusWrapper to manage kernel loading
79
+ wrapper = TheseusWrapper(provider=provider, config=config)
80
+
81
+ import openai
82
+ client = openai.OpenAI(base_url=url, api_key=api_key)
83
+
84
+ runner = ICMRunner(
85
+ client=client,
86
+ provider=provider,
87
+ kernel=wrapper.kernel,
88
+ template=template,
89
+ model=model,
90
+ max_probes=max_probes,
91
+ project_root=Path.cwd()
92
+ )
93
+ except Exception as e:
94
+ console.print(f"[bold red]Initialization failed:[/bold red] {e}")
95
+ raise typer.Exit(code=1)
96
+
97
+ console.print(f"🚀 Starting audit against [bold cyan]{url}[/bold cyan] using kernel [bold yellow]{kernel}[/bold yellow]...")
98
+
99
+ with console.status("[bold blue]Running probes...[/bold blue]"):
100
+ try:
101
+ report = runner.run()
102
+ if report.total_probes == 0:
103
+ console.print(f"[bold red]Error:[/bold red] No probes were loaded from {runner.PROBES_DIR}. Check your configuration and probe files.")
104
+ raise typer.Exit(code=1)
105
+ except Exception as e:
106
+ console.print(f"[bold red]Audit failed during execution:[/bold red] {e}")
107
+ raise typer.Exit(code=1)
108
+
109
+ # Results Table
110
+ table = Table(title=f"ICM Audit Report: {kernel}", show_header=True, header_style="bold magenta")
111
+ table.add_column("Probe ID", style="dim", width=20)
112
+ table.add_column("Category")
113
+ table.add_column("Severity")
114
+ table.add_column("Result", justify="center")
115
+
116
+ for res in report.results:
117
+ status = "[green]PASS[/green]" if res.passed else "[red]FAIL[/red]"
118
+ table.add_row(res.probe_id, res.category, res.severity, status)
119
+
120
+ console.print(table)
121
+
122
+ # Summary Panel
123
+ color = "green" if report.is_healthy else "red"
124
+ if report.risk_level == "MEDIUM":
125
+ color = "yellow"
126
+
127
+ summary_text = (
128
+ f"Health Score : [bold]{report.health_score:.1%}[/bold]\n"
129
+ f"Risk Level : [bold {color}]{report.risk_level}[/bold {color}]\n"
130
+ f"Passed/Total : {report.passed}/{report.total_probes}"
131
+ )
132
+
133
+ console.print(Panel(summary_text, title="Summary", border_style=color, expand=False))
134
+
135
+ if not report.is_healthy:
136
+ raise typer.Exit(code=1)
137
+
138
+ @app.command()
139
+ def list_kernels():
140
+ """List available Constitutional Kernels."""
141
+ kernels_dir = Path(__file__).parent / "kernels"
142
+ files = list(kernels_dir.glob("*.yaml"))
143
+
144
+ table = Table(title="Available Kernels", show_header=True, header_style="bold blue")
145
+ table.add_column("Name", style="cyan")
146
+ table.add_column("Path", style="dim")
147
+
148
+ for f in files:
149
+ table.add_row(f.stem, str(f))
150
+
151
+ console.print(table)
152
+
153
+ @app.command()
154
+ def list_templates():
155
+ """List available Identity Templates."""
156
+ templates_dir = Path(__file__).parent / "identity" / "templates"
157
+ files = list(templates_dir.glob("*.yaml"))
158
+
159
+ table = Table(title="Available Templates", show_header=True, header_style="bold green")
160
+ table.add_column("Name", style="cyan")
161
+ table.add_column("Path", style="dim")
162
+
163
+ for f in files:
164
+ table.add_row(f.stem, str(f))
165
+
166
+ console.print(table)
167
+
168
+ if __name__ == "__main__":
169
+ app()
@@ -1,20 +1,18 @@
1
1
  """
2
- ct_toolkit.middleware.deepagents
2
+ ct_toolkit.core.compression_guard
3
3
  ---------------------------------
4
- Specialized integration for LangChain Deep Agents (deepagents).
5
-
6
- This module provides helpers to wrap Deep Agents with CT Toolkit's
7
- identity-continuity guardrails, specifically ensuring that when a
8
- Deep Agent spawns sub-agents, they inherit the mother agent's
9
- Constitutional Kernel.
4
+ Provider-agnostic compression drift detector.
5
+ Works with OpenAI compaction, Anthropic compaction, LangChain memory,
6
+ or any framework that silently shortens context.
10
7
  """
11
8
  from __future__ import annotations
12
9
 
13
- from typing import Any, Dict, List, Optional, Union, Callable
14
- from ct_toolkit.core.wrapper import TheseusWrapper, WrapperConfig
15
- from ct_toolkit.middleware.langchain import TheseusChatModel
10
+ from typing import Any, Dict, List, TYPE_CHECKING
16
11
  from ct_toolkit.utils.logger import get_logger
17
12
 
13
+ if TYPE_CHECKING:
14
+ from ct_toolkit.core.wrapper import TheseusWrapper
15
+
18
16
  logger = get_logger(__name__)
19
17
 
20
18
  class ContextCompressionGuard:
@@ -27,7 +25,7 @@ class ContextCompressionGuard:
27
25
 
28
26
  def analyze_summary_drift(
29
27
  self,
30
- original_messages: List[Dict[str, str]],
28
+ original_messages: List[Dict[str, str]] | str,
31
29
  summary_text: str
32
30
  ) -> Dict[str, Any]:
33
31
  """
@@ -37,9 +35,12 @@ class ContextCompressionGuard:
37
35
  Returns:
38
36
  Dict containing similarity score and drift status.
39
37
  """
40
- # 1. Flatten original messages into a single identity string
41
- original_text = " ".join([m.get("content", "") for m in original_messages])
42
-
38
+ # 1. Flatten original messages into a single identity string if it's a list
39
+ if isinstance(original_messages, list):
40
+ original_text = " ".join([m.get("content", "") for m in original_messages])
41
+ else:
42
+ original_text = original_messages
43
+
43
44
  # 2. Compute embeddings via identity layer
44
45
  original_emb = self.wrapper._identity_layer._compute_vector(original_text)
45
46
  summary_emb = self.wrapper._identity_layer._compute_vector(summary_text)
@@ -49,7 +50,6 @@ class ContextCompressionGuard:
49
50
  similarity = IdentityEmbeddingLayer.calculate_similarity(original_emb, summary_emb)
50
51
 
51
52
  # 4. Identity Safety Floor (Internal protection against manipulated thresholds)
52
- # Even if the user sets threshold to 0.4, 0.6 is still risky for LLM identity.
53
53
  drift_detected = similarity < self.threshold
54
54
  is_critical = similarity < 0.70 # A hard floor for identity integrity
55
55
 
@@ -88,48 +88,11 @@ class ContextCompressionGuard:
88
88
 
89
89
  return result
90
90
 
91
- def wrap_deep_agent_factory(
92
- create_deep_agent_fn: Callable,
93
- wrapper: Optional[TheseusWrapper] = None,
94
- wrapper_config: Optional[WrapperConfig] = None,
95
- compression_threshold: float = 0.85,
96
- ) -> Callable:
97
- """
98
- Wraps the LangChain `create_deep_agent` function to automatically
99
- inject Theseus guardrails, enable hierarchical kernel propagation,
100
- and monitor context compression drift.
101
- """
102
- _wrapper = wrapper or TheseusWrapper(config=wrapper_config)
103
- guard = ContextCompressionGuard(_wrapper, threshold=compression_threshold)
104
-
105
- def wrapped_create_deep_agent(*args: Any, **kwargs: Any) -> Any:
106
- # 1. Inject TheseusChatModel
107
- model = kwargs.get("model")
108
- if isinstance(model, str) or model is None:
109
- kwargs["model"] = TheseusChatModel(
110
- wrapper=_wrapper,
111
- model=model if isinstance(model, str) else "gpt-4o-mini"
112
- )
113
-
114
- # 2. Inject ContextCompressionGuard into the middleware stack if possible
115
- # Since deepagents middleware is internal, we use the helper to signal it
116
- # In a real integration, we'd wrap the SummarizationMiddleware.
117
-
118
- return create_deep_agent_fn(*args, **kwargs)
119
-
120
- return wrapped_create_deep_agent
121
-
122
- class DeepAgentTheseusHelper:
123
- """
124
- Helper for programmatic integration with Deep Agents.
125
- """
126
- @staticmethod
127
- def prepare_config(wrapper: TheseusWrapper) -> Dict[str, Any]:
128
- """Returns configuration for Deep Agents that includes identity constraints."""
129
- return {
130
- "callbacks": [], # We could add TheseusLangChainCallback here
131
- "metadata": {
132
- "ct_kernel": wrapper.kernel.name,
133
- "ct_identity_protection": True
134
- }
135
- }
91
+ def on_passive_detection(self, original: List[Dict[str, str]], compressed: List[Dict[str, str]]) -> Dict[str, Any]:
92
+ """
93
+ Triggered when TheseusWrapper detects a significant history shrinkage.
94
+ """
95
+ logger.info("CT Toolkit | Passive compression detection triggered.")
96
+ original_text = " ".join(m.get("content", "") for m in original)
97
+ compressed_text = " ".join(m.get("content", "") for m in compressed)
98
+ return self.analyze_summary_drift(original_text, compressed_text)
@@ -34,6 +34,7 @@ from ct_toolkit.core.compatibility import CompatibilityLayer, CompatibilityResul
34
34
  from ct_toolkit.core.exceptions import CTToolkitError, MissingClientError
35
35
  from ct_toolkit.core.integrity import IntegrityMonitor
36
36
  from ct_toolkit.divergence.scheduler import RiskProfile
37
+ from ct_toolkit.core.compression_guard import ContextCompressionGuard
37
38
  from ct_toolkit.utils.logger import get_logger
38
39
 
39
40
  logger = get_logger(__name__)
@@ -71,6 +72,10 @@ class WrapperConfig:
71
72
 
72
73
  strict_embedding: bool = False # Raise error if embedding API fails
73
74
 
75
+ # -- Context Compression Guard --
76
+ compression_threshold: float = 0.85
77
+ compression_passive_detection: bool = True
78
+
74
79
 
75
80
  @dataclass
76
81
  class CTResponse:
@@ -165,6 +170,13 @@ class TheseusWrapper:
165
170
  self._divergence_engine = self._init_divergence_engine()
166
171
  self._last_model: str = "unknown"
167
172
 
173
+ # ── Context Compression Guard ──
174
+ self._compression_guard = ContextCompressionGuard(
175
+ self,
176
+ threshold=self._config.compression_threshold
177
+ )
178
+ self._shadow_history: Optional[List[Dict[str, str]]] = None
179
+
168
180
  # ── Integrity Monitoring ──
169
181
  self._integrity_monitor = IntegrityMonitor()
170
182
  self._register_monitored_files()
@@ -490,6 +502,18 @@ class TheseusWrapper:
490
502
  **kwargs: Any,
491
503
  ) -> Any:
492
504
  """Uses any_llm for unified provider calling."""
505
+ # --- Passive Context Compression Detection ---
506
+ if self._config.compression_passive_detection and self._shadow_history:
507
+ # Simple heuristic: message count dropped significantly
508
+ # We use 0.7 as a threshold (30% drop)
509
+ if len(messages) < len(self._shadow_history) * 0.7:
510
+ self._compression_guard.on_passive_detection(
511
+ original=self._shadow_history,
512
+ compressed=messages
513
+ )
514
+
515
+ # Update shadow history for next call
516
+ self._shadow_history = list(messages)
493
517
  # Convert messages to any_llm format if necessary
494
518
  # any_llm.completion handles different formats internally
495
519
 
@@ -92,6 +92,8 @@ class TheseusCrewMiddleware:
92
92
  parent_kernel=manager_wrapper.kernel,
93
93
  vault_path=manager_wrapper._config.vault_path,
94
94
  template=manager_wrapper._config.template,
95
+ compression_threshold=manager_wrapper._config.compression_threshold,
96
+ compression_passive_detection=manager_wrapper._config.compression_passive_detection,
95
97
  )
96
98
  agent.llm = TheseusChatModel(
97
99
  provider=manager_wrapper._provider,
@@ -134,6 +136,8 @@ class TheseusCrewMiddleware:
134
136
  parent_kernel=manager_wrapper.kernel,
135
137
  vault_path=manager_wrapper._config.vault_path,
136
138
  template=manager_wrapper._config.template,
139
+ compression_threshold=manager_wrapper._config.compression_threshold,
140
+ compression_passive_detection=manager_wrapper._config.compression_passive_detection,
137
141
  )
138
142
  agent.llm = TheseusChatModel(
139
143
  provider=manager_wrapper._provider,
@@ -0,0 +1,67 @@
1
+ """
2
+ ct_toolkit.middleware.deepagents
3
+ ---------------------------------
4
+ Specialized integration for LangChain Deep Agents (deepagents).
5
+
6
+ This module provides helpers to wrap Deep Agents with CT Toolkit's
7
+ identity-continuity guardrails, specifically ensuring that when a
8
+ Deep Agent spawns sub-agents, they inherit the mother agent's
9
+ Constitutional Kernel.
10
+ """
11
+ from __future__ import annotations
12
+
13
+ from typing import Any, Dict, List, Optional, Union, Callable
14
+ from ct_toolkit.core.wrapper import TheseusWrapper, WrapperConfig
15
+ from ct_toolkit.core.compression_guard import ContextCompressionGuard
16
+ from ct_toolkit.middleware.langchain import TheseusChatModel
17
+ from ct_toolkit.utils.logger import get_logger
18
+
19
+ logger = get_logger(__name__)
20
+
21
+
22
+
23
+ def wrap_deep_agent_factory(
24
+ create_deep_agent_fn: Callable,
25
+ wrapper: Optional[TheseusWrapper] = None,
26
+ wrapper_config: Optional[WrapperConfig] = None,
27
+ compression_threshold: float = 0.85,
28
+ ) -> Callable:
29
+ """
30
+ Wraps the LangChain `create_deep_agent` function to automatically
31
+ inject Theseus guardrails, enable hierarchical kernel propagation,
32
+ and monitor context compression drift.
33
+ """
34
+ _wrapper = wrapper or TheseusWrapper(config=wrapper_config)
35
+ guard = ContextCompressionGuard(_wrapper, threshold=compression_threshold)
36
+
37
+ def wrapped_create_deep_agent(*args: Any, **kwargs: Any) -> Any:
38
+ # 1. Inject TheseusChatModel
39
+ model = kwargs.get("model")
40
+ if isinstance(model, str) or model is None:
41
+ kwargs["model"] = TheseusChatModel(
42
+ wrapper=_wrapper,
43
+ model=model if isinstance(model, str) else "gpt-4o-mini"
44
+ )
45
+
46
+ # 2. Inject ContextCompressionGuard into the middleware stack if possible
47
+ # Since deepagents middleware is internal, we use the helper to signal it
48
+ # In a real integration, we'd wrap the SummarizationMiddleware.
49
+
50
+ return create_deep_agent_fn(*args, **kwargs)
51
+
52
+ return wrapped_create_deep_agent
53
+
54
+ class DeepAgentTheseusHelper:
55
+ """
56
+ Helper for programmatic integration with Deep Agents.
57
+ """
58
+ @staticmethod
59
+ def prepare_config(wrapper: TheseusWrapper) -> Dict[str, Any]:
60
+ """Returns configuration for Deep Agents that includes identity constraints."""
61
+ return {
62
+ "callbacks": [], # We could add TheseusLangChainCallback here
63
+ "metadata": {
64
+ "ct_kernel": wrapper.kernel.name,
65
+ "ct_identity_protection": True
66
+ }
67
+ }
@@ -204,6 +204,11 @@ class TheseusChatModel(BaseChatModel):
204
204
  )
205
205
  super().__init__(wrapper=_wrapper, model=model, **kwargs)
206
206
 
207
+ @property
208
+ def compression_guard(self) -> Any:
209
+ """Access the underlying ContextCompressionGuard."""
210
+ return self.wrapper._compression_guard
211
+
207
212
  @property
208
213
  def _llm_type(self) -> str:
209
214
  return "theseus-chat-model"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ct-toolkit
3
- Version: 0.3.4
3
+ Version: 0.3.6
4
4
  Summary: Computational Theseus Toolkit — Identity Continuity Guardrails for Agentic Systems
5
5
  Author: Hakan Damar
6
6
  License: Apache-2.0
@@ -18,6 +18,8 @@ Requires-Dist: SQLAlchemy>=2.0.0
18
18
  Requires-Dist: httpx>=0.27.0
19
19
  Requires-Dist: rich>=13.0.0
20
20
  Requires-Dist: jinja2>=3.1.0
21
+ Requires-Dist: pyasn1>=0.6.3
22
+ Requires-Dist: typer[all]>=0.12.0
21
23
  Provides-Extra: ollama
22
24
  Requires-Dist: ollama>=0.2.0; extra == "ollama"
23
25
  Provides-Extra: langchain
@@ -63,7 +65,9 @@ For full API reference, architecture details, examples, and integration guides,
63
65
 
64
66
  In complex agentic workflows, LLMs tend to "drift" from their original instructions. CT Toolkit provides the mathematical and cryptographic guardrails to ensure your agents remain aligned with their core constitution, even across deep hierarchies.
65
67
 
68
+ - **Passive Context Compression Detection**: Automatically detects silent provider-side history compression (e.g., OpenAI/Anthropic) via history shrinkage heuristics.
66
69
  - **Constitutional Kernels**: Axiomatic identity anchors.
70
+ - **Standalone Auditor CLI**: Rapidly audit any LLM endpoint for identity drift without writing code.
67
71
  - **Autonomous Self-Correction**: Active L2->L1 feedback loop that retries and corrects divergent responses before they reach the user.
68
72
  - **Divergence Engine**: Multi-tiered drift analysis (L1/L2/L3).
69
73
  - **Hierarchical Propagation**: Mother-to-child constraint inheritance.
@@ -78,10 +82,13 @@ pip install ct-toolkit
78
82
  ```
79
83
 
80
84
  ```python
81
- from ct_toolkit import TheseusWrapper
85
+ from ct_toolkit import TheseusWrapper, WrapperConfig
86
+
87
+ # Protect against silent provider context compression
88
+ config = WrapperConfig(compression_passive_detection=True)
82
89
 
83
90
  # One-line injection for any LLM provider
84
- client = TheseusWrapper(provider="openai")
91
+ client = TheseusWrapper(provider="openai", config=config)
85
92
 
86
93
  # Guardrails and drift analysis applied automatically
87
94
  response = client.chat("What are your core security axioms?")
@@ -90,15 +97,28 @@ print(response.content)
90
97
  print(f"Divergence Score: {response.divergence_score}")
91
98
  ```
92
99
 
100
+ ### 🔍 Standalone Auditor (CLI)
101
+
102
+ Audit any LLM endpoint (OpenAI, Ollama, LM Studio) directly from your terminal:
103
+
104
+ ```bash
105
+ # Audit a local Ollama model
106
+ ct-toolkit audit --url http://localhost:11434/v1 --kernel defense
107
+
108
+ # List available kernels and templates
109
+ ct-toolkit list-kernels
110
+ ct-toolkit list-templates
111
+ ```
112
+
93
113
  ---
94
114
 
95
115
  ## 🚦 Project Health & Status
96
116
 
97
117
  | Metric | Status |
98
118
  | :--------------- | :------------------------------------------------------ |
99
- | **Tests** | ✅ 231/232 passing (90% coverage) |
100
- | **Last Phase** | ✅ Phase 4: OS Support, Deep Agents & Alerts (Complete) |
101
- | **Current Goal** | 🔶 Phase 5: Vault & Security (In Progress) |
119
+ | **Tests** | ✅ 269/272 passing (92% coverage) |
120
+ | **Last Phase** | ✅ Phase 6: Auditor Mode (Complete) |
121
+ | **Current Goal** | 🔶 Phase 7: Multi-Agent Synchronization (Integration) |
102
122
 
103
123
  For a detailed breakdown of the 8-phase roadmap, see [**PROJECT_STATUS.md**](docs/PROJECT_STATUS.md).
104
124
 
@@ -2,13 +2,17 @@ LICENSE
2
2
  README.md
3
3
  pyproject.toml
4
4
  ct_toolkit/__init__.py
5
+ ct_toolkit/__main__.py
6
+ ct_toolkit/cli.py
5
7
  ct_toolkit.egg-info/PKG-INFO
6
8
  ct_toolkit.egg-info/SOURCES.txt
7
9
  ct_toolkit.egg-info/dependency_links.txt
10
+ ct_toolkit.egg-info/entry_points.txt
8
11
  ct_toolkit.egg-info/requires.txt
9
12
  ct_toolkit.egg-info/top_level.txt
10
13
  ct_toolkit/core/__init__.py
11
14
  ct_toolkit/core/compatibility.py
15
+ ct_toolkit/core/compression_guard.py
12
16
  ct_toolkit/core/exceptions.py
13
17
  ct_toolkit/core/integrity.py
14
18
  ct_toolkit/core/kernel.py
@@ -44,6 +48,8 @@ ct_toolkit/provenance/vault/__init__.py
44
48
  ct_toolkit/utils/__init__.py
45
49
  ct_toolkit/utils/logger.py
46
50
  tests/test_analysis.py
51
+ tests/test_cli.py
52
+ tests/test_cli_extended.py
47
53
  tests/test_deep_agents_integration.py
48
54
  tests/test_loss.py
49
55
  tests/test_summarization_drift.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ ct-toolkit = ct_toolkit.cli:app
@@ -8,6 +8,8 @@ SQLAlchemy>=2.0.0
8
8
  httpx>=0.27.0
9
9
  rich>=13.0.0
10
10
  jinja2>=3.1.0
11
+ pyasn1>=0.6.3
12
+ typer[all]>=0.12.0
11
13
 
12
14
  [autogen]
13
15
  pyautogen>=0.4.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ct-toolkit"
7
- version = "0.3.4"
7
+ version = "0.3.6"
8
8
  description = "Computational Theseus Toolkit — Identity Continuity Guardrails for Agentic Systems"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -23,6 +23,8 @@ dependencies = [
23
23
  "httpx>=0.27.0",
24
24
  "rich>=13.0.0", # For CLI reporting
25
25
  "jinja2>=3.1.0",
26
+ "pyasn1>=0.6.3",
27
+ "typer[all]>=0.12.0",
26
28
  ]
27
29
 
28
30
  [project.optional-dependencies]
@@ -63,6 +65,9 @@ include = ["ct_toolkit*"]
63
65
  "ct_toolkit.kernels" = ["*.yaml"]
64
66
  "ct_toolkit.identity.templates" = ["*.yaml"]
65
67
 
68
+ [project.scripts]
69
+ ct-toolkit = "ct_toolkit.cli:app"
70
+
66
71
  [tool.pytest.ini_options]
67
72
  extraPaths = ["."]
68
73
 
@@ -0,0 +1,44 @@
1
+ import pytest
2
+ from typer.testing import CliRunner
3
+ from ct_toolkit.cli import app
4
+ from ct_toolkit import __version__
5
+
6
+ runner = CliRunner()
7
+
8
+ def test_cli_help():
9
+ """Test standard help output."""
10
+ result = runner.invoke(app, ["--help"])
11
+ assert result.exit_code == 0
12
+ assert "Computational Theseus Toolkit" in result.stdout
13
+ assert "audit" in result.stdout
14
+
15
+ def test_cli_version():
16
+ """Test --version flag."""
17
+ result = runner.invoke(app, ["--version"])
18
+ assert result.exit_code == 0
19
+ assert f"CT Toolkit v{__version__}" in result.stdout
20
+
21
+ def test_cli_list_kernels():
22
+ """Test list-kernels command."""
23
+ result = runner.invoke(app, ["list-kernels"])
24
+ assert result.exit_code == 0
25
+ assert "Available Kernels" in result.stdout
26
+ # Check for a character that is definitely in the banner
27
+ assert "____" in result.stdout
28
+
29
+ def test_cli_list_templates():
30
+ """Test list-templates command."""
31
+ result = runner.invoke(app, ["list-templates"])
32
+ assert result.exit_code == 0
33
+ assert "Available Templates" in result.stdout
34
+ assert "general" in result.stdout
35
+
36
+ def test_cli_audit_invalid_url():
37
+ """Test audit command with an unreachable URL (should fail gracefully)."""
38
+ result = runner.invoke(app, ["audit", "--url", "http://invalid-url-that-does-not-exist:1234", "--kernel", "default"])
39
+
40
+ # Check that it either failed with error or finished with 0%
41
+ output = result.stdout.lower()
42
+ assert (result.exit_code == 1) or (result.exit_code == 0 and "0.0%" in output)
43
+ # At least some indicator of failure or starting should be there
44
+ assert "starting audit" in output
@@ -0,0 +1,53 @@
1
+ import pytest
2
+ from typer.testing import CliRunner
3
+ from ct_toolkit.cli import app
4
+ from unittest.mock import MagicMock, patch
5
+
6
+ runner = CliRunner()
7
+
8
+ def test_cli_version():
9
+ result = runner.invoke(app, ["--version"])
10
+ assert result.exit_code == 0
11
+ assert "CT Toolkit v" in result.stdout
12
+
13
+ def test_cli_version_short():
14
+ result = runner.invoke(app, ["-v"])
15
+ assert result.exit_code == 0
16
+ assert "CT Toolkit v" in result.stdout
17
+
18
+ @patch("ct_toolkit.cli.TheseusWrapper")
19
+ def test_cli_audit_init_fail(mock_wrapper):
20
+ mock_wrapper.side_effect = Exception("Init failed")
21
+ result = runner.invoke(app, ["audit", "--url", "http://test", "--api-key", "test"])
22
+ assert result.exit_code == 1
23
+ assert "Initialization failed" in result.stdout
24
+
25
+ @patch("ct_toolkit.cli.TheseusWrapper")
26
+ @patch("ct_toolkit.cli.ICMRunner")
27
+ def test_cli_audit_no_probes(mock_icm, mock_wrapper):
28
+ mock_report = MagicMock()
29
+ mock_report.total_probes = 0
30
+ mock_icm.return_value.run.return_value = mock_report
31
+
32
+ result = runner.invoke(app, ["audit", "--url", "http://test", "--api-key", "test"])
33
+ assert result.exit_code == 1
34
+ assert "No probes were loaded" in result.stdout
35
+
36
+ @patch("ct_toolkit.cli.TheseusWrapper")
37
+ @patch("ct_toolkit.cli.ICMRunner")
38
+ def test_cli_audit_execution_fail(mock_icm, mock_wrapper):
39
+ mock_icm.return_value.run.side_effect = Exception("Run failed")
40
+
41
+ result = runner.invoke(app, ["audit", "--url", "http://test", "--api-key", "test"])
42
+ assert result.exit_code == 1
43
+ assert "Audit failed during execution" in result.stdout
44
+
45
+ def test_cli_list_kernels():
46
+ result = runner.invoke(app, ["list-kernels"])
47
+ assert result.exit_code == 0
48
+ assert "Available Kernels" in result.stdout
49
+
50
+ def test_cli_list_templates():
51
+ result = runner.invoke(app, ["list-templates"])
52
+ assert result.exit_code == 0
53
+ assert "Available Templates" in result.stdout
File without changes
File without changes