agentcrew-ai 0.8.13__py3-none-any.whl → 0.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 (40) hide show
  1. AgentCrew/__init__.py +1 -1
  2. AgentCrew/app.py +34 -633
  3. AgentCrew/main_docker.py +1 -30
  4. AgentCrew/modules/agents/local_agent.py +2 -2
  5. AgentCrew/modules/chat/message/command_processor.py +33 -8
  6. AgentCrew/modules/chat/message/handler.py +5 -1
  7. AgentCrew/modules/console/completers.py +1 -1
  8. AgentCrew/modules/console/console_ui.py +6 -11
  9. AgentCrew/modules/console/conversation_browser/__init__.py +9 -0
  10. AgentCrew/modules/console/conversation_browser/browser.py +84 -0
  11. AgentCrew/modules/console/conversation_browser/browser_input_handler.py +279 -0
  12. AgentCrew/modules/console/{conversation_browser.py → conversation_browser/browser_ui.py} +249 -163
  13. AgentCrew/modules/console/conversation_handler.py +34 -1
  14. AgentCrew/modules/console/display_handlers.py +123 -7
  15. AgentCrew/modules/gui/components/command_handler.py +137 -29
  16. AgentCrew/modules/gui/themes/README.md +30 -14
  17. AgentCrew/modules/gui/themes/__init__.py +2 -1
  18. AgentCrew/modules/gui/themes/atom_light.yaml +1287 -0
  19. AgentCrew/modules/gui/themes/catppuccin.yaml +1276 -0
  20. AgentCrew/modules/gui/themes/dracula.yaml +1262 -0
  21. AgentCrew/modules/gui/themes/nord.yaml +1267 -0
  22. AgentCrew/modules/gui/themes/saigontech.yaml +1268 -0
  23. AgentCrew/modules/gui/themes/style_provider.py +76 -264
  24. AgentCrew/modules/gui/themes/theme_loader.py +379 -0
  25. AgentCrew/modules/gui/themes/unicorn.yaml +1276 -0
  26. AgentCrew/modules/gui/widgets/configs/global_settings.py +3 -4
  27. AgentCrew/modules/llm/constants.py +13 -4
  28. AgentCrew/setup.py +470 -0
  29. {agentcrew_ai-0.8.13.dist-info → agentcrew_ai-0.9.0.dist-info}/METADATA +1 -1
  30. {agentcrew_ai-0.8.13.dist-info → agentcrew_ai-0.9.0.dist-info}/RECORD +34 -29
  31. {agentcrew_ai-0.8.13.dist-info → agentcrew_ai-0.9.0.dist-info}/WHEEL +1 -1
  32. AgentCrew/modules/gui/themes/atom_light.py +0 -1365
  33. AgentCrew/modules/gui/themes/catppuccin.py +0 -1404
  34. AgentCrew/modules/gui/themes/dracula.py +0 -1372
  35. AgentCrew/modules/gui/themes/nord.py +0 -1365
  36. AgentCrew/modules/gui/themes/saigontech.py +0 -1359
  37. AgentCrew/modules/gui/themes/unicorn.py +0 -1372
  38. {agentcrew_ai-0.8.13.dist-info → agentcrew_ai-0.9.0.dist-info}/entry_points.txt +0 -0
  39. {agentcrew_ai-0.8.13.dist-info → agentcrew_ai-0.9.0.dist-info}/licenses/LICENSE +0 -0
  40. {agentcrew_ai-0.8.13.dist-info → agentcrew_ai-0.9.0.dist-info}/top_level.txt +0 -0
@@ -125,10 +125,9 @@ class SettingsTab(QWidget):
125
125
  # Theme dropdown
126
126
  theme_label = QLabel("Theme:")
127
127
  self.theme_dropdown = QComboBox()
