rcoder 1.0.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.
@@ -0,0 +1,648 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Rcoder 自动优化模块
4
+ 减少人工干预配置,自动根据场景优化连接方式
5
+ """
6
+
7
+ import time
8
+ import asyncio
9
+ import json
10
+ import os
11
+ from typing import Optional, Dict, Any, List, Tuple
12
+ from rcoder.core_optimized import get_remote_host
13
+ from rcoder.async_feedback import get_async_feedback
14
+
15
+ class AutoOptimizer:
16
+ """
17
+ 自动优化器类
18
+ 自动检测网络环境,优化连接方式,减少人工干预
19
+ """
20
+
21
+ def __init__(self, config_file: str = '~/.rcoder/auto_config.json'):
22
+ """
23
+ 初始化自动优化器
24
+
25
+ Args:
26
+ config_file: 配置文件路径
27
+ """
28
+ self.config_file = os.path.expanduser(config_file)
29
+ self.config = self._load_config()
30
+ self._remote_host = None
31
+ self._feedback = None
32
+ self._current_scenario = None
33
+ self._current_strategy = None
34
+ self._network_history = []
35
+ self._scenario_history = []
36
+ self._lock = None
37
+
38
+ def _load_config(self) -> Dict[str, Any]:
39
+ """
40
+ 加载配置文件
41
+ """
42
+ default_config = {
43
+ "scenarios": {
44
+ "low_bandwidth": {
45
+ "description": "低带宽场景",
46
+ "strategies": {
47
+ "enable_compression": True,
48
+ "enable_connection_pool": True,
49
+ "connection_pool_size": 10,
50
+ "timeout": 120,
51
+ "retry_count": 5,
52
+ "retry_delay": 2,
53
+ "batch_size": 3,
54
+ "use_cache": True,
55
+ "cache_expiry": 120,
56
+ "lightweight_monitoring": True
57
+ }
58
+ },
59
+ "very_low_bandwidth": {
60
+ "description": "极低带宽场景",
61
+ "strategies": {
62
+ "enable_compression": True,
63
+ "enable_connection_pool": True,
64
+ "connection_pool_size": 12,
65
+ "timeout": 180,
66
+ "retry_count": 8,
67
+ "retry_delay": 3,
68
+ "batch_size": 1,
69
+ "use_cache": True,
70
+ "cache_expiry": 180,
71
+ "lightweight_monitoring": True,
72
+ "enable_minimal_payload": True
73
+ }
74
+ },
75
+ "high_latency": {
76
+ "description": "高延迟场景",
77
+ "strategies": {
78
+ "enable_compression": True,
79
+ "enable_connection_pool": True,
80
+ "connection_pool_size": 8,
81
+ "timeout": 180,
82
+ "retry_count": 3,
83
+ "retry_delay": 3,
84
+ "batch_size": 2,
85
+ "use_cache": True,
86
+ "cache_expiry": 180,
87
+ "lightweight_monitoring": True
88
+ }
89
+ },
90
+ "very_high_latency": {
91
+ "description": "极高延迟场景",
92
+ "strategies": {
93
+ "enable_compression": True,
94
+ "enable_connection_pool": True,
95
+ "connection_pool_size": 6,
96
+ "timeout": 240,
97
+ "retry_count": 5,
98
+ "retry_delay": 5,
99
+ "batch_size": 1,
100
+ "use_cache": True,
101
+ "cache_expiry": 240,
102
+ "lightweight_monitoring": True
103
+ }
104
+ },
105
+ "unstable_network": {
106
+ "description": "网络不稳定场景",
107
+ "strategies": {
108
+ "enable_compression": True,
109
+ "enable_connection_pool": True,
110
+ "connection_pool_size": 5,
111
+ "timeout": 240,
112
+ "retry_count": 8,
113
+ "retry_delay": 1,
114
+ "batch_size": 1,
115
+ "use_cache": True,
116
+ "cache_expiry": 60,
117
+ "lightweight_monitoring": True,
118
+ "enable_breakpoint_resume": True
119
+ }
120
+ },
121
+ "very_unstable_network": {
122
+ "description": "极不稳定网络场景",
123
+ "strategies": {
124
+ "enable_compression": True,
125
+ "enable_connection_pool": True,
126
+ "connection_pool_size": 3,
127
+ "timeout": 300,
128
+ "retry_count": 10,
129
+ "retry_delay": 2,
130
+ "batch_size": 1,
131
+ "use_cache": True,
132
+ "cache_expiry": 30,
133
+ "lightweight_monitoring": True,
134
+ "enable_breakpoint_resume": True,
135
+ "enable_exponential_backoff": True
136
+ }
137
+ },
138
+ "proxy_transfer": {
139
+ "description": "中转服务器场景",
140
+ "strategies": {
141
+ "enable_compression": True,
142
+ "enable_connection_pool": True,
143
+ "connection_pool_size": 10,
144
+ "timeout": 150,
145
+ "retry_count": 5,
146
+ "retry_delay": 2,
147
+ "batch_size": 4,
148
+ "use_cache": True,
149
+ "cache_expiry": 90,
150
+ "lightweight_monitoring": False
151
+ }
152
+ },
153
+ "local_network": {
154
+ "description": "本地网络场景",
155
+ "strategies": {
156
+ "enable_compression": False,
157
+ "enable_connection_pool": True,
158
+ "connection_pool_size": 5,
159
+ "timeout": 60,
160
+ "retry_count": 2,
161
+ "retry_delay": 1,
162
+ "batch_size": 10,
163
+ "use_cache": True,
164
+ "cache_expiry": 30,
165
+ "lightweight_monitoring": False
166
+ }
167
+ }
168
+ },
169
+ "default_strategy": {
170
+ "enable_compression": True,
171
+ "enable_connection_pool": True,
172
+ "connection_pool_size": 5,
173
+ "timeout": 60,
174
+ "retry_count": 3,
175
+ "retry_delay": 1,
176
+ "batch_size": 5,
177
+ "use_cache": True,
178
+ "cache_expiry": 60,
179
+ "lightweight_monitoring": False
180
+ },
181
+ "network_detection": {
182
+ "interval": 30,
183
+ "history_size": 50,
184
+ "scenario_thresholds": {
185
+ "low_bandwidth": {
186
+ "max_bandwidth": 0.5 # MB/s
187
+ },
188
+ "high_latency": {
189
+ "min_latency": 500 # ms
190
+ },
191
+ "unstable_network": {
192
+ "packet_loss": 0.1 # 10%
193
+ }
194
+ }
195
+ },
196
+ "auto_detection": True,
197
+ "auto_adjust": True,
198
+ "learning_mode": True,
199
+ "log_level": "info"
200
+ }
201
+
202
+ try:
203
+ if os.path.exists(self.config_file):
204
+ with open(self.config_file, 'r', encoding='utf-8') as f:
205
+ config = json.load(f)
206
+ # 合并默认配置
207
+ self._merge_config(default_config, config)
208
+ return default_config
209
+ except Exception as e:
210
+ print(f"警告: 加载配置文件失败: {e}")
211
+
212
+ # 保存默认配置
213
+ self._save_config(default_config)
214
+ return default_config
215
+
216
+ def _merge_config(self, default: Dict[str, Any], user: Dict[str, Any]):
217
+ """
218
+ 合并配置
219
+ """
220
+ for key, value in user.items():
221
+ if key in default and isinstance(default[key], dict) and isinstance(value, dict):
222
+ self._merge_config(default[key], value)
223
+ else:
224
+ default[key] = value
225
+
226
+ def _save_config(self, config: Dict[str, Any]):
227
+ """
228
+ 保存配置文件
229
+ """
230
+ try:
231
+ os.makedirs(os.path.dirname(self.config_file), exist_ok=True)
232
+ with open(self.config_file, 'w', encoding='utf-8') as f:
233
+ json.dump(config, f, indent=2, ensure_ascii=False)
234
+ except Exception as e:
235
+ print(f"警告: 保存配置文件失败: {e}")
236
+
237
+ def _detect_network_scenario(self) -> str:
238
+ """
239
+ 检测网络场景
240
+ """
241
+ if not self._feedback:
242
+ return "unknown"
243
+
244
+ # 获取当前网络状态
245
+ network_status = self._feedback.get_network_status()
246
+
247
+ # 检查历史网络数据
248
+ bandwidth_trend = self._feedback.get_bandwidth_trend()
249
+
250
+ # 分析网络状态
251
+ scenario = "local_network" # 默认场景
252
+
253
+ # 检查低带宽
254
+ if 'bandwidth' in network_status:
255
+ try:
256
+ bandwidth = float(network_status['bandwidth'].split()[0])
257
+ if bandwidth < 0.5:
258
+ scenario = "low_bandwidth"
259
+ elif bandwidth < 0.2:
260
+ scenario = "very_low_bandwidth" # 新增:极低带宽场景
261
+ except:
262
+ pass
263
+
264
+ # 检查高延迟
265
+ if 'latency' in network_status:
266
+ try:
267
+ latency = float(network_status['latency'].split()[0])
268
+ if latency > 500:
269
+ scenario = "high_latency"
270
+ elif latency > 1000:
271
+ scenario = "very_high_latency" # 新增:极高延迟场景
272
+ except:
273
+ pass
274
+
275
+ # 检查网络不稳定
276
+ if len(bandwidth_trend) >= 5:
277
+ # 计算带宽波动
278
+ bandwidths = []
279
+ for entry in bandwidth_trend[-5:]:
280
+ if 'bandwidth' in entry:
281
+ bandwidths.append(entry['bandwidth'])
282
+
283
+ if len(bandwidths) >= 3:
284
+ # 计算标准差
285
+ mean = sum(bandwidths) / len(bandwidths)
286
+ variance = sum((b - mean) ** 2 for b in bandwidths) / len(bandwidths)
287
+ std_dev = variance ** 0.5
288
+
289
+ # 如果带宽波动较大,认为网络不稳定
290
+ if std_dev > mean * 0.3:
291
+ scenario = "unstable_network"
292
+ elif std_dev > mean * 0.5:
293
+ scenario = "very_unstable_network" # 新增:极不稳定网络场景
294
+
295
+ # 检查是否使用中转服务器
296
+ if self._remote_host and hasattr(self._remote_host, 'rcoder'):
297
+ if self._remote_host.rcoder.proxy_server:
298
+ scenario = "proxy_transfer"
299
+
300
+ # 记录场景
301
+ self._scenario_history.append({
302
+ 'timestamp': time.time(),
303
+ 'scenario': scenario,
304
+ 'network_status': network_status
305
+ })
306
+
307
+ # 只保留最近50条记录
308
+ if len(self._scenario_history) > 50:
309
+ self._scenario_history.pop(0)
310
+
311
+ return scenario
312
+
313
+ def _get_strategy(self, scenario: str) -> Dict[str, Any]:
314
+ """
315
+ 获取场景对应的策略
316
+ """
317
+ if scenario in self.config.get('scenarios', {}):
318
+ return self.config['scenarios'][scenario]['strategies']
319
+ return self.config.get('default_strategy', {})
320
+
321
+ def _apply_strategy(self, strategy: Dict[str, Any]):
322
+ """
323
+ 应用策略
324
+ """
325
+ if not self._remote_host or not hasattr(self._remote_host, 'rcoder'):
326
+ return
327
+
328
+ rcoder = self._remote_host.rcoder
329
+
330
+ # 应用策略到rcoder实例
331
+ if hasattr(rcoder, 'enable_compression'):
332
+ rcoder.enable_compression = strategy.get('enable_compression', True)
333
+ if hasattr(rcoder, 'enable_connection_pool'):
334
+ rcoder.enable_connection_pool = strategy.get('enable_connection_pool', True)
335
+ if hasattr(rcoder, 'connection_pool_size'):
336
+ rcoder.connection_pool_size = strategy.get('connection_pool_size', 5)
337
+ if hasattr(rcoder, '_timeout'):
338
+ rcoder._timeout = strategy.get('timeout', 60)
339
+ if hasattr(rcoder, '_retry_delay'):
340
+ rcoder._retry_delay = strategy.get('retry_delay', 1)
341
+ if hasattr(rcoder, '_cache_expiry'):
342
+ rcoder._cache_expiry = strategy.get('cache_expiry', 60)
343
+
344
+ # 应用新策略参数
345
+ if hasattr(rcoder, 'enable_minimal_payload'):
346
+ rcoder.enable_minimal_payload = strategy.get('enable_minimal_payload', False)
347
+ if hasattr(rcoder, 'enable_exponential_backoff'):
348
+ rcoder.enable_exponential_backoff = strategy.get('enable_exponential_backoff', False)
349
+ if hasattr(rcoder, 'enable_breakpoint_resume'):
350
+ rcoder.enable_breakpoint_resume = strategy.get('enable_breakpoint_resume', False)
351
+
352
+ async def _monitor_and_adjust(self):
353
+ """
354
+ 监控并自动调整策略
355
+ """
356
+ while True:
357
+ try:
358
+ # 检测网络场景
359
+ scenario = self._detect_network_scenario()
360
+
361
+ # 如果场景变化,应用新策略
362
+ if scenario != self._current_scenario:
363
+ self._current_scenario = scenario
364
+ strategy = self._get_strategy(scenario)
365
+ self._current_strategy = strategy
366
+
367
+ # 应用策略
368
+ self._apply_strategy(strategy)
369
+
370
+ # 记录调整
371
+ print(f"📊 网络场景变化: {scenario}")
372
+ print(f"🔧 应用新策略: {strategy}")
373
+
374
+ # 保存配置
375
+ self._save_config(self.config)
376
+ except Exception as e:
377
+ print(f"⚠️ 监控调整失败: {e}")
378
+
379
+ # 等待下一次检测
380
+ await asyncio.sleep(self.config.get('network_detection', {}).get('interval', 30))
381
+
382
+ def get_remote_host(self, host: str, port: int = 443,
383
+ proxy_server: Optional[Tuple[str, int]] = None,
384
+ password: Optional[str] = None) -> Any:
385
+ """
386
+ 获取远程主机实例,自动应用优化策略
387
+
388
+ Args:
389
+ host: 服务器主机
390
+ port: 服务器端口
391
+ proxy_server: 中转服务器
392
+ password: 认证密码
393
+ """
394
+ # 检测初始场景
395
+ temp_remote = get_remote_host(
396
+ host=host,
397
+ port=port,
398
+ proxy_server=proxy_server,
399
+ enable_compression=True,
400
+ enable_connection_pool=True,
401
+ password=password
402
+ )
403
+
404
+ # 获取初始网络状态
405
+ temp_feedback = get_async_feedback(temp_remote)
406
+ temp_feedback.start_network_monitor()
407
+
408
+ # 等待网络检测
409
+ time.sleep(3)
410
+
411
+ # 检测场景
412
+ scenario = self._detect_network_scenario()
413
+ strategy = self._get_strategy(scenario)
414
+
415
+ # 停止临时监控
416
+ temp_feedback.stop_network_monitor()
417
+ temp_feedback.shutdown()
418
+
419
+ # 使用检测到的策略创建最终的远程主机
420
+ self._remote_host = get_remote_host(
421
+ host=host,
422
+ port=port,
423
+ proxy_server=proxy_server,
424
+ enable_compression=strategy.get('enable_compression', True),
425
+ enable_connection_pool=strategy.get('enable_connection_pool', True),
426
+ password=password
427
+ )
428
+
429
+ # 获取反馈实例
430
+ self._feedback = get_async_feedback(self._remote_host)
431
+
432
+ # 应用完整策略
433
+ self._current_scenario = scenario
434
+ self._current_strategy = strategy
435
+ self._apply_strategy(strategy)
436
+
437
+ # 启动网络监控
438
+ self._feedback.start_network_monitor()
439
+
440
+ # 启动自动调整
441
+ import threading
442
+ self._lock = threading.Lock()
443
+
444
+ def monitor_thread():
445
+ loop = asyncio.new_event_loop()
446
+ asyncio.set_event_loop(loop)
447
+ loop.run_until_complete(self._monitor_and_adjust())
448
+
449
+ monitor = threading.Thread(target=monitor_thread, daemon=True)
450
+ monitor.start()
451
+
452
+ print(f"✅ 自动优化器初始化完成")
453
+ print(f"📊 检测到场景: {scenario}")
454
+ print(f"🔧 应用策略: {strategy}")
455
+
456
+ return self._remote_host
457
+
458
+ def get_feedback(self):
459
+ """
460
+ 获取异步反馈实例
461
+ """
462
+ return self._feedback
463
+
464
+ def get_current_scenario(self) -> Optional[str]:
465
+ """
466
+ 获取当前场景
467
+ """
468
+ return self._current_scenario
469
+
470
+ def get_current_strategy(self) -> Optional[Dict[str, Any]]:
471
+ """
472
+ 获取当前策略
473
+ """
474
+ return self._current_strategy
475
+
476
+ def get_network_history(self) -> List[Dict[str, Any]]:
477
+ """
478
+ 获取网络历史
479
+ """
480
+ return self._network_history
481
+
482
+ def get_scenario_history(self) -> List[Dict[str, Any]]:
483
+ """
484
+ 获取场景历史
485
+ """
486
+ return self._scenario_history
487
+
488
+ def add_custom_scenario(self, name: str, description: str, strategies: Dict[str, Any]):
489
+ """
490
+ 添加自定义场景
491
+
492
+ Args:
493
+ name: 场景名称
494
+ description: 场景描述
495
+ strategies: 场景策略
496
+ """
497
+ self.config['scenarios'][name] = {
498
+ 'description': description,
499
+ 'strategies': strategies
500
+ }
501
+ self._save_config(self.config)
502
+ print(f"✅ 自定义场景 '{name}' 添加成功")
503
+
504
+ def update_scenario(self, name: str, strategies: Dict[str, Any]):
505
+ """
506
+ 更新场景策略
507
+
508
+ Args:
509
+ name: 场景名称
510
+ strategies: 新的策略
511
+ """
512
+ if name in self.config.get('scenarios', {}):
513
+ self.config['scenarios'][name]['strategies'].update(strategies)
514
+ self._save_config(self.config)
515
+ print(f"✅ 场景 '{name}' 策略更新成功")
516
+ else:
517
+ print(f"❌ 场景 '{name}' 不存在")
518
+
519
+ def export_config(self, output_file: str):
520
+ """
521
+ 导出配置
522
+
523
+ Args:
524
+ output_file: 输出文件路径
525
+ """
526
+ self._save_config(self.config)
527
+ import shutil
528
+ shutil.copy2(self.config_file, output_file)
529
+ print(f"✅ 配置已导出到: {output_file}")
530
+
531
+ def import_config(self, input_file: str):
532
+ """
533
+ 导入配置
534
+
535
+ Args:
536
+ input_file: 输入文件路径
537
+ """
538
+ try:
539
+ with open(input_file, 'r', encoding='utf-8') as f:
540
+ imported_config = json.load(f)
541
+
542
+ self.config.update(imported_config)
543
+ self._save_config(self.config)
544
+ print(f"✅ 配置已从: {input_file} 导入")
545
+ except Exception as e:
546
+ print(f"❌ 导入配置失败: {e}")
547
+
548
+ def shutdown(self):
549
+ """
550
+ 关闭自动优化器
551
+ """
552
+ if self._feedback:
553
+ self._feedback.stop_network_monitor()
554
+ self._feedback.shutdown()
555
+ print("✅ 自动优化器已关闭")
556
+
557
+
558
+ def get_auto_optimizer(config_file: str = '~/.rcoder/auto_config.json') -> AutoOptimizer:
559
+ """
560
+ 获取自动优化器实例
561
+
562
+ Args:
563
+ config_file: 配置文件路径
564
+ """
565
+ return AutoOptimizer(config_file)
566
+
567
+
568
+ # 示例代码
569
+ if __name__ == "__main__":
570
+ print("=== Rcoder 自动优化器示例 ===")
571
+
572
+ # 创建自动优化器
573
+ optimizer = get_auto_optimizer()
574
+
575
+ # 获取远程主机实例(自动优化)
576
+ print("1. 获取远程主机实例(自动优化)")
577
+ remote = optimizer.get_remote_host(
578
+ host='192.168.1.8',
579
+ port=443
580
+ # proxy_server=('1.2.3.4', 443) # 可选:中转服务器
581
+ )
582
+ print()
583
+
584
+ # 获取反馈实例
585
+ feedback = optimizer.get_feedback()
586
+
587
+ # 等待策略应用
588
+ print("2. 等待策略应用...")
589
+ time.sleep(2)
590
+
591
+ # 查看当前场景和策略
592
+ print("3. 当前场景和策略")
593
+ print(f" 当前场景: {optimizer.get_current_scenario()}")
594
+ print(f" 当前策略: {optimizer.get_current_strategy()}")
595
+ print()
596
+
597
+ # 示例:执行命令
598
+ print("4. 执行测试命令")
599
+ try:
600
+ result = remote.run("echo '测试命令执行' && sleep 2 && echo '命令执行完成'")
601
+ print(f" 命令执行结果: {result}")
602
+ except Exception as e:
603
+ print(f" 命令执行失败: {e}")
604
+ print()
605
+
606
+ # 查看网络状态
607
+ print("5. 查看当前网络状态")
608
+ network_status = feedback.get_network_status()
609
+ print(f" 状态: {network_status['status']}")
610
+ print(f" 延迟: {network_status['latency']}")
611
+ print(f" 带宽: {network_status['bandwidth']}")
612
+ print()
613
+
614
+ # 查看场景历史
615
+ print("6. 查看场景历史")
616
+ scenario_history = optimizer.get_scenario_history()
617
+ if scenario_history:
618
+ print(f" 最近场景: {[h['scenario'] for h in scenario_history[-5:]]}")
619
+ else:
620
+ print(" 暂无场景历史")
621
+ print()
622
+
623
+ # 导出配置
624
+ print("7. 导出配置")
625
+ export_file = 'auto_config_export.json'
626
+ optimizer.export_config(export_file)
627
+ print()
628
+
629
+ # 关闭自动优化器
630
+ print("8. 关闭自动优化器")
631
+ optimizer.shutdown()
632
+ print()
633
+
634
+ print("=== 示例完成 ===")
635
+ print("✅ 自动优化器功能演示完成")
636
+ print()
637
+ print("关键特性:")
638
+ print("1. 自动场景检测: 低带宽、高延迟、网络不稳定、中转服务器")
639
+ print("2. 智能策略应用: 根据场景自动调整参数")
640
+ print("3. 实时监控调整: 动态适应网络变化")
641
+ print("4. 配置管理: 导入导出配置,支持自定义场景")
642
+ print("5. 历史记录: 场景和网络状态历史")
643
+ print()
644
+ print("使用方法:")
645
+ print("1. 创建自动优化器: optimizer = get_auto_optimizer()")
646
+ print("2. 获取远程主机: remote = optimizer.get_remote_host(host='服务器地址')")
647
+ print("3. 开始使用: result = remote.run('命令')")
648
+ print("4. 自动优化器会在后台自动调整策略")