cct-cli 0.7.9.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.
Files changed (325) hide show
  1. calc_terminal/__init__.py +14 -0
  2. calc_terminal/__main__.py +14 -0
  3. calc_terminal/activity.py +1334 -0
  4. calc_terminal/agent.py +3387 -0
  5. calc_terminal/agent_runtime.py +519 -0
  6. calc_terminal/ai_context.py +447 -0
  7. calc_terminal/ai_modes.py +752 -0
  8. calc_terminal/ai_personalization.py +286 -0
  9. calc_terminal/ai_preview_feedback.py +213 -0
  10. calc_terminal/aicore.py +2572 -0
  11. calc_terminal/anim.py +367 -0
  12. calc_terminal/app.py +3685 -0
  13. calc_terminal/art.py +639 -0
  14. calc_terminal/atomsim.py +368 -0
  15. calc_terminal/attachments.py +743 -0
  16. calc_terminal/benchmark_system.py +414 -0
  17. calc_terminal/browser/__init__.py +36 -0
  18. calc_terminal/browser/browser_state.py +346 -0
  19. calc_terminal/browser/devserver.py +176 -0
  20. calc_terminal/browser/engine.py +494 -0
  21. calc_terminal/browser/navigation.py +84 -0
  22. calc_terminal/browser/preview.py +429 -0
  23. calc_terminal/browser/preview_entry.py +95 -0
  24. calc_terminal/browser/project_detector.py +144 -0
  25. calc_terminal/browser/server.py +449 -0
  26. calc_terminal/browser/state.py +75 -0
  27. calc_terminal/browser/watcher.py +99 -0
  28. calc_terminal/browser_gui/__init__.py +1 -0
  29. calc_terminal/browser_gui/__main__.py +3 -0
  30. calc_terminal/browser_gui/launcher.py +173 -0
  31. calc_terminal/browser_gui/playwright_browser.py +117 -0
  32. calc_terminal/browser_gui/qt_browser.py +1501 -0
  33. calc_terminal/browser_gui/webview_browser.py +57 -0
  34. calc_terminal/capabilities/__init__.py +35 -0
  35. calc_terminal/capabilities/adapters/__init__.py +33 -0
  36. calc_terminal/capabilities/adapters/bioinformatics.py +204 -0
  37. calc_terminal/capabilities/adapters/browser_adapter.py +205 -0
  38. calc_terminal/capabilities/adapters/filesystem.py +206 -0
  39. calc_terminal/capabilities/adapters/git_adapter.py +202 -0
  40. calc_terminal/capabilities/adapters/jupyter_adapter.py +138 -0
  41. calc_terminal/capabilities/adapters/ml_frameworks.py +158 -0
  42. calc_terminal/capabilities/adapters/platforms.py +200 -0
  43. calc_terminal/capabilities/adapters/python_exec.py +93 -0
  44. calc_terminal/capabilities/adapters/quantum_adapter.py +150 -0
  45. calc_terminal/capabilities/adapters/scientific_comp.py +123 -0
  46. calc_terminal/capabilities/adapters/structural_bio.py +161 -0
  47. calc_terminal/capabilities/adapters/terminal.py +99 -0
  48. calc_terminal/capabilities/bus.py +178 -0
  49. calc_terminal/capabilities/discovery.py +207 -0
  50. calc_terminal/capabilities/schema.py +221 -0
  51. calc_terminal/cat.ico +0 -0
  52. calc_terminal/cat_browser.py +2018 -0
  53. calc_terminal/chat_store.py +703 -0
  54. calc_terminal/cli.py +1178 -0
  55. calc_terminal/code_editor.py +640 -0
  56. calc_terminal/collaboration.py +723 -0
  57. calc_terminal/commands_data.py +139 -0
  58. calc_terminal/compatibility_engine.py +352 -0
  59. calc_terminal/compute/__init__.py +31 -0
  60. calc_terminal/compute/fabric.py +350 -0
  61. calc_terminal/config.py +227 -0
  62. calc_terminal/core/__init__.py +41 -0
  63. calc_terminal/core/checkpoint.py +156 -0
  64. calc_terminal/core/input/__init__.py +45 -0
  65. calc_terminal/core/mode_registry.py +300 -0
  66. calc_terminal/core/project_graph.py +172 -0
  67. calc_terminal/core/recovery.py +129 -0
  68. calc_terminal/core/security_layer.py +112 -0
  69. calc_terminal/core/task_graph.py +202 -0
  70. calc_terminal/core/unified_runtime.py +184 -0
  71. calc_terminal/core/verification.py +257 -0
  72. calc_terminal/customization.py +1566 -0
  73. calc_terminal/derivations.py +153 -0
  74. calc_terminal/device_control.py +263 -0
  75. calc_terminal/diagnostics/__init__.py +27 -0
  76. calc_terminal/diagnostics/doctor_engine.py +382 -0
  77. calc_terminal/diagnostics/self_test.py +247 -0
  78. calc_terminal/doctor.py +519 -0
  79. calc_terminal/easter_eggs.py +274 -0
  80. calc_terminal/editor/__init__.py +1 -0
  81. calc_terminal/editor/actions.py +263 -0
  82. calc_terminal/editor/commands.py +160 -0
  83. calc_terminal/editor/shortcuts.py +226 -0
  84. calc_terminal/engine.py +259 -0
  85. calc_terminal/errors.py +120 -0
  86. calc_terminal/event_stream.py +146 -0
  87. calc_terminal/eventbus.py +133 -0
  88. calc_terminal/extensions.py +733 -0
  89. calc_terminal/fallback_cli.py +1321 -0
  90. calc_terminal/first_run.py +265 -0
  91. calc_terminal/fomoji_auth.py +1043 -0
  92. calc_terminal/formulas.py +82 -0
  93. calc_terminal/fs_cache.py +121 -0
  94. calc_terminal/fs_watcher.py +277 -0
  95. calc_terminal/game.py +193 -0
  96. calc_terminal/gen1.py +5 -0
  97. calc_terminal/generators.py +245 -0
  98. calc_terminal/gestures/__init__.py +42 -0
  99. calc_terminal/gestures/bindings.py +175 -0
  100. calc_terminal/gestures/manager.py +477 -0
  101. calc_terminal/goodbye.py +363 -0
  102. calc_terminal/gpu3d.py +290 -0
  103. calc_terminal/graphs.py +358 -0
  104. calc_terminal/hardware_analyzer.py +440 -0
  105. calc_terminal/host/__init__.py +30 -0
  106. calc_terminal/host/browser_manager.py +187 -0
  107. calc_terminal/host/desktop.py +1386 -0
  108. calc_terminal/host/launcher.py +395 -0
  109. calc_terminal/host/terminal.py +279 -0
  110. calc_terminal/identity.py +216 -0
  111. calc_terminal/input/__init__.py +54 -0
  112. calc_terminal/input/capabilities.py +258 -0
  113. calc_terminal/input/focus.py +87 -0
  114. calc_terminal/input/gestures.py +64 -0
  115. calc_terminal/input/pointer.py +114 -0
  116. calc_terminal/input/touch.py +345 -0
  117. calc_terminal/keys.py +84 -0
  118. calc_terminal/live_automation.py +165 -0
  119. calc_terminal/mathtext.py +433 -0
  120. calc_terminal/mcp.py +386 -0
  121. calc_terminal/memory.py +337 -0
  122. calc_terminal/memory_v2.py +479 -0
  123. calc_terminal/metrics.py +333 -0
  124. calc_terminal/mode_detection.py +146 -0
  125. calc_terminal/model.py +2431 -0
  126. calc_terminal/model_router.py +665 -0
  127. calc_terminal/models/__init__.py +0 -0
  128. calc_terminal/models/active_state.py +187 -0
  129. calc_terminal/models/dynamic_registry.py +584 -0
  130. calc_terminal/models/manager.py +781 -0
  131. calc_terminal/models/model_metadata.json +3526 -0
  132. calc_terminal/models/profiles.py +194 -0
  133. calc_terminal/models/registry.py +265 -0
  134. calc_terminal/models/schema.py +197 -0
  135. calc_terminal/models/validator.py +287 -0
  136. calc_terminal/models/verification_engine.py +368 -0
  137. calc_terminal/native_picker.py +215 -0
  138. calc_terminal/ollama_catalog.py +279 -0
  139. calc_terminal/ollama_download.py +233 -0
  140. calc_terminal/orchestrator.py +304 -0
  141. calc_terminal/package_research.py +322 -0
  142. calc_terminal/packages.py +1024 -0
  143. calc_terminal/pc_specs.py +116 -0
  144. calc_terminal/permissions.py +334 -0
  145. calc_terminal/pet.py +106 -0
  146. calc_terminal/pipeline.py +505 -0
  147. calc_terminal/platform/__init__.py +491 -0
  148. calc_terminal/platform/desktop.py +491 -0
  149. calc_terminal/platform/web.py +781 -0
  150. calc_terminal/preview/__init__.py +1 -0
  151. calc_terminal/preview/dev_server.py +303 -0
  152. calc_terminal/preview/diagnostics.py +131 -0
  153. calc_terminal/preview/live_reload.py +66 -0
  154. calc_terminal/preview/manager.py +129 -0
  155. calc_terminal/project_stats.py +209 -0
  156. calc_terminal/projects.py +328 -0
  157. calc_terminal/providers/__init__.py +0 -0
  158. calc_terminal/providers/adapters/__init__.py +80 -0
  159. calc_terminal/providers/adapters/anthropic_adapter.py +127 -0
  160. calc_terminal/providers/adapters/base.py +106 -0
  161. calc_terminal/providers/adapters/chinese_adapters.py +420 -0
  162. calc_terminal/providers/adapters/gemini_adapter.py +101 -0
  163. calc_terminal/providers/adapters/ollama_adapter.py +83 -0
  164. calc_terminal/providers/adapters/openai_adapter.py +159 -0
  165. calc_terminal/providers/adapters/other_adapters.py +246 -0
  166. calc_terminal/providers/anthropic_provider.py +172 -0
  167. calc_terminal/providers/auto_update.py +416 -0
  168. calc_terminal/providers/base_provider.py +105 -0
  169. calc_terminal/providers/discovery_manager.py +207 -0
  170. calc_terminal/providers/gemini_provider.py +178 -0
  171. calc_terminal/providers/lifecycle.py +767 -0
  172. calc_terminal/providers/ollama_adapter.py +707 -0
  173. calc_terminal/providers/openai_provider.py +254 -0
  174. calc_terminal/providers/provider_manager.py +1827 -0
  175. calc_terminal/providers/providers.json +4075 -0
  176. calc_terminal/reactionsim.py +279 -0
  177. calc_terminal/registry.py +337 -0
  178. calc_terminal/report.py +162 -0
  179. calc_terminal/research/__init__.py +45 -0
  180. calc_terminal/research/artifact_intel.py +126 -0
  181. calc_terminal/research/data_lineage.py +123 -0
  182. calc_terminal/research/experiment_ledger.py +303 -0
  183. calc_terminal/research/reproducibility.py +131 -0
  184. calc_terminal/resilience/__init__.py +47 -0
  185. calc_terminal/resilience/agent_state.py +121 -0
  186. calc_terminal/resilience/capability_matcher.py +174 -0
  187. calc_terminal/resilience/circuit_breaker.py +158 -0
  188. calc_terminal/resilience/failover_engine.py +230 -0
  189. calc_terminal/resilience/health_monitor.py +192 -0
  190. calc_terminal/resilience/ollama_adapter.py +125 -0
  191. calc_terminal/resilience/orchestrator.py +312 -0
  192. calc_terminal/resilience/types.py +134 -0
  193. calc_terminal/sandbox.py +98 -0
  194. calc_terminal/scires.py +558 -0
  195. calc_terminal/security_scanner.py +126 -0
  196. calc_terminal/session.py +294 -0
  197. calc_terminal/sim3d.py +206 -0
  198. calc_terminal/solver.py +276 -0
  199. calc_terminal/sound.py +127 -0
  200. calc_terminal/task_reports.py +287 -0
  201. calc_terminal/terminal_host.py +201 -0
  202. calc_terminal/terminal_identity.py +411 -0
  203. calc_terminal/test_ai_mode_reliability.py +344 -0
  204. calc_terminal/test_browser.py +368 -0
  205. calc_terminal/test_code_editor_upgrade.py +485 -0
  206. calc_terminal/test_customization.py +1148 -0
  207. calc_terminal/test_customization_ui.py +612 -0
  208. calc_terminal/test_dynamic_registry.py +304 -0
  209. calc_terminal/test_extensions.py +436 -0
  210. calc_terminal/test_overhaul.py +557 -0
  211. calc_terminal/test_project_detect.py +255 -0
  212. calc_terminal/test_root_cause_fix.py +527 -0
  213. calc_terminal/test_stability.py +532 -0
  214. calc_terminal/test_terminal_identity.py +132 -0
  215. calc_terminal/test_v079_speed.py +460 -0
  216. calc_terminal/theme.py +1107 -0
  217. calc_terminal/timeline.py +139 -0
  218. calc_terminal/todos.py +246 -0
  219. calc_terminal/tool_call_normalizer.py +419 -0
  220. calc_terminal/tui.py +104 -0
  221. calc_terminal/ui/__init__.py +8 -0
  222. calc_terminal/ui/activity_panel.py +231 -0
  223. calc_terminal/ui/activity_stream_panel.py +238 -0
  224. calc_terminal/ui/animations.py +122 -0
  225. calc_terminal/ui/app.py +7271 -0
  226. calc_terminal/ui/attach_panel.py +597 -0
  227. calc_terminal/ui/attachments.py +424 -0
  228. calc_terminal/ui/backup_panel.py +810 -0
  229. calc_terminal/ui/browser_shell.py +887 -0
  230. calc_terminal/ui/cat_agent.py +357 -0
  231. calc_terminal/ui/chats_panel.py +899 -0
  232. calc_terminal/ui/command_palette.py +125 -0
  233. calc_terminal/ui/command_palette_modal.py +166 -0
  234. calc_terminal/ui/composer.py +1141 -0
  235. calc_terminal/ui/context_menu.py +197 -0
  236. calc_terminal/ui/conversation.py +1435 -0
  237. calc_terminal/ui/customization_panel.py +1229 -0
  238. calc_terminal/ui/dashboard.py +404 -0
  239. calc_terminal/ui/design_system.py +557 -0
  240. calc_terminal/ui/diff_panel.py +213 -0
  241. calc_terminal/ui/editor.py +2102 -0
  242. calc_terminal/ui/empty_state.py +302 -0
  243. calc_terminal/ui/events.py +487 -0
  244. calc_terminal/ui/extensions_panel.py +815 -0
  245. calc_terminal/ui/footer.py +166 -0
  246. calc_terminal/ui/gestures_panel.py +383 -0
  247. calc_terminal/ui/goodbye_screen.py +100 -0
  248. calc_terminal/ui/header.py +1034 -0
  249. calc_terminal/ui/help_panel.py +254 -0
  250. calc_terminal/ui/live_activities.py +914 -0
  251. calc_terminal/ui/mcp_panel.py +570 -0
  252. calc_terminal/ui/memory_center.py +524 -0
  253. calc_terminal/ui/mode_colors_panel.py +525 -0
  254. calc_terminal/ui/nav_screens.py +747 -0
  255. calc_terminal/ui/ollama_panel.py +536 -0
  256. calc_terminal/ui/palette.py +221 -0
  257. calc_terminal/ui/permission_panel.py +269 -0
  258. calc_terminal/ui/personalization_panel.py +517 -0
  259. calc_terminal/ui/personalize_center.py +1568 -0
  260. calc_terminal/ui/preview_panel.py +441 -0
  261. calc_terminal/ui/resizers.py +402 -0
  262. calc_terminal/ui/sidebar.py +1285 -0
  263. calc_terminal/ui/statusbar.py +168 -0
  264. calc_terminal/ui/theme_css.py +1396 -0
  265. calc_terminal/ui/thinking.py +226 -0
  266. calc_terminal/ui/timeline_panel.py +102 -0
  267. calc_terminal/ui/todo_panel.py +193 -0
  268. calc_terminal/ui/viewport.py +136 -0
  269. calc_terminal/ui/vision_panel.py +489 -0
  270. calc_terminal/ui/welcome_modal.py +343 -0
  271. calc_terminal/ui/widgets.py +160 -0
  272. calc_terminal/ui/workspace.py +831 -0
  273. calc_terminal/viewers/__init__.py +1 -0
  274. calc_terminal/viewers/document_viewer.py +252 -0
  275. calc_terminal/viewers/image_viewer.py +241 -0
  276. calc_terminal/viewers/pdf_viewer.py +203 -0
  277. calc_terminal/viewers/presentation_viewer.py +164 -0
  278. calc_terminal/viewers/registry.py +120 -0
  279. calc_terminal/viewers/spreadsheet_viewer.py +204 -0
  280. calc_terminal/vision/__init__.py +89 -0
  281. calc_terminal/vision/analysis.py +194 -0
  282. calc_terminal/vision/annotations.py +297 -0
  283. calc_terminal/vision/capture.py +171 -0
  284. calc_terminal/vision/context.py +231 -0
  285. calc_terminal/vision/correlation.py +169 -0
  286. calc_terminal/vision/cursor.py +258 -0
  287. calc_terminal/vision/events.py +66 -0
  288. calc_terminal/vision/frame_pipeline.py +259 -0
  289. calc_terminal/vision/priority.py +218 -0
  290. calc_terminal/vision/provider.py +180 -0
  291. calc_terminal/vision/safety.py +149 -0
  292. calc_terminal/vision/session.py +281 -0
  293. calc_terminal/vision/verify.py +162 -0
  294. calc_terminal/vision.py +514 -0
  295. calc_terminal/vscode_integration.py +113 -0
  296. calc_terminal/web/__init__.py +8 -0
  297. calc_terminal/web/cat_runtime.py +710 -0
  298. calc_terminal/web/server.py +2891 -0
  299. calc_terminal/web/static/css/app.css +3152 -0
  300. calc_terminal/web/static/icons/badge-72.png +0 -0
  301. calc_terminal/web/static/icons/cat.ico +0 -0
  302. calc_terminal/web/static/icons/icon-128.png +0 -0
  303. calc_terminal/web/static/icons/icon-144.png +0 -0
  304. calc_terminal/web/static/icons/icon-152.png +0 -0
  305. calc_terminal/web/static/icons/icon-192.png +0 -0
  306. calc_terminal/web/static/icons/icon-384.png +0 -0
  307. calc_terminal/web/static/icons/icon-512.png +0 -0
  308. calc_terminal/web/static/icons/icon-72.png +0 -0
  309. calc_terminal/web/static/icons/icon-96.png +0 -0
  310. calc_terminal/web/static/icons/icon.svg +34 -0
  311. calc_terminal/web/static/icons/new-project.png +0 -0
  312. calc_terminal/web/static/icons/open-project.png +0 -0
  313. calc_terminal/web/static/index.html +734 -0
  314. calc_terminal/web/static/js/app.js +2403 -0
  315. calc_terminal/web/static/manifest.json +88 -0
  316. calc_terminal/web/static/sw.js +230 -0
  317. calc_terminal/workflow_engine.py +769 -0
  318. calc_terminal/workspace.py +593 -0
  319. calc_terminal/workspace_index.py +385 -0
  320. cct_cli-0.7.9.0.dist-info/METADATA +210 -0
  321. cct_cli-0.7.9.0.dist-info/RECORD +325 -0
  322. cct_cli-0.7.9.0.dist-info/WHEEL +5 -0
  323. cct_cli-0.7.9.0.dist-info/entry_points.txt +4 -0
  324. cct_cli-0.7.9.0.dist-info/licenses/LICENSE +21 -0
  325. cct_cli-0.7.9.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,127 @@