128
- self.theme_dropdown.addItems(
129
- ["dark", "light", "nord", "dracula", "unicorn", "saigontech"]
130
- )
131
- self.theme_dropdown.setCurrentText("dark") # Default to dark
128
+ from AgentCrew.modules.gui.themes import ThemeLoader
129
+ self.theme_dropdown.addItems(sorted(ThemeLoader.get_available_themes()))
130
+ self.theme_dropdown.setCurrentText("catppuccin")
132
131
  self.theme_dropdown.setStyleSheet(style_provider.get_combo_box_style())
133
132
  global_settings_form_layout.addRow(theme_label, self.theme_dropdown)
134
133
 
@@ -405,6 +405,7 @@ _GITHUB_COPILOT_MODELS = [
405
405
  description="",
406
406
  capabilities=["tool_use", "vision", "stream"],
407
407
  default=False,
408
+ max_context_token=200_000,
408
409
  input_token_price_1m=0.0,
409
410
  output_token_price_1m=0.0,
410
411
  ),
@@ -477,6 +478,7 @@ _GITHUB_COPILOT_MODELS = [
477
478
  description="",
478
479
  capabilities=["tool_use", "thinking", "vision", "stream", "structured_output"],
479
480
  default=False,
481
+ max_context_token=400_000,
480
482
  input_token_price_1m=0.0,
481
483
  output_token_price_1m=0.0,
482
484
  ),
