netra-zen 1.0.1__py3-none-any.whl → 1.0.2__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.
- {netra_zen-1.0.1.dist-info → netra_zen-1.0.2.dist-info}/METADATA +776 -776
- {netra_zen-1.0.1.dist-info → netra_zen-1.0.2.dist-info}/RECORD +7 -7
- {netra_zen-1.0.1.dist-info → netra_zen-1.0.2.dist-info}/licenses/LICENSE.md +1 -1
- zen_orchestrator.py +103 -37
- {netra_zen-1.0.1.dist-info → netra_zen-1.0.2.dist-info}/WHEEL +0 -0
- {netra_zen-1.0.1.dist-info → netra_zen-1.0.2.dist-info}/entry_points.txt +0 -0
- {netra_zen-1.0.1.dist-info → netra_zen-1.0.2.dist-info}/top_level.txt +0 -0
@@ -1,15 +1,15 @@
|
|
1
|
-
zen_orchestrator.py,sha256=
|
1
|
+
zen_orchestrator.py,sha256=Q4bEnsyMYPJV6R9PutC6vrfxGiaOizlFjSW6qJDLrDI,148686
|
2
2
|
agent_interface/__init__.py,sha256=OsbOKzElHsxhVgak87oOx_u46QNgKmz-Reis-plAMwk,525
|
3
3
|
agent_interface/base_agent.py,sha256=GNskG9VaZgno7X24lQTpFdxUoQE0yJHLh0UPFJvOPn4,11098
|
4
|
-
netra_zen-1.0.
|
4
|
+
netra_zen-1.0.2.dist-info/licenses/LICENSE.md,sha256=t6LtOzAE2hgIIv5WbaN0wOcU3QCnGtAkMGNclHrKTOs,79
|
5
5
|
token_budget/__init__.py,sha256=_2tmi72DGNtbYcZ-rGIxVKMytdkHFjzJaWz8bDhYACc,33
|
6
6
|
token_budget/budget_manager.py,sha256=VRWxKcGDtgJfIRh-ztYQ4-wuhBvddVJJnyoGfxCBlv0,9567
|
7
7
|
token_budget/models.py,sha256=14xFTk2-R1Ql0F9WLDof7vADrKC_5Fj7EE7UmZdoG00,2384
|
8
8
|
token_budget/visualization.py,sha256=SaNnZ15edHXtjDCA5Yfu7w3AztCZRYsYCPGBqzapupY,719
|
9
9
|
token_transparency/__init__.py,sha256=go86Rg4_VYAPLw3myVpLe1s1PbMu1llDTw1wfomP1lA,453
|
10
10
|
token_transparency/claude_pricing_engine.py,sha256=9zWQJS3HJEs_lljil-xT1cUvG-Jf3ykNAninJFyfNSM,12630
|
11
|
-
netra_zen-1.0.
|
12
|
-
netra_zen-1.0.
|
13
|
-
netra_zen-1.0.
|
14
|
-
netra_zen-1.0.
|
15
|
-
netra_zen-1.0.
|
11
|
+
netra_zen-1.0.2.dist-info/METADATA,sha256=3iv4Hq5DNLRAMivXVCwx_jieqevK_G3d1OU0Tbksl-g,29442
|
12
|
+
netra_zen-1.0.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
13
|
+
netra_zen-1.0.2.dist-info/entry_points.txt,sha256=oDehCnPGZezG0m9ZWspxjHLHyQ3eERX87eojR4ljaRo,45
|
14
|
+
netra_zen-1.0.2.dist-info/top_level.txt,sha256=dHz-hgh_dfiiOUrPf8wW80fA31rfEYDFmA6fpu67Yjk,65
|
15
|
+
netra_zen-1.0.2.dist-info/RECORD,,
|
@@ -1 +1 @@
|
|
1
|
-
© Netra Inc. All rights reserved. Use is subject to Netra's Terms of Service.
|
1
|
+
© Netra Inc. All rights reserved. Use is subject to Netra's Terms of Service.
|
zen_orchestrator.py
CHANGED
@@ -2,43 +2,41 @@
|
|
2
2
|
"""
|
3
3
|
Usage Examples:
|
4
4
|
|
5
|
-
zen -h # Help
|
6
|
-
|
7
5
|
Direct Command Execution:
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
6
|
+
python zen_orchestrator.py "/help" # Execute single command directly
|
7
|
+
python zen_orchestrator.py "/analyze-code" --workspace ~/my-project
|
8
|
+
python zen_orchestrator.py "/debug-issue" --instance-name "debug-session"
|
9
|
+
python zen_orchestrator.py "/optimize-performance" --session-id "perf-1"
|
10
|
+
python zen_orchestrator.py "/generate-docs" --clear-history --compact-history
|
13
11
|
|
14
12
|
Configuration File Mode:
|
15
|
-
|
16
|
-
|
13
|
+
python zen_orchestrator.py --config config.json
|
14
|
+
python zen_orchestrator.py --config config.json --workspace ~/my-project
|
17
15
|
|
18
16
|
Default Instances Mode:
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
17
|
+
python zen_orchestrator.py --dry-run # Auto-detects workspace from project root
|
18
|
+
python zen_orchestrator.py --workspace ~/my-project --dry-run # Override workspace
|
19
|
+
python zen_orchestrator.py --startup-delay 2.0 # 2 second delay between launches
|
20
|
+
python zen_orchestrator.py --startup-delay 0.5 # 0.5 second delay between launches
|
21
|
+
python zen_orchestrator.py --max-line-length 1000 # Longer output lines
|
22
|
+
python zen_orchestrator.py --status-report-interval 60 # Status reports every 60s
|
23
|
+
python zen_orchestrator.py --quiet # Minimal output, errors only
|
26
24
|
|
27
25
|
Command Discovery:
|
28
|
-
|
29
|
-
|
26
|
+
python zen_orchestrator.py --list-commands # Show all available commands
|
27
|
+
python zen_orchestrator.py --inspect-command "/analyze-code" # Inspect specific command
|
30
28
|
|
31
29
|
Scheduling:
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
30
|
+
python zen_orchestrator.py "/analyze-code" --start-at "2h" # Start 2 hours from now
|
31
|
+
python zen_orchestrator.py "/debug-issue" --start-at "30m" # Start in 30 minutes
|
32
|
+
python zen_orchestrator.py "/optimize" --start-at "1am" # Start at 1 AM (today or tomorrow)
|
33
|
+
python zen_orchestrator.py "/review-code" --start-at "14:30" # Start at 2:30 PM (today or tomorrow)
|
34
|
+
python zen_orchestrator.py "/generate-docs" --start-at "10:30pm" # Start at 10:30 PM (today or tomorrow)
|
37
35
|
|
38
36
|
Precedence Rules:
|
39
|
-
1. Direct command (highest) -
|
40
|
-
2. Config file (medium) -
|
41
|
-
3. Default instances (lowest) -
|
37
|
+
1. Direct command (highest) - python zen_orchestrator.py "/command"
|
38
|
+
2. Config file (medium) - python zen_orchestrator.py --config file.json
|
39
|
+
3. Default instances (lowest) - python zen_orchestrator.py
|
42
40
|
"""
|
43
41
|
|
44
42
|
import asyncio
|
@@ -79,6 +77,16 @@ except ImportError as e:
|
|
79
77
|
ClaudePricingEngine = None
|
80
78
|
TokenUsageData = None
|
81
79
|
|
80
|
+
# Add CLI extensions imports
|
81
|
+
try:
|
82
|
+
from cli_extensions import handle_example_commands
|
83
|
+
except ImportError as e:
|
84
|
+
# Graceful fallback if CLI extensions are not available
|
85
|
+
handle_example_commands = None
|
86
|
+
|
87
|
+
# NetraOptimizer database functionality has been removed for security
|
88
|
+
# Local token metrics are preserved without database persistence
|
89
|
+
|
82
90
|
# Setup logging
|
83
91
|
logging.basicConfig(
|
84
92
|
level=logging.INFO,
|
@@ -107,7 +115,8 @@ def determine_log_level(args) -> LogLevel:
|
|
107
115
|
@dataclass
|
108
116
|
class InstanceConfig:
|
109
117
|
"""Configuration for a Claude Code instance"""
|
110
|
-
command: str
|
118
|
+
command: Optional[str] = None # For slash commands like /help
|
119
|
+
prompt: Optional[str] = None # For raw prompts like "What are the available commands?"
|
111
120
|
name: Optional[str] = None
|
112
121
|
description: Optional[str] = None
|
113
122
|
allowed_tools: List[str] = None
|
@@ -121,10 +130,35 @@ class InstanceConfig:
|
|
121
130
|
|
122
131
|
def __post_init__(self):
|
123
132
|
"""Set defaults after initialization"""
|
133
|
+
# Validate that either command or prompt is provided
|
134
|
+
if not self.command and not self.prompt:
|
135
|
+
raise ValueError("Either 'command' or 'prompt' must be provided")
|
136
|
+
|
137
|
+
# If both are provided, prioritize command over prompt
|
138
|
+
if self.command and self.prompt:
|
139
|
+
# Use command, but log that prompt is being ignored
|
140
|
+
pass # This is valid - command takes precedence
|
141
|
+
|
142
|
+
# If only prompt is provided, treat it as the command for execution
|
143
|
+
elif self.prompt and not self.command:
|
144
|
+
self.command = self.prompt
|
145
|
+
|
146
|
+
# Set default name
|
124
147
|
if self.name is None:
|
125
|
-
self.
|
148
|
+
if self.command and self.command.startswith('/'):
|
149
|
+
self.name = self.command
|
150
|
+
else:
|
151
|
+
# For prompts, create a shorter name
|
152
|
+
display_text = self.prompt or self.command
|
153
|
+
self.name = display_text[:30] + "..." if len(display_text) > 30 else display_text
|
154
|
+
|
155
|
+
# Set default description
|
126
156
|
if self.description is None:
|
127
|
-
self.
|
157
|
+
if self.command and self.command.startswith('/'):
|
158
|
+
self.description = f"Execute {self.command}"
|
159
|
+
else:
|
160
|
+
self.description = f"Execute prompt: {(self.prompt or self.command)[:50]}..."
|
161
|
+
|
128
162
|
# Set permission mode if not explicitly set
|
129
163
|
if self.permission_mode is None:
|
130
164
|
# Default to bypassPermissions for all platforms to avoid approval prompts
|
@@ -180,7 +214,7 @@ class ClaudeInstanceOrchestrator:
|
|
180
214
|
|
181
215
|
def __init__(self, workspace_dir: Path, max_console_lines: int = 5, startup_delay: float = 1.0,
|
182
216
|
max_line_length: int = 500, status_report_interval: int = 30,
|
183
|
-
quiet: bool = False,
|
217
|
+
use_cloud_sql: bool = False, quiet: bool = False,
|
184
218
|
overall_token_budget: Optional[int] = None,
|
185
219
|
overall_cost_budget: Optional[float] = None,
|
186
220
|
budget_type: str = "tokens",
|
@@ -199,9 +233,11 @@ class ClaudeInstanceOrchestrator:
|
|
199
233
|
self.status_report_interval = status_report_interval # Seconds between status reports
|
200
234
|
self.last_status_report = time.time()
|
201
235
|
self.status_report_task = None # For the rolling status report task
|
236
|
+
self.use_cloud_sql = use_cloud_sql
|
202
237
|
self.quiet = quiet
|
203
238
|
self.log_level = log_level
|
204
239
|
self.batch_id = str(uuid4()) # Generate batch ID for this orchestration run
|
240
|
+
# Database client removed for security - local metrics only
|
205
241
|
self.optimizer = None
|
206
242
|
|
207
243
|
# Initialize budget manager if any budget settings are provided
|
@@ -242,6 +278,12 @@ class ClaudeInstanceOrchestrator:
|
|
242
278
|
else:
|
243
279
|
logger.debug("Token budget tracking disabled (no budget specified)")
|
244
280
|
|
281
|
+
# Configure CloudSQL if requested
|
282
|
+
# CloudSQL functionality available with Netra Apex
|
283
|
+
# Token metrics are now handled locally without database persistence
|
284
|
+
if use_cloud_sql:
|
285
|
+
logger.warning("CloudSQL functionality has been disabled. Token metrics will be displayed locally only.")
|
286
|
+
logger.info("For data persistence, consider upgrading to Netra Apex.")
|
245
287
|
|
246
288
|
def log_at_level(self, level: LogLevel, message: str, log_func=None):
|
247
289
|
"""Log message only if current log level permits."""
|
@@ -257,10 +299,17 @@ class ClaudeInstanceOrchestrator:
|
|
257
299
|
|
258
300
|
def add_instance(self, config: InstanceConfig):
|
259
301
|
"""Add a new instance configuration"""
|
260
|
-
#
|
261
|
-
|
262
|
-
|
263
|
-
|
302
|
+
# Determine if this is a slash command or raw prompt
|
303
|
+
is_slash_command = config.command and config.command.startswith('/')
|
304
|
+
is_raw_prompt = config.prompt and not is_slash_command
|
305
|
+
|
306
|
+
if is_slash_command:
|
307
|
+
# Validate slash command exists
|
308
|
+
if not self.validate_command(config.command):
|
309
|
+
logger.warning(f"Command '{config.command}' not found in available commands")
|
310
|
+
logger.info(f"Available commands: {', '.join(self.discover_available_commands())}")
|
311
|
+
elif is_raw_prompt:
|
312
|
+
logger.info(f"Using raw prompt: {config.prompt[:50]}{'...' if len(config.prompt) > 50 else ''}")
|
264
313
|
|
265
314
|
self.instances[config.name] = config
|
266
315
|
self.statuses[config.name] = InstanceStatus(name=config.name)
|
@@ -2321,7 +2370,8 @@ async def main():
|
|
2321
2370
|
help="Seconds between rolling status reports (default: 5)")
|
2322
2371
|
parser.add_argument("--start-at", type=str, default=None,
|
2323
2372
|
help="Schedule orchestration to start at specific time. Examples: '2h' (2 hours from now), '30m' (30 minutes), '14:30' (2:30 PM today), '1am' (1 AM today/tomorrow)")
|
2324
|
-
|
2373
|
+
parser.add_argument("--use-cloud-sql", action="store_true",
|
2374
|
+
help="Save metrics to CloudSQL database (NetraOptimizer integration)")
|
2325
2375
|
|
2326
2376
|
# Direct command options
|
2327
2377
|
parser.add_argument("--instance-name", type=str, help="Instance name for direct command execution")
|
@@ -2404,6 +2454,11 @@ async def main():
|
|
2404
2454
|
|
2405
2455
|
logger.info(f"Using workspace: {workspace}")
|
2406
2456
|
|
2457
|
+
# Handle CLI extension commands
|
2458
|
+
if handle_example_commands and handle_example_commands(args):
|
2459
|
+
return
|
2460
|
+
|
2461
|
+
|
2407
2462
|
# Load instance configurations with direct command precedence
|
2408
2463
|
direct_instance = create_direct_instance(args, workspace)
|
2409
2464
|
|
@@ -2492,6 +2547,7 @@ async def main():
|
|
2492
2547
|
startup_delay=args.startup_delay,
|
2493
2548
|
max_line_length=args.max_line_length,
|
2494
2549
|
status_report_interval=args.status_report_interval,
|
2550
|
+
use_cloud_sql=args.use_cloud_sql,
|
2495
2551
|
quiet=args.quiet,
|
2496
2552
|
overall_token_budget=final_overall_budget,
|
2497
2553
|
overall_cost_budget=final_overall_cost_budget,
|
@@ -2719,6 +2775,9 @@ async def main():
|
|
2719
2775
|
|
2720
2776
|
# Run all instances
|
2721
2777
|
logger.info("Starting Claude Code instance orchestration")
|
2778
|
+
if args.use_cloud_sql:
|
2779
|
+
logger.info(f"Batch ID: {orchestrator.batch_id}")
|
2780
|
+
logger.info("Metrics will be saved to CloudSQL")
|
2722
2781
|
start_time = time.time()
|
2723
2782
|
|
2724
2783
|
results = await orchestrator.run_all_instances(args.timeout)
|
@@ -2850,13 +2909,20 @@ async def main():
|
|
2850
2909
|
|
2851
2910
|
# For detailed data access
|
2852
2911
|
print("\n" + "="*80)
|
2853
|
-
print("🚀
|
2912
|
+
print("🚀 NEED DETAILED TOKEN ANALYTICS & DATA ACCESS?")
|
2854
2913
|
print("="*80)
|
2855
|
-
print("
|
2914
|
+
print("For comprehensive token usage analytics, historical data,")
|
2915
|
+
print("and advanced reporting features, upgrade to Netra Apex.")
|
2856
2916
|
print("")
|
2857
2917
|
print("🌐 Learn more: https://netrasystems.ai/")
|
2858
2918
|
print("="*80)
|
2859
2919
|
|
2920
|
+
# Show CloudSQL info if enabled
|
2921
|
+
if args.use_cloud_sql:
|
2922
|
+
print(f"\n📊 Local metrics displayed above")
|
2923
|
+
print(f" Batch ID: {orchestrator.batch_id}")
|
2924
|
+
print(f" Database persistence disabled for security")
|
2925
|
+
|
2860
2926
|
# Exit with appropriate code
|
2861
2927
|
sys.exit(0 if summary['failed'] == 0 else 1)
|
2862
2928
|
|
File without changes
|
File without changes
|
File without changes
|