1
+ """
2
+ calc_terminal/providers/adapters/anthropic_adapter.py
3
+ ====================================================
4
+ Anthropic Claude Provider Adapter with live discovery and Claude 4 support.
5
+ """
6
+
7
+ import requests
8
+ from typing import List
9
+
10
+ from .base import BaseProviderAdapter
11
+ from ...models.schema import ModelInfo
12
+ from ...models.validator import ModelValidator
13
+
14
+
15
+ class AnthropicAdapter(BaseProviderAdapter):
16
+ provider_id = "anthropic"
17
+ display_name = "Anthropic (Claude)"
18
+ company = "Anthropic"
19
+ region = "US"
20
+ api_base = "https://api.anthropic.com/v1"
21
+ authentication_type = "header"
22
+ documentation_url = "https://docs.anthropic.com/en/docs/about-claude/models"
23
+
24
+ CATALOG_MODELS = {
25
+ "claude-4-sonnet-20260515": {
26
+ "display_name": "Claude 4 Sonnet",
27
+ "family": "Claude",
28
+ "version": "4",
29
+ "context_window": 500000,
30
+ "max_output_tokens": 32768,
31
+ "capabilities": ["reasoning", "coding", "vision", "tools", "streaming"],
32
+ "pricing": {"input_price_per_1m": 3.0, "output_price_per_1m": 15.0},
33
+ "recommendation_badges": ["Best for Coding"],
34
+ },
35
+ "claude-4-fable-5.1": {
36
+ "display_name": "Claude 4 Fable 5.1",
37
+ "family": "Claude",
38
+ "version": "4",
39
+ "context_window": 500000,
40
+ "max_output_tokens": 64000,
41
+ "capabilities": ["reasoning", "coding", "vision", "tools", "streaming", "long_context"],
42
+ "pricing": {"input_price_per_1m": 4.0, "output_price_per_1m": 16.0},
43
+ "recommendation_badges": ["Best for Research"],
44
+ },
45
+ "claude-sonnet-4": {
46
+ "display_name": "Claude Sonnet 4",
47
+ "family": "Claude",
48
+ "version": "4",
49
+ "context_window": 200000,
50
+ "max_output_tokens": 16384,
51
+ "capabilities": ["reasoning", "coding", "vision", "tools", "streaming"],
52
+ "pricing": {"input_price_per_1m": 3.0, "output_price_per_1m": 15.0},
53
+ "recommendation_badges": ["Best for Coding"],
54
+ },
55
+ "claude-opus-4": {
56
+ "display_name": "Claude Opus 4",
57
+ "family": "Claude",
58
+ "version": "4",
59
+ "context_window": 200000,
60
+ "max_output_tokens": 16384,
61
+ "capabilities": ["reasoning", "coding", "vision", "research", "tools", "streaming"],
62
+ "pricing": {"input_price_per_1m": 15.0, "output_price_per_1m": 75.0},
63
+ "recommendation_badges": ["Best for Reasoning"],
64
+ },
65
+ "claude-3-7-sonnet": {
66
+ "display_name": "Claude 3.7 Sonnet",
67
+ "family": "Claude",
68
+ "version": "3.7",
69
+ "context_window": 200000,
70
+ "max_output_tokens": 8192,
71
+ "capabilities": ["reasoning", "coding", "vision", "tools", "streaming"],
72
+ "pricing": {"input_price_per_1m": 3.0, "output_price_per_1m": 15.0},
73
+ "recommendation_badges": ["Best for Coding"],
74
+ },
75
+ "claude-3-5-sonnet": {
76
+ "display_name": "Claude 3.5 Sonnet",
77
+ "family": "Claude",
78
+ "version": "3.5",
79
+ "context_window": 200000,
80
+ "max_output_tokens": 8192,
81
+ "capabilities": ["coding", "vision", "tools", "streaming"],
82
+ "pricing": {"input_price_per_1m": 3.0, "output_price_per_1m": 15.0},
83
+ },
84
+ "claude-3-5-haiku": {
85
+ "display_name": "Claude 3.5 Haiku",
86
+ "family": "Claude",
87
+ "version": "3.5",
88
+ "context_window": 200000,
89
+ "max_output_tokens": 8192,
90
+ "capabilities": ["coding", "tools", "streaming", "fast"],
91
+ "pricing": {"input_price_per_1m": 0.8, "output_price_per_1m": 4.0},
92
+ "recommendation_badges": ["Best Fast Model"],
93
+ },
94
+ }
95
+
96
+ def discover_models(self, timeout: float = 8.0) -> List[ModelInfo]:
97
+ base = self.get_api_base()
98
+ key = self.get_api_key()
99
+ headers = {"Content-Type": "application/json", "anthropic-version": "2023-06-01"}
100
+ if key:
101
+ headers["x-api-key"] = key
102
+
103
+ discovered_ids = []
104
+ try:
105
+ resp = requests.get(f"{base}/models", headers=headers, timeout=timeout)
106
+ if resp.status_code == 200:
107
+ data = resp.json().get("data", [])
108
+ for item in data:
109
+ mid = str(item.get("id", "")).strip()
110
+ if mid:
111
+ discovered_ids.append(mid)
112
+ except Exception:
113
+ pass
114
+
115
+ for cat_id in self.CATALOG_MODELS:
116
+ if cat_id not in discovered_ids:
117
+ discovered_ids.append(cat_id)
118
+
119
+ results = []
120
+ for mid in discovered_ids:
121
+ meta = dict(self.CATALOG_MODELS.get(mid, {}))
122
+ meta["model_id"] = mid
123
+ meta["endpoint"] = base
124
+ val = ModelValidator.validate_raw(meta, self.provider_id, self.config)
125
+ if val.is_valid and val.model_info:
126
+ results.append(val.model_info)
127
+ return results
@@ -0,0 +1,106 @@
1
+ """
2
+ calc_terminal/providers/adapters/base.py
3
+ ========================================
4
+ Base Provider Adapter Interface for Dynamic Model Discovery.
5
+
6
+ Every provider adapter implements this contract to allow CAT to automatically
7
+ discover, validate, and query AI models directly from official provider APIs.
8
+ """
9
+
10
+ from abc import ABC, abstractmethod
11
+ from typing import Dict, List, Optional, Tuple, Any
12
+
13
+ from ...models.schema import ModelInfo, STATUS_ACTIVE, STATUS_UNAVAILABLE, AVAILABILITY_PAID_API
14
+ from ...models.validator import ModelValidator
15
+
16
+
17
+ class BaseProviderAdapter(ABC):
18
+ """Abstract interface for all CAT provider adapters."""
19
+
20
+ provider_id: str = ""
21
+ display_name: str = ""
22
+ company: str = ""
23
+ region: str = "US"
24
+ api_base: str = ""
25
+ authentication_type: str = "bearer_token" # bearer_token | query_param | none | custom
26
+ documentation_url: str = ""
27
+
28
+ def __init__(self, provider_id_or_config: Any = None, config: Optional[Dict[str, Any]] = None):
29
+ if isinstance(provider_id_or_config, str):
30
+ self.provider_id = provider_id_or_config
31
+ self.config = dict(config or {})
32
+ elif isinstance(provider_id_or_config, dict):
33
+ self.config = dict(provider_id_or_config)
34
+ else:
35
+ self.config = dict(config or {})
36
+
37
+ def get_api_base(self) -> str:
38
+ return (
39
+ self.config.get("base_url")
40
+ or self.config.get("api_url")
41
+ or self.api_base
42
+ ).rstrip("/")
43
+
44
+ def get_api_key(self) -> Optional[str]:
45
+ return self.config.get("api_key")
46
+
47
+ @abstractmethod
48
+ def discover_models(self, timeout: float = 8.0) -> List[ModelInfo]:
49
+ """Fetch and normalize model listings from official provider endpoint."""
50
+ pass
51
+
52
+ def validate_model(self, model_id: str) -> Tuple[bool, str]:
53
+ """Check if model ID is recognized and supported by this adapter."""
54
+ if not model_id or not model_id.strip():
55
+ return False, "Empty model identifier."
56
+ return True, "Valid model ID."
57
+
58
+ def get_model_metadata(self, model_id: str) -> Optional[ModelInfo]:
59
+ """Return curated or default ModelInfo for a specific model ID."""
60
+ res = ModelValidator.validate_raw(model_id, self.provider_id, self.config)
61
+ return res.model_info if res.is_valid else None
62
+
63
+ def get_capabilities(self, model_id: str) -> List[str]:
64
+ meta = self.get_model_metadata(model_id)
65
+ return meta.capabilities if meta else ["chat", "streaming"]
66
+
67
+ def get_limits(self, model_id: str) -> Dict[str, int]:
68
+ meta = self.get_model_metadata(model_id)
69
+ if meta:
70
+ return {"context_window": meta.context_window, "max_output_tokens": meta.max_output_tokens}
71
+ return {"context_window": 128000, "max_output_tokens": 4096}
72
+
73
+ def get_pricing(self, model_id: str) -> Dict[str, float]:
74
+ meta = self.get_model_metadata(model_id)
75
+ return meta.pricing if meta else {"input_price_per_1m": 0.0, "output_price_per_1m": 0.0}
76
+
77
+ def get_availability(self, model_id: str) -> str:
78
+ meta = self.get_model_metadata(model_id)
79
+ return meta.availability if meta else AVAILABILITY_PAID_API
80
+
81
+ def health_check(self, timeout: float = 5.0) -> Dict[str, Any]:
82
+ """Ping provider endpoint to verify connectivity and status."""
83
+ import requests
84
+ base = self.get_api_base()
85
+ if not base:
86
+ return {"status": "unknown", "provider": self.provider_id, "message": "No endpoint configured"}
87
+ try:
88
+ # Most OpenAI-compatible endpoints respond to GET /models or /
89
+ headers = {}
90
+ key = self.get_api_key()
91
+ if key and self.authentication_type == "bearer_token":
92
+ headers["Authorization"] = f"Bearer {key}"
93
+ resp = requests.get(f"{base}/models", headers=headers, timeout=timeout)
94
+ if resp.status_code == 401:
95
+ return {"status": "online", "provider": self.provider_id, "auth_required": True, "code": 401}
96
+ if resp.status_code < 400:
97
+ return {"status": "online", "provider": self.provider_id, "code": resp.status_code}
98
+ if resp.status_code >= 500:
99
+ return {"status": "degraded", "provider": self.provider_id, "code": resp.status_code}
100
+ return {"status": "online", "provider": self.provider_id, "code": resp.status_code}
101
+ except requests.exceptions.Timeout:
102
+ return {"status": "degraded", "provider": self.provider_id, "error": "Timeout"}
103
+ except requests.exceptions.ConnectionError:
104
+ return {"status": "offline", "provider": self.provider_id, "error": "Connection error"}
105
+ except Exception as e:
106
+ return {"status": "unknown", "provider": self.provider_id, "error": str(e)}
@@ -0,0 +1,420 @@
1
+ """
2
+ calc_terminal/providers/adapters/chinese_adapters.py
3
+ ===================================================
4
+ First-Class Adapters for Major Chinese AI Providers:
5
+ - DeepSeek (V3, R1 Reasoner)
6
+ - Alibaba Cloud / Qwen (Max, Plus, Turbo, Coder, QwQ)
7
+ - Moonshot AI (Kimi K3, K2, moonshot-v1)
8
+ - Z.AI / Zhipu (GLM-5.1, GLM-5.2, GLM-5.3, GLM-4)
9
+ - MiniMax (H3, abab6.5s)
10
+ - Tencent (Hunyuan / Hy3)
11
+ - ByteDance (Doubao / Seed)
12
+ - Xiaomi (MiMo)
13
+ - Baidu (ERNIE 4.0 / Qianfan)
14
+ """
15
+
16
+ import requests
17
+ from typing import List, Dict, Any, Optional
18
+
19
+ from .base import BaseProviderAdapter
20
+ from ...models.schema import ModelInfo, AVAILABILITY_PAID_API, AVAILABILITY_OPEN_WEIGHT
21
+ from ...models.validator import ModelValidator
22
+
23
+
24
+ class BaseOpenAICompatibleChineseAdapter(BaseProviderAdapter):
25
+ """Reusable base for OpenAI-compatible Chinese AI endpoints."""
26
+
27
+ catalog: Dict[str, Dict[str, Any]] = {}
28
+
29
+ def discover_models(self, timeout: float = 8.0) -> List[ModelInfo]:
30
+ base = self.get_api_base()
31
+ key = self.get_api_key()
32
+ headers = {"Content-Type": "application/json"}
33
+ if key:
34
+ headers["Authorization"] = f"Bearer {key}"
35
+
36
+ discovered_ids = []
37
+ try:
38
+ resp = requests.get(f"{base}/models", headers=headers, timeout=timeout)
39
+ if resp.status_code == 200:
40
+ data = resp.json().get("data", [])
41
+ for item in data:
42
+ mid = str(item.get("id", "")).strip()
43
+ if mid:
44
+ discovered_ids.append(mid)
45
+ except Exception:
46
+ pass
47
+
48
+ # Ensure catalog models are present
49
+ for cat_id in self.catalog:
50
+ if cat_id not in discovered_ids:
51
+ discovered_ids.append(cat_id)
52
+
53
+ results = []
54
+ for mid in discovered_ids:
55
+ meta = dict(self.catalog.get(mid, {}))
56
+ meta["model_id"] = mid
57
+ meta["endpoint"] = base
58
+ val = ModelValidator.validate_raw(meta, self.provider_id, self.config)
59
+ if val.is_valid and val.model_info:
60
+ results.append(val.model_info)
61
+ return results
62
+
63
+
64
+ class DeepSeekAdapter(BaseOpenAICompatibleChineseAdapter):
65
+ provider_id = "deepseek"
66
+ display_name = "DeepSeek"
67
+ company = "DeepSeek"
68
+ region = "CN"
69
+ api_base = "https://api.deepseek.com/v1"
70
+ authentication_type = "bearer_token"
71
+ documentation_url = "https://platform.deepseek.com/api-docs"
72
+
73
+ catalog = {
74
+ "deepseek-chat": {
75
+ "display_name": "DeepSeek-V3",
76
+ "family": "DeepSeek",
77
+ "version": "V3",
78
+ "context_window": 128000,
79
+ "max_output_tokens": 8192,
80
+ "capabilities": ["chat", "coding", "tools", "streaming", "fast"],
81
+ "pricing": {"input_price_per_1m": 0.14, "output_price_per_1m": 0.28},
82
+ "availability": AVAILABILITY_OPEN_WEIGHT,
83
+ "recommendation_badges": ["Best Budget Model", "Best Fast Model"],
84
+ },
85
+ "deepseek-reasoner": {
86
+ "display_name": "DeepSeek-R1 (Reasoner)",
87
+ "family": "DeepSeek",
88
+ "version": "R1",
89
+ "context_window": 128000,
90
+ "max_output_tokens": 32768,
91
+ "reasoning_levels": ["high"],
92
+ "capabilities": ["reasoning", "coding", "tools", "streaming"],
93
+ "pricing": {"input_price_per_1m": 0.55, "output_price_per_1m": 2.19},
94
+ "availability": AVAILABILITY_OPEN_WEIGHT,
95
+ "recommendation_badges": ["Best for Reasoning", "Best Budget Model"],
96
+ },
97
+ "deepseek-r1": {
98
+ "display_name": "DeepSeek-R1",
99
+ "family": "DeepSeek",
100
+ "version": "R1",
101
+ "context_window": 128000,
102
+ "max_output_tokens": 32768,
103
+ "reasoning_levels": ["high"],
104
+ "capabilities": ["reasoning", "coding", "tools", "streaming"],
105
+ "pricing": {"input_price_per_1m": 0.55, "output_price_per_1m": 2.19},
106
+ "availability": AVAILABILITY_OPEN_WEIGHT,
107
+ "recommendation_badges": ["Best for Reasoning", "Best Budget Model"],
108
+ },
109
+ }
110
+
111
+
112
+ class QwenAdapter(BaseOpenAICompatibleChineseAdapter):
113
+ provider_id = "alibaba"
114
+ display_name = "Alibaba Cloud (Qwen)"
115
+ company = "Alibaba Cloud"
116
+ region = "CN"
117
+ api_base = "https://dashscope.aliyuncs.com/compatible-mode/v1"
118
+ authentication_type = "bearer_token"
119
+ documentation_url = "https://help.aliyun.com/zh/dashscope"
120
+
121
+ catalog = {
122
+ "qwen-max": {
123
+ "display_name": "Qwen Max",
124
+ "family": "Qwen",
125
+ "context_window": 131072,
126
+ "max_output_tokens": 8192,
127
+ "capabilities": ["reasoning", "coding", "vision", "tools", "streaming"],
128
+ "pricing": {"input_price_per_1m": 2.8, "output_price_per_1m": 8.4},
129
+ "recommendation_badges": ["Best for Coding"],
130
+ },
131
+ "qwen-plus": {
132
+ "display_name": "Qwen Plus",
133
+ "family": "Qwen",
134
+ "context_window": 131072,
135
+ "max_output_tokens": 8192,
136
+ "capabilities": ["coding", "tools", "streaming"],
137
+ "pricing": {"input_price_per_1m": 0.4, "output_price_per_1m": 1.2},
138
+ },
139
+ "qwen-turbo": {
140
+ "display_name": "Qwen Turbo",
141
+ "family": "Qwen",
142
+ "context_window": 1000000,
143
+ "max_output_tokens": 8192,
144
+ "capabilities": ["tools", "streaming", "fast", "long_context"],
145
+ "pricing": {"input_price_per_1m": 0.05, "output_price_per_1m": 0.15},
146
+ "recommendation_badges": ["Best Fast Model", "Best Budget Model"],
147
+ },
148
+ "qwen-2.5-coder-32b": {
149
+ "display_name": "Qwen 2.5 Coder 32B",
150
+ "family": "Qwen",
151
+ "context_window": 131072,
152
+ "max_output_tokens": 8192,
153
+ "capabilities": ["coding", "tools", "streaming"],
154
+ "pricing": {"input_price_per_1m": 0.5, "output_price_per_1m": 1.5},
155
+ "availability": AVAILABILITY_OPEN_WEIGHT,
156
+ "recommendation_badges": ["Best for Coding"],
157
+ },
158
+ "qwen-qwq-32b": {
159
+ "display_name": "Qwen QwQ 32B (Reasoning)",
160
+ "family": "Qwen",
161
+ "context_window": 131072,
162
+ "max_output_tokens": 32768,
163
+ "reasoning_levels": ["high"],
164
+ "capabilities": ["reasoning", "coding", "tools", "streaming"],
165
+ "pricing": {"input_price_per_1m": 0.8, "output_price_per_1m": 2.4},
166
+ "availability": AVAILABILITY_OPEN_WEIGHT,
167
+ "recommendation_badges": ["Best for Reasoning"],
168
+ },
169
+ }
170
+
171
+
172
+ class MoonshotAdapter(BaseOpenAICompatibleChineseAdapter):
173
+ provider_id = "moonshot"
174
+ display_name = "Moonshot AI (Kimi)"
175
+ company = "Moonshot AI"
176
+ region = "CN"
177
+ api_base = "https://api.moonshot.cn/v1"
178
+ authentication_type = "bearer_token"
179
+ documentation_url = "https://platform.moonshot.cn/docs"
180
+
181
+ catalog = {
182
+ "kimi-k3": {
183
+ "display_name": "Kimi K3",
184
+ "family": "Kimi",
185
+ "context_window": 256000,
186
+ "max_output_tokens": 16384,
187
+ "capabilities": ["reasoning", "coding", "long_context", "tools", "streaming"],
188
+ "pricing": {"input_price_per_1m": 1.5, "output_price_per_1m": 6.0},
189
+ "recommendation_badges": ["Best for Research"],
190
+ },
191
+ "kimi-k2": {
192
+ "display_name": "Kimi K2",
193
+ "family": "Kimi",
194
+ "context_window": 128000,
195
+ "max_output_tokens": 8192,
196
+ "capabilities": ["coding", "tools", "streaming"],
197
+ "pricing": {"input_price_per_1m": 1.0, "output_price_per_1m": 4.0},
198
+ },
199
+ "moonshot-v1-128k": {
200
+ "display_name": "Moonshot v1 128k",
201
+ "family": "Kimi",
202
+ "context_window": 128000,
203
+ "max_output_tokens": 8192,
204
+ "capabilities": ["long_context", "tools", "streaming"],
205
+ "pricing": {"input_price_per_1m": 1.2, "output_price_per_1m": 4.8},
206
+ },
207
+ }
208
+
209
+
210
+ class ZhipuGLMAdapter(BaseOpenAICompatibleChineseAdapter):
211
+ provider_id = "zhipu"
212
+ display_name = "Zhipu AI (GLM)"
213
+ company = "Zhipu AI / Z.AI"
214
+ region = "CN"
215
+ api_base = "https://open.bigmodel.cn/api/paas/v4"
216
+ authentication_type = "bearer_token"
217
+ documentation_url = "https://open.bigmodel.cn/dev/api"
218
+
219
+ catalog = {
220
+ "glm-5.1": {
221
+ "display_name": "GLM-5.1",
222
+ "family": "GLM",
223
+ "version": "5.1",
224
+ "context_window": 256000,
225
+ "max_output_tokens": 16384,
226
+ "capabilities": ["reasoning", "coding", "tools", "streaming"],
227
+ "pricing": {"input_price_per_1m": 1.5, "output_price_per_1m": 5.0},
228
+ "recommendation_badges": ["Best for Reasoning"],
229
+ },
230
+ "glm-5.2": {
231
+ "display_name": "GLM-5.2",
232
+ "family": "GLM",
233
+ "version": "5.2",
234
+ "context_window": 256000,
235
+ "max_output_tokens": 16384,
236
+ "capabilities": ["reasoning", "coding", "tools", "streaming"],
237
+ "pricing": {"input_price_per_1m": 2.0, "output_price_per_1m": 6.0},
238
+ },
239
+ "glm-5.3": {
240
+ "display_name": "GLM-5.3",
241
+ "family": "GLM",
242
+ "version": "5.3",
243
+ "context_window": 512000,
244
+ "max_output_tokens": 32768,
245
+ "capabilities": ["reasoning", "coding", "vision", "tools", "streaming", "long_context"],
246
+ "pricing": {"input_price_per_1m": 2.5, "output_price_per_1m": 8.0},
247
+ "recommendation_badges": ["Best for Coding", "Best for Research"],
248
+ },
249
+ "glm-4-plus": {
250
+ "display_name": "GLM-4 Plus",
251
+ "family": "GLM",
252
+ "context_window": 128000,
253
+ "max_output_tokens": 8192,
254
+ "capabilities": ["coding", "tools", "streaming"],
255
+ "pricing": {"input_price_per_1m": 1.4, "output_price_per_1m": 4.2},
256
+ },
257
+ "glm-4-air": {
258
+ "display_name": "GLM-4 Air",
259
+ "family": "GLM",
260
+ "context_window": 128000,
261
+ "max_output_tokens": 8192,
262
+ "capabilities": ["tools", "streaming", "fast"],
263
+ "pricing": {"input_price_per_1m": 0.14, "output_price_per_1m": 0.42},
264
+ "recommendation_badges": ["Best Fast Model"],
265
+ },
266
+ }
267
+
268
+
269
+ class MiniMaxAdapter(BaseOpenAICompatibleChineseAdapter):
270
+ provider_id = "minimax"
271
+ display_name = "MiniMax"
272
+ company = "MiniMax"
273
+ region = "CN"
274
+ api_base = "https://api.minimax.chat/v1"
275
+ authentication_type = "bearer_token"
276
+ documentation_url = "https://platform.minimaxi.com"
277
+
278
+ catalog = {
279
+ "h3": {
280
+ "display_name": "MiniMax H3",
281
+ "family": "MiniMax",
282
+ "context_window": 256000,
283
+ "max_output_tokens": 16384,
284
+ "capabilities": ["reasoning", "coding", "tools", "streaming"],
285
+ "pricing": {"input_price_per_1m": 1.0, "output_price_per_1m": 4.0},
286
+ },
287
+ "minimax-text-01": {
288
+ "display_name": "MiniMax Text 01",
289
+ "family": "MiniMax",
290
+ "context_window": 1000000,
291
+ "max_output_tokens": 16384,
292
+ "capabilities": ["long_context", "tools", "streaming"],
293
+ "pricing": {"input_price_per_1m": 0.5, "output_price_per_1m": 2.0},
294
+ },
295
+ "abab6.5s": {
296
+ "display_name": "MiniMax Abab 6.5s",
297
+ "family": "MiniMax",
298
+ "context_window": 256000,
299
+ "max_output_tokens": 8192,
300
+ "capabilities": ["chat", "fast", "tools", "streaming"],
301
+ "pricing": {"input_price_per_1m": 0.2, "output_price_per_1m": 0.8},
302
+ "recommendation_badges": ["Best Fast Model"],
303
+ },
304
+ }
305
+
306
+
307
+ class TencentHunyuanAdapter(BaseOpenAICompatibleChineseAdapter):
308
+ provider_id = "tencent"
309
+ display_name = "Tencent Hunyuan"
310
+ company = "Tencent"
311
+ region = "CN"
312
+ api_base = "https://api.hunyuan.cloud.tencent.com/v1"
313
+ authentication_type = "bearer_token"
314
+ documentation_url = "https://cloud.tencent.com/document/product/1729"
315
+
316
+ catalog = {
317
+ "hy3": {
318
+ "display_name": "Hunyuan Hy3",
319
+ "family": "Hunyuan",
320
+ "context_window": 256000,
321
+ "max_output_tokens": 16384,
322
+ "capabilities": ["reasoning", "coding", "tools", "streaming"],
323
+ "pricing": {"input_price_per_1m": 1.5, "output_price_per_1m": 5.0},
324
+ },
325
+ "hunyuan-pro": {
326
+ "display_name": "Hunyuan Pro",
327
+ "family": "Hunyuan",
328
+ "context_window": 128000,
329
+ "max_output_tokens": 8192,
330
+ "capabilities": ["coding", "tools", "streaming"],
331
+ "pricing": {"input_price_per_1m": 1.0, "output_price_per_1m": 4.0},
332
+ },
333
+ }
334
+
335
+
336
+ class ByteDanceSeedAdapter(BaseOpenAICompatibleChineseAdapter):
337
+ provider_id = "bytedance"
338
+ display_name = "ByteDance (Doubao / Seed)"
339
+ company = "ByteDance"
340
+ region = "CN"
341
+ api_base = "https://ark.cn-beijing.volces.com/api/v3"
342
+ authentication_type = "bearer_token"
343
+ documentation_url = "https://www.volcengine.com/docs/82379"
344
+
345
+ catalog = {
346
+ "doubao-pro": {
347
+ "display_name": "Doubao Pro (Seed)",
348
+ "family": "Seed",
349
+ "context_window": 128000,
350
+ "max_output_tokens": 8192,
351
+ "capabilities": ["chat", "coding", "tools", "streaming"],
352
+ "pricing": {"input_price_per_1m": 0.12, "output_price_per_1m": 0.24},
353
+ "recommendation_badges": ["Best Budget Model"],
354
+ },
355
+ "doubao-lite": {
356
+ "display_name": "Doubao Lite (Seed)",
357
+ "family": "Seed",
358
+ "context_window": 128000,
359
+ "max_output_tokens": 8192,
360
+ "capabilities": ["chat", "fast", "tools", "streaming"],
361
+ "pricing": {"input_price_per_1m": 0.04, "output_price_per_1m": 0.08},
362
+ "recommendation_badges": ["Best Fast Model"],
363
+ },
364
+ }
365
+
366
+
367
+ class XiaomiMiMoAdapter(BaseOpenAICompatibleChineseAdapter):
368
+ provider_id = "xiaomi"
369
+ display_name = "Xiaomi MiMo"
370
+ company = "Xiaomi"
371
+ region = "CN"
372
+ api_base = "https://api.mimo.mi.com/v1"
373
+ authentication_type = "bearer_token"
374
+ documentation_url = "https://dev.mi.com"
375
+
376
+ catalog = {
377
+ "mimo-pro": {
378
+ "display_name": "MiMo Pro",
379
+ "family": "MiMo",
380
+ "context_window": 128000,
381
+ "max_output_tokens": 8192,
382
+ "capabilities": ["chat", "tools", "streaming"],
383
+ "pricing": {"input_price_per_1m": 0.5, "output_price_per_1m": 1.5},
384
+ },
385
+ }
386
+
387
+
388
+ class BaiduErnieAdapter(BaseOpenAICompatibleChineseAdapter):
389
+ provider_id = "baidu"
390
+ display_name = "Baidu (ERNIE)"
391
+ company = "Baidu"
392
+ region = "CN"
393
+ api_base = "https://aip.baidubce.com/v2"
394
+ authentication_type = "bearer_token"
395
+ documentation_url = "https://cloud.baidu.com/doc/WENXINWORKSHOP"
396
+
397
+ catalog = {
398
+ "ernie-4.0-turbo": {
399
+ "display_name": "ERNIE 4.0 Turbo",
400
+ "family": "ERNIE",
401
+ "context_window": 128000,
402
+ "max_output_tokens": 8192,
403
+ "capabilities": ["reasoning", "coding", "tools", "streaming"],
404
+ "pricing": {"input_price_per_1m": 2.0, "output_price_per_1m": 6.0},
405
+ },
406
+ "ernie-speed": {
407
+ "display_name": "ERNIE Speed",
408
+ "family": "ERNIE",
409
+ "context_window": 128000,
410
+ "max_output_tokens": 8192,
411
+ "capabilities": ["chat", "fast", "streaming"],
412
+ "pricing": {"input_price_per_1m": 0.0, "output_price_per_1m": 0.0},
413
+ "recommendation_badges": ["Best Free Model"],
414
+ },
415
+ }
416
+
417
+
418
+ # Convenience aliases
419
+ AlibabaQwenAdapter = QwenAdapter
420
+ MoonshotKimiAdapter = MoonshotAdapter