@@ -487,6 +489,7 @@ _GITHUB_COPILOT_MODELS = [
487
489
  description="",
488
490
  capabilities=["tool_use", "thinking", "vision", "stream", "structured_output"],
489
491
  default=False,
492
+ max_context_token=400_000,
490
493
  input_token_price_1m=0.0,
491
494
  output_token_price_1m=0.0,
492
495
  endpoint="response",
@@ -510,6 +513,7 @@ _GITHUB_COPILOT_MODELS = [
510
513
  description="",
511
514
  capabilities=["tool_use", "vision", "stream", "thinking", "structured_output"],
512
515
  default=False,
516
+ max_context_token=264_000,
513
517
  input_token_price_1m=0.0,
514
518
  output_token_price_1m=0.0,
515
519
  ),
@@ -554,6 +558,7 @@ _GITHUB_COPILOT_MODELS = [
554
558
  description="",
555
559
  capabilities=["tool_use", "vision", "stream", "thinking", "structured_output"],
556
560
  default=False,
561
+ max_context_token=400_000,
557
562
  input_token_price_1m=0.0,
558
563
  output_token_price_1m=0.0,
559
564
  endpoint="response",
@@ -562,7 +567,7 @@ _GITHUB_COPILOT_MODELS = [
562
567
  id="oswe-vscode-prime",
563
568
  provider="github_copilot",
564
569
  name="Raptor mini",
565
- max_context_token=200_000,
570
+ max_context_token=264_000,
566
571
  description="",
567
572
  capabilities=["tool_use", "vision", "stream", "structured_output"],
568
573
  default=True,
@@ -576,6 +581,7 @@ _GITHUB_COPILOT_MODELS = [
576
581
  description="",
577
582
  capabilities=["tool_use", "vision", "stream", "thinking"],
578
583
  default=False,
584
+ max_context_token=216_000,
579
585
  input_token_price_1m=0.0,
580
586
  output_token_price_1m=0.0,
581
587
  ),
@@ -584,8 +590,9 @@ _GITHUB_COPILOT_MODELS = [
584
590
  provider="github_copilot",
585
591
  name="Claude Sonnet 4.5",
586
592
  description="",
587
- capabilities=["tool_use", "vision", "stream"],
593
+ capabilities=["tool_use", "vision", "stream", "thinking"],
588
594
  default=False,
595
+ max_context_token=200_000,
589
596
  input_token_price_1m=0.0,
590
597
  output_token_price_1m=0.0,
591
598
  ),
@@ -594,8 +601,9 @@ _GITHUB_COPILOT_MODELS = [
594
601
  provider="github_copilot",
595
602
  name="Claude Opus 4.1 (Preview)",
596
603
  description="",
597
- capabilities=["tool_use", "vision", "stream"],
604
+ capabilities=["tool_use", "vision", "stream", "thinking"],
598
605
  default=False,
606
+ max_context_token=80_000,
599
607
  input_token_price_1m=0.0,
600
608
  output_token_price_1m=0.0,
601
609
  ),
@@ -604,8 +612,9 @@ _GITHUB_COPILOT_MODELS = [
604
612
  provider="github_copilot",
605
613
  name="Claude Opus 4.5 (Preview)",
606
614
  description="",
607
- capabilities=["tool_use", "vision", "stream"],
615
+ capabilities=["tool_use", "vision", "stream", "thinking"],
608
616
  default=False,
617
+ max_context_token=200_000,
609
618
  input_token_price_1m=0.0,
610
619
  output_token_price_1m=0.0,
611
620
  ),
AgentCrew/setup.py ADDED
@@ -0,0 +1,470 @@
1
+ import os
2
+ import json
3
+ import time
4
+ import webbrowser
5
+ from typing import Optional, Dict, Any
6
+
7
+ import click
8
+ import requests
9
+
10
+ from AgentCrew.modules.config import ConfigManagement
11
+ from AgentCrew.modules.llm.model_registry import ModelRegistry
12
+ from AgentCrew.modules.llm.service_manager import ServiceManager
13
+ from AgentCrew.modules.memory.chroma_service import ChromaMemoryService
14
+ from AgentCrew.modules.memory.context_persistent import ContextPersistenceService
15
+ from AgentCrew.modules.clipboard import ClipboardService
16
+ from AgentCrew.modules.web_search import TavilySearchService
17
+ from AgentCrew.modules.code_analysis import CodeAnalysisService
18
+ from AgentCrew.modules.image_generation import ImageGenerationService
19
+ from AgentCrew.modules.browser_automation import BrowserAutomationService
20
+ from AgentCrew.modules.agents.manager import AgentManager
21
+ from AgentCrew.modules.agents.local_agent import LocalAgent
22
+ from AgentCrew.modules.agents.remote_agent import RemoteAgent
23
+ from AgentCrew.modules.agents.example import (
24
+ DEFAULT_NAME,
25
+ DEFAULT_DESCRIPTION,
26
+ DEFAULT_PROMPT,
27
+ )
28
+
29
+
30
+ PROVIDER_LIST = [
31
+ "claude",
32
+ "groq",
33
+ "openai",
34
+ "google",
35
+ "deepinfra",
36
+ "github_copilot",
37
+ "copilot_response",
38
+ ]
39
+
40
+
41
+ class ApplicationSetup:
42
+ def __init__(self, config_manager: Optional[ConfigManagement] = None):
43
+ self.config_manager = config_manager or ConfigManagement()
44
+ self.services: Optional[Dict[str, Any]] = None
45
+ self.agent_manager: Optional[AgentManager] = None
46
+
47
+ def load_api_keys_from_config(self) -> None:
48
+ config_file_path = os.getenv("AGENTCREW_CONFIG_PATH")
49
+ if not config_file_path:
50
+ config_file_path = "./config.json"
51
+ config_file_path = os.path.expanduser(config_file_path)
52
+
53
+ api_keys_config = {}
54
+ if os.path.exists(config_file_path):
55
+ try:
56
+ with open(config_file_path, "r", encoding="utf-8") as f:
57
+ loaded_config = json.load(f)
58
+ if isinstance(loaded_config, dict) and isinstance(
59
+ loaded_config.get("api_keys"), dict
60
+ ):
61
+ api_keys_config = loaded_config["api_keys"]
62
+ else:
63
+ click.echo(
64
+ f"\u26a0\ufe0f API keys in {config_file_path} are not in the expected format.",
65
+ err=True,
66
+ )
67
+ except json.JSONDecodeError:
68
+ click.echo(
69
+ f"\u26a0\ufe0f Error decoding API keys from {config_file_path}.",
70
+ err=True,
71
+ )
72
+ except Exception as e:
73
+ click.echo(
74
+ f"\u26a0\ufe0f Could not load API keys from {config_file_path}: {e}",
75
+ err=True,
76
+ )
77
+
78
+ keys_to_check = [
79
+ "ANTHROPIC_API_KEY",
80
+ "GEMINI_API_KEY",
81
+ "OPENAI_API_KEY",
82
+ "GROQ_API_KEY",
83
+ "DEEPINFRA_API_KEY",
84
+ "GITHUB_COPILOT_API_KEY",
85
+ "TAVILY_API_KEY",
86
+ "VOYAGE_API_KEY",
87
+ "ELEVENLABS_API_KEY",
88
+ ]
89
+
90
+ for key_name in keys_to_check:
91
+ if key_name in api_keys_config and api_keys_config[key_name]:
92
+ os.environ[key_name] = str(api_keys_config[key_name]).strip()
93
+
94
+ def detect_provider(self) -> Optional[str]:
95
+ try:
96
+ last_provider = self.config_manager.get_last_used_provider()
97
+ if last_provider:
98
+ if last_provider in PROVIDER_LIST:
99
+ api_key_map = {
100
+ "claude": "ANTHROPIC_API_KEY",
101
+ "google": "GEMINI_API_KEY",
102
+ "openai": "OPENAI_API_KEY",
103
+ "groq": "GROQ_API_KEY",
104
+ "deepinfra": "DEEPINFRA_API_KEY",
105
+ "github_copilot": "GITHUB_COPILOT_API_KEY",
106
+ "copilot_response": "GITHUB_COPILOT_API_KEY",
107
+ }
108
+ if os.getenv(api_key_map.get(last_provider, "")):
109
+ return last_provider
110
+ else:
111
+ custom_providers = (
112
+ self.config_manager.read_custom_llm_providers_config()
113
+ )
114
+ if any(p["name"] == last_provider for p in custom_providers):
115
+ return last_provider
116
+ except Exception as e:
117
+ click.echo(f"\u26a0\ufe0f Could not restore last used provider: {e}")
118
+
119
+ if os.getenv("GITHUB_COPILOT_API_KEY"):
120
+ return "github_copilot"
121
+ elif os.getenv("ANTHROPIC_API_KEY"):
122
+ return "claude"
123
+ elif os.getenv("GEMINI_API_KEY"):
124
+ return "google"
125
+ elif os.getenv("OPENAI_API_KEY"):
126
+ return "openai"
127
+ elif os.getenv("GROQ_API_KEY"):
128
+ return "groq"
129
+ elif os.getenv("DEEPINFRA_API_KEY"):
130
+ return "deepinfra"
131
+ else:
132
+ custom_providers = self.config_manager.read_custom_llm_providers_config()
133
+ if len(custom_providers) > 0:
134
+ return custom_providers[0]["name"]
135
+
136
+ return None
137
+
138
+ def setup_services(
139
+ self, provider: str, memory_llm: Optional[str] = None, need_memory: bool = True
140
+ ) -> Dict[str, Any]:
141
+ registry = ModelRegistry.get_instance()
142
+ llm_manager = ServiceManager.get_instance()
143
+
144
+ models = registry.get_models_by_provider(provider)
145
+ if models:
146
+ default_model = next((m for m in models if m.default), models[0])
147
+ registry.set_current_model(f"{default_model.provider}/{default_model.id}")
148
+
149
+ llm_service = llm_manager.get_service(provider)
150
+
151
+ try:
152
+ last_model = self.config_manager.get_last_used_model()
153
+ last_provider = self.config_manager.get_last_used_provider()
154
+
155
+ if last_model and last_provider:
156
+ should_restore = False
157
+ if provider == last_provider:
158
+ should_restore = True
159
+
160
+ last_model_class = registry.get_model(last_model)
161
+ if should_restore and last_model_class:
162
+ llm_service.model = last_model_class.id
163
+ except Exception as e:
164
+ click.echo(f"\u26a0\ufe0f Could not restore last used model: {e}")
165
+
166
+ memory_service = None
167
+ context_service = None
168
+ if need_memory:
169
+ if memory_llm:
170
+ memory_service = ChromaMemoryService(
171
+ llm_service=llm_manager.initialize_standalone_service(memory_llm)
172
+ )
173
+ else:
174
+ memory_service = ChromaMemoryService(
175
+ llm_service=llm_manager.initialize_standalone_service(provider)
176
+ )
177
+
178
+ context_service = ContextPersistenceService()
179
+ clipboard_service = ClipboardService()
180
+
181
+ try:
182
+ search_service = TavilySearchService()
183
+ except Exception as e:
184
+ click.echo(f"\u26a0\ufe0f Web search tools not available: {str(e)}")
185
+ search_service = None
186
+
187
+ try:
188
+ code_analysis_llm = llm_manager.initialize_standalone_service(provider)
189
+ code_analysis_service = CodeAnalysisService(llm_service=code_analysis_llm)
190
+ except Exception as e:
191
+ click.echo(f"\u26a0\ufe0f Code analysis tool not available: {str(e)}")
192
+ code_analysis_service = None
193
+
194
+ try:
195
+ if os.getenv("OPENAI_API_KEY"):
196
+ image_gen_service = ImageGenerationService()
197
+ else:
198
+ image_gen_service = None
199
+ click.echo(
200
+ "\u26a0\ufe0f Image generation service not available: No API keys found."
201
+ )
202
+ except Exception as e:
203
+ click.echo(f"\u26a0\ufe0f Image generation service not available: {str(e)}")
204
+ image_gen_service = None
205
+
206
+ try:
207
+ browser_automation_service = BrowserAutomationService()
208
+ except Exception as e:
209
+ click.echo(
210
+ f"\u26a0\ufe0f Browser automation service not available: {str(e)}"
211
+ )
212
+ browser_automation_service = None
213
+
214
+ try:
215
+ from AgentCrew.modules.file_editing import FileEditingService
216
+
217
+ file_editing_service = FileEditingService()
218
+ except Exception as e:
219
+ click.echo(f"\u26a0\ufe0f File editing service not available: {str(e)}")
220
+ file_editing_service = None
221
+
222
+ try:
223
+ from AgentCrew.modules.command_execution import CommandExecutionService
224
+
225
+ command_execution_service = CommandExecutionService.get_instance()
226
+ except Exception as e:
227
+ click.echo(
228
+ f"\u26a0\ufe0f Command execution service not available: {str(e)}"
229
+ )
230
+ command_execution_service = None
231
+
232
+ self.services = {
233
+ "llm": llm_service,
234
+ "memory": memory_service,
235
+ "clipboard": clipboard_service,
236
+ "code_analysis": code_analysis_service,
237
+ "web_search": search_service,
238
+ "context_persistent": context_service,
239
+ "image_generation": image_gen_service,
240
+ "browser": browser_automation_service,
241
+ "file_editing": file_editing_service,
242
+ "command_execution": command_execution_service,
243
+ }
244
+ return self.services
245
+
246
+ def setup_agents(
247
+ self,
248
+ services: Dict[str, Any],
249
+ config_uri: Optional[str] = None,
250
+ remoting_provider: Optional[str] = None,
251
+ model_id: Optional[str] = None,
252
+ ) -> AgentManager:
253
+ self.agent_manager = AgentManager.get_instance()
254
+ llm_manager = ServiceManager.get_instance()
255
+
256
+ services["agent_manager"] = self.agent_manager
257
+
258
+ global_config = self.config_manager.read_global_config_data()
259
+ self.agent_manager.context_shrink_enabled = global_config.get(
260
+ "global_settings", {}
261
+ ).get("auto_context_shrink", True)
262
+ self.agent_manager.shrink_excluded_list = global_config.get(
263
+ "global_settings", {}
264
+ ).get("shrink_excluded", [])
265
+
266
+ llm_service = services["llm"]
267
+
268
+ if config_uri:
269
+ os.environ["SW_AGENTS_CONFIG"] = config_uri
270
+ else:
271
+ config_uri = os.getenv("SW_AGENTS_CONFIG")
272
+ if not config_uri:
273
+ config_uri = "./agents.toml"
274
+ if not os.path.exists(config_uri):
275
+ click.echo(
276
+ f"Agent configuration not found at {config_uri}. Creating default configuration."
277
+ )
278
+ os.makedirs(os.path.dirname(config_uri), exist_ok=True)
279
+
280
+ default_config = f"""
281
+ [[agents]]
282
+ name = "{DEFAULT_NAME}"
283
+ description = "{DEFAULT_DESCRIPTION}"
284
+ system_prompt = '''{DEFAULT_PROMPT}'''
285
+ tools = ["memory", "browser", "web_search", "code_analysis"]
286
+ """
287
+
288
+ with open(config_uri, "w+", encoding="utf-8") as f:
289
+ f.write(default_config)
290
+
291
+ click.echo(f"Created default agent configuration at {config_uri}")
292
+
293
+ agent_definitions = AgentManager.load_agents_from_config(config_uri)
294
+
295
+ for agent_def in agent_definitions:
296
+ if agent_def.get("base_url", ""):
297
+ try:
298
+ agent = RemoteAgent(
299
+ agent_def["name"],
300
+ agent_def.get("base_url"),
301
+ headers=agent_def.get("headers", {}),
302
+ )
303
+ except Exception:
304
+ print("Error: cannot connect to remote agent, skipping...")
305
+ continue
306
+ else:
307
+ if remoting_provider:
308
+ llm_service = llm_manager.initialize_standalone_service(
309
+ remoting_provider
310
+ )
311
+ if model_id:
312
+ llm_service.model = model_id
313
+ agent = LocalAgent(
314
+ name=agent_def["name"],
315
+ description=agent_def["description"],
316
+ llm_service=llm_service,
317
+ services=services,
318
+ tools=agent_def["tools"],
319
+ temperature=agent_def.get("temperature", None),
320
+ voice_enabled=agent_def.get("voice_enabled", "disabled"),
321
+ voice_id=agent_def.get("voice_id", None),
322
+ )
323
+ agent.set_system_prompt(agent_def["system_prompt"])
324
+ if remoting_provider:
325
+ agent.set_custom_system_prompt(
326
+ self.agent_manager.get_remote_system_prompt()
327
+ )
328
+ agent.is_remoting_mode = True
329
+ agent.activate()
330
+ self.agent_manager.register_agent(agent)
331
+
332
+ from AgentCrew.modules.mcpclient.tool import register as mcp_register
333
+
334
+ mcp_register()
335
+
336
+ if remoting_provider:
337
+ from AgentCrew.modules.mcpclient import MCPSessionManager
338
+
339
+ mcp_manager = MCPSessionManager.get_instance()
340
+ mcp_manager.initialize_for_agent()
341
+ return self.agent_manager
342
+
343
+ return self.agent_manager
344
+
345
+ def restore_last_agent(self) -> None:
346
+ initial_agent_selected = False
347
+ try:
348
+ last_agent = self.config_manager.get_last_used_agent()
349
+
350
+ if (
351
+ last_agent
352
+ and self.agent_manager
353
+ and last_agent in self.agent_manager.agents
354
+ ):
355
+ if self.agent_manager.select_agent(last_agent):
356
+ initial_agent_selected = True
357
+ except Exception as e:
358
+ click.echo(f"\u26a0\ufe0f Could not restore last used agent: {e}")
359
+
360
+ if not initial_agent_selected and self.agent_manager:
361
+ first_agent_name = list(self.agent_manager.agents.keys())[0]
362
+ if not self.agent_manager.select_agent(first_agent_name):
363
+ available_agents = ", ".join(self.agent_manager.agents.keys())
364
+ click.echo(
365
+ f"\u26a0\ufe0f Unknown agent: {first_agent_name}. Using default agent. Available agents: {available_agents}"
366
+ )
367
+
368
+ def login(self) -> bool:
369
+ try:
370
+ click.echo("\U0001f510 Starting GitHub Copilot authentication...")
371
+
372
+ resp = requests.post(
373
+ "https://github.com/login/device/code",
374
+ headers={
375
+ "accept": "application/json",
376
+ "editor-version": "vscode/1.100.3",
377
+ "editor-plugin-version": "GitHub.copilot/1.330.0",
378
+ "content-type": "application/json",
379
+ "user-agent": "GithubCopilot/1.330.0",
380
+ "accept-encoding": "gzip,deflate,br",
381
+ },
382
+ data='{"client_id":"Iv1.b507a08c87ecfe98","scope":"read:user"}',
383
+ )
384
+
385
+ if resp.status_code != 200:
386
+ click.echo(
387
+ f"\u274c Failed to get device code: {resp.status_code}", err=True
388
+ )
389
+ return False
390
+
391
+ resp_json = resp.json()
392
+ device_code = resp_json.get("device_code")
393
+ user_code = resp_json.get("user_code")
394
+ verification_uri = resp_json.get("verification_uri")
395
+
396
+ if not all([device_code, user_code, verification_uri]):
397
+ click.echo("\u274c Invalid response from GitHub", err=True)
398
+ return False
399
+
400
+ click.echo(
401
+ f"\U0001f4cb Please visit {verification_uri} and enter code: {user_code}"
402
+ )
403
+ click.echo("\u23f3 Waiting for authentication...")
404
+
405
+ webbrowser.open(verification_uri)
406
+
407
+ while True:
408
+ time.sleep(5)
409
+
410
+ resp = requests.post(
411
+ "https://github.com/login/oauth/access_token",
412
+ headers={
413
+ "accept": "application/json",
414
+ "editor-version": "vscode/1.100.3",
415
+ "editor-plugin-version": "GitHub.copilot/1.330.0",
416
+ "content-type": "application/json",
417
+ "user-agent": "GithubCopilot/1.330.0",
418
+ "accept-encoding": "gzip,deflate,br",
419
+ },
420
+ data=f'{{"client_id":"Iv1.b507a08c87ecfe98","device_code":"{device_code}","grant_type":"urn:ietf:params:oauth:grant-type:device_code"}}',
421
+ )
422
+
423
+ resp_json = resp.json()
424
+ access_token = resp_json.get("access_token")
425
+ error = resp_json.get("error")
426
+
427
+ if access_token:
428
+ click.echo("\u2705 Authentication successful!")
429
+ break
430
+ elif error == "authorization_pending":
431
+ continue
432
+ elif error == "slow_down":
433
+ time.sleep(5)
434
+ continue
435
+ elif error == "expired_token":
436
+ click.echo(
437
+ "\u274c Authentication expired. Please try again.", err=True
438
+ )
439
+ return False
440
+ elif error == "access_denied":
441
+ click.echo("\u274c Authentication denied by user.", err=True)
442
+ return False
443
+ else:
444
+ click.echo(f"\u274c Authentication error: {error}", err=True)
445
+ return False
446
+
447
+ global_config = self.config_manager.read_global_config_data()
448
+
449
+ if "api_keys" not in global_config:
450
+ global_config["api_keys"] = {}
451
+
452
+ global_config["api_keys"]["GITHUB_COPILOT_API_KEY"] = access_token
453
+ self.config_manager.write_global_config_data(global_config)
454
+
455
+ click.echo("\U0001f4be GitHub Copilot API key saved to config file!")
456
+ click.echo(
457
+ "\U0001f680 You can now use GitHub Copilot with --provider github_copilot"
458
+ )
459
+ return True
460
+
461
+ except ImportError:
462
+ click.echo(
463
+ "\u274c Error: 'requests' package is required for authentication",
464
+ err=True,
465
+ )
466
+ click.echo("Install it with: pip install requests")
467
+ return False
468
+ except Exception as e:
469
+ click.echo(f"\u274c Authentication failed: {str(e)}", err=True)
470
+ return False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentcrew-ai
3
- Version: 0.8.13
3
+ Version: 0.9.0
4
4
  Summary: Multi-Agents Interactive Chat Tool
5
5
  Author-email: Quy Truong <quy.truong@saigontechnology.com>
6
6
  License-Expression: Apache-2.0