github-agent 0.2.7__tar.gz → 0.2.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: github-agent
3
- Version: 0.2.7
3
+ Version: 0.2.8
4
4
  Summary: GitHub Agent for MCP
5
5
  Author-email: Audel Rouhi <knucklessg1@gmail.com>
6
6
  License: MIT
@@ -43,7 +43,7 @@ Dynamic: license-file
43
43
  ![PyPI - Wheel](https://img.shields.io/pypi/wheel/github-agent)
44
44
  ![PyPI - Implementation](https://img.shields.io/pypi/implementation/github-agent)
45
45
 
46
- *Version: 0.2.7*
46
+ *Version: 0.2.8*
47
47
 
48
48
  ## Overview
49
49
 
@@ -21,7 +21,7 @@
21
21
  ![PyPI - Wheel](https://img.shields.io/pypi/wheel/github-agent)
22
22
  ![PyPI - Implementation](https://img.shields.io/pypi/implementation/github-agent)
23
23
 
24
- *Version: 0.2.7*
24
+ *Version: 0.2.8*
25
25
 
26
26
  ## Overview
27
27
 
@@ -39,7 +39,7 @@ from pydantic import ValidationError
39
39
  from pydantic_ai.ui import SSE_CONTENT_TYPE
40
40
  from pydantic_ai.ui.ag_ui import AGUIAdapter
41
41
 
42
- __version__ = "0.2.7"
42
+ __version__ = "0.2.8"
43
43
 
44
44
  logging.basicConfig(
45
45
  level=logging.INFO,
@@ -379,13 +379,39 @@ def create_agent(
379
379
  else:
380
380
  pass
381
381
 
382
+ # Collect tool names for logging
383
+ all_tool_names = []
384
+ for ts in tag_toolsets:
385
+ try:
386
+ # Unwrap FilteredToolset
387
+ current_ts = ts
388
+ while hasattr(current_ts, "wrapped"):
389
+ current_ts = current_ts.wrapped
390
+
391
+ # Check for .tools (e.g. SkillsToolset)
392
+ if hasattr(current_ts, "tools") and isinstance(current_ts.tools, dict):
393
+ all_tool_names.extend(current_ts.tools.keys())
394
+ # Check for ._tools (some implementations might use private attr)
395
+ elif hasattr(current_ts, "_tools") and isinstance(
396
+ current_ts._tools, dict
397
+ ):
398
+ all_tool_names.extend(current_ts._tools.keys())
399
+ else:
400
+ # Fallback for MCP or others where tools are not available sync
401
+ all_tool_names.append(f"<{type(current_ts).__name__}>")
402
+ except Exception as e:
403
+ logger.info(f"Unable to retrieve toolset: {e}")
404
+ pass
405
+
406
+ tool_list_str = ", ".join(all_tool_names)
407
+ logger.info(f"Available tools for {agent_name} ({tag}): {tool_list_str}")
382
408
  agent = Agent(
383
- name=agent_name,
384
- system_prompt=system_prompt,
385
409
  model=model,
386
- model_settings=settings,
410
+ system_prompt=system_prompt,
411
+ name=agent_name,
387
412
  toolsets=tag_toolsets,
388
413
  tool_timeout=DEFAULT_TOOL_TIMEOUT,
414
+ model_settings=settings,
389
415
  )
390
416
  child_agents[tag] = agent
391
417
 
@@ -400,171 +426,267 @@ def create_agent(
400
426
  @supervisor.tool
401
427
  async def assign_task_to_context_agent(ctx: RunContext[Any], task: str) -> str:
402
428
  """Assign a task related to user context and general GitHub status to the Context Agent."""
403
- return (
404
- await child_agents["person"].run(task, usage=ctx.usage, deps=ctx.deps)
405
- ).output
429
+ try:
430
+ return (
431
+ await child_agents["person"].run(task, usage=ctx.usage, deps=ctx.deps)
432
+ ).output
433
+ except Exception as e:
434
+ logger.exception(f"Error in Context Agent: {e}")
435
+ return f"Error executing task for Context Agent: {e}"
406
436
 
407
437
  @supervisor.tool
408
438
  async def assign_task_to_actions_agent(ctx: RunContext[Any], task: str) -> str:
409
439
  """Assign a task related to GitHub Actions and Workflows to the Actions Agent."""
410
- return (
411
- await child_agents["workflow"].run(task, usage=ctx.usage, deps=ctx.deps)
412
- ).output
440
+ try:
441
+ return (
442
+ await child_agents["workflow"].run(task, usage=ctx.usage, deps=ctx.deps)
443
+ ).output
444
+ except Exception as e:
445
+ logger.exception(f"Error in Actions Agent: {e}")
446
+ return f"Error executing task for Actions Agent: {e}"
413
447
 
414
448
  @supervisor.tool
415
449
  async def assign_task_to_code_security_agent(
416
450
  ctx: RunContext[Any], task: str
417
451
  ) -> str:
418
452
  """Assign a task related to code security and scanning to the Code Security Agent."""
419
- return (
420
- await child_agents["codescan"].run(task, usage=ctx.usage, deps=ctx.deps)
421
- ).output
453
+ try:
454
+ return (
455
+ await child_agents["codescan"].run(task, usage=ctx.usage, deps=ctx.deps)
456
+ ).output
457
+ except Exception as e:
458
+ logger.exception(f"Error in Code Security Agent: {e}")
459
+ return f"Error executing task for Code Security Agent: {e}"
422
460
 
423
461
  @supervisor.tool
424
462
  async def assign_task_to_dependabot_agent(ctx: RunContext[Any], task: str) -> str:
425
463
  """Assign a task related to Dependabot to the Dependabot Agent."""
426
- return (
427
- await child_agents["dependabot"].run(task, usage=ctx.usage, deps=ctx.deps)
428
- ).output
464
+ try:
465
+ return (
466
+ await child_agents["dependabot"].run(
467
+ task, usage=ctx.usage, deps=ctx.deps
468
+ )
469
+ ).output
470
+ except Exception as e:
471
+ logger.exception(f"Error in Dependabot Agent: {e}")
472
+ return f"Error executing task for Dependabot Agent: {e}"
429
473
 
430
474
  @supervisor.tool
431
475
  async def assign_task_to_discussions_agent(ctx: RunContext[Any], task: str) -> str:
432
476
  """Assign a task related to GitHub Discussions to the Discussions Agent."""
433
- return (
434
- await child_agents["comment-discussion"].run(
435
- task, usage=ctx.usage, deps=ctx.deps
436
- )
437
- ).output
477
+ try:
478
+ return (
479
+ await child_agents["comment-discussion"].run(
480
+ task, usage=ctx.usage, deps=ctx.deps
481
+ )
482
+ ).output
483
+ except Exception as e:
484
+ logger.exception(f"Error in Discussions Agent: {e}")
485
+ return f"Error executing task for Discussions Agent: {e}"
438
486
 
439
487
  @supervisor.tool
440
488
  async def assign_task_to_gists_agent(ctx: RunContext[Any], task: str) -> str:
441
489
  """Assign a task related to Gists to the Gists Agent."""
442
- return (
443
- await child_agents["logo-gist"].run(task, usage=ctx.usage, deps=ctx.deps)
444
- ).output
490
+ try:
491
+ return (
492
+ await child_agents["logo-gist"].run(
493
+ task, usage=ctx.usage, deps=ctx.deps
494
+ )
495
+ ).output
496
+ except Exception as e:
497
+ logger.exception(f"Error in Gists Agent: {e}")
498
+ return f"Error executing task for Gists Agent: {e}"
445
499
 
446
500
  @supervisor.tool
447
501
  async def assign_task_to_git_agent(ctx: RunContext[Any], task: str) -> str:
448
502
  """Assign a task related to low-level Git operations (refs, blobs) to the Git Agent."""
449
- return (
450
- await child_agents["git-branch"].run(task, usage=ctx.usage, deps=ctx.deps)
451
- ).output
503
+ try:
504
+ return (
505
+ await child_agents["git-branch"].run(
506
+ task, usage=ctx.usage, deps=ctx.deps
507
+ )
508
+ ).output
509
+ except Exception as e:
510
+ logger.exception(f"Error in Git Agent: {e}")
511
+ return f"Error executing task for Git Agent: {e}"
452
512
 
453
513
  @supervisor.tool
454
514
  async def assign_task_to_issues_agent(ctx: RunContext[Any], task: str) -> str:
455
515
  """Assign a task related to Issues (create, list, comment) to the Issues Agent."""
456
- return (
457
- await child_agents["issue-opened"].run(task, usage=ctx.usage, deps=ctx.deps)
458
- ).output
516
+ try:
517
+ return (
518
+ await child_agents["issue-opened"].run(
519
+ task, usage=ctx.usage, deps=ctx.deps
520
+ )
521
+ ).output
522
+ except Exception as e:
523
+ logger.exception(f"Error in Issues Agent: {e}")
524
+ return f"Error executing task for Issues Agent: {e}"
459
525
 
460
526
  @supervisor.tool
461
527
  async def assign_task_to_labels_agent(ctx: RunContext[Any], task: str) -> str:
462
528
  """Assign a task related to Labels to the Labels Agent."""
463
- return (
464
- await child_agents["tag"].run(task, usage=ctx.usage, deps=ctx.deps)
465
- ).output
529
+ try:
530
+ return (
531
+ await child_agents["tag"].run(task, usage=ctx.usage, deps=ctx.deps)
532
+ ).output
533
+ except Exception as e:
534
+ logger.exception(f"Error in Labels Agent: {e}")
535
+ return f"Error executing task for Labels Agent: {e}"
466
536
 
467
537
  @supervisor.tool
468
538
  async def assign_task_to_notifications_agent(
469
539
  ctx: RunContext[Any], task: str
470
540
  ) -> str:
471
541
  """Assign a task related to Notifications to the Notifications Agent."""
472
- return (
473
- await child_agents["bell"].run(task, usage=ctx.usage, deps=ctx.deps)
474
- ).output
542
+ try:
543
+ return (
544
+ await child_agents["bell"].run(task, usage=ctx.usage, deps=ctx.deps)
545
+ ).output
546
+ except Exception as e:
547
+ logger.exception(f"Error in Notifications Agent: {e}")
548
+ return f"Error executing task for Notifications Agent: {e}"
475
549
 
476
550
  @supervisor.tool
477
551
  async def assign_task_to_organizations_agent(
478
552
  ctx: RunContext[Any], task: str
479
553
  ) -> str:
480
554
  """Assign a task related to Organizations to the Organizations Agent."""
481
- return (
482
- await child_agents["organization"].run(task, usage=ctx.usage, deps=ctx.deps)
483
- ).output
555
+ try:
556
+ return (
557
+ await child_agents["organization"].run(
558
+ task, usage=ctx.usage, deps=ctx.deps
559
+ )
560
+ ).output
561
+ except Exception as e:
562
+ logger.exception(f"Error in Organizations Agent: {e}")
563
+ return f"Error executing task for Organizations Agent: {e}"
484
564
 
485
565
  @supervisor.tool
486
566
  async def assign_task_to_projects_agent(ctx: RunContext[Any], task: str) -> str:
487
567
  """Assign a task related to GitHub Projects to the Projects Agent."""
488
- return (
489
- await child_agents["project"].run(task, usage=ctx.usage, deps=ctx.deps)
490
- ).output
568
+ try:
569
+ return (
570
+ await child_agents["project"].run(task, usage=ctx.usage, deps=ctx.deps)
571
+ ).output
572
+ except Exception as e:
573
+ logger.exception(f"Error in Projects Agent: {e}")
574
+ return f"Error executing task for Projects Agent: {e}"
491
575
 
492
576
  @supervisor.tool
493
577
  async def assign_task_to_pull_requests_agent(
494
578
  ctx: RunContext[Any], task: str
495
579
  ) -> str:
496
580
  """Assign a task related to Pull Requests to the Pull Requests Agent."""
497
- return (
498
- await child_agents["git-pull-request"].run(
499
- task, usage=ctx.usage, deps=ctx.deps
500
- )
501
- ).output
581
+ try:
582
+ return (
583
+ await child_agents["git-pull-request"].run(
584
+ task, usage=ctx.usage, deps=ctx.deps
585
+ )
586
+ ).output
587
+ except Exception as e:
588
+ logger.exception(f"Error in Pull Requests Agent: {e}")
589
+ return f"Error executing task for Pull Requests Agent: {e}"
502
590
 
503
591
  @supervisor.tool
504
592
  async def assign_task_to_repos_agent(ctx: RunContext[Any], task: str) -> str:
505
593
  """Assign a task related to Repositories (list, settings, delete) to the Repositories Agent."""
506
- return (
507
- await child_agents["repo"].run(task, usage=ctx.usage, deps=ctx.deps)
508
- ).output
594
+ try:
595
+ return (
596
+ await child_agents["repo"].run(task, usage=ctx.usage, deps=ctx.deps)
597
+ ).output
598
+ except Exception as e:
599
+ logger.exception(f"Error in Repositories Agent: {e}")
600
+ return f"Error executing task for Repositories Agent: {e}"
509
601
 
510
602
  @supervisor.tool
511
603
  async def assign_task_to_secret_protection_agent(
512
604
  ctx: RunContext[Any], task: str
513
605
  ) -> str:
514
606
  """Assign a task related to Secret Protection to the Secret Protection Agent."""
515
- return (
516
- await child_agents["shield-lock"].run(task, usage=ctx.usage, deps=ctx.deps)
517
- ).output
607
+ try:
608
+ return (
609
+ await child_agents["shield-lock"].run(
610
+ task, usage=ctx.usage, deps=ctx.deps
611
+ )
612
+ ).output
613
+ except Exception as e:
614
+ logger.exception(f"Error in Secret Protection Agent: {e}")
615
+ return f"Error executing task for Secret Protection Agent: {e}"
518
616
 
519
617
  @supervisor.tool
520
618
  async def assign_task_to_security_advisories_agent(
521
619
  ctx: RunContext[Any], task: str
522
620
  ) -> str:
523
621
  """Assign a task related to Security Advisories to the Security Advisories Agent."""
524
- return (
525
- await child_agents["shield"].run(task, usage=ctx.usage, deps=ctx.deps)
526
- ).output
622
+ try:
623
+ return (
624
+ await child_agents["shield"].run(task, usage=ctx.usage, deps=ctx.deps)
625
+ ).output
626
+ except Exception as e:
627
+ logger.exception(f"Error in Security Advisories Agent: {e}")
628
+ return f"Error executing task for Security Advisories Agent: {e}"
527
629
 
528
630
  @supervisor.tool
529
631
  async def assign_task_to_stargazers_agent(ctx: RunContext[Any], task: str) -> str:
530
632
  """Assign a task related to Stargazers to the Stargazers Agent."""
531
- return (
532
- await child_agents["star"].run(task, usage=ctx.usage, deps=ctx.deps)
533
- ).output
633
+ try:
634
+ return (
635
+ await child_agents["star"].run(task, usage=ctx.usage, deps=ctx.deps)
636
+ ).output
637
+ except Exception as e:
638
+ logger.exception(f"Error in Stargazers Agent: {e}")
639
+ return f"Error executing task for Stargazers Agent: {e}"
534
640
 
535
641
  @supervisor.tool
536
642
  async def assign_task_to_users_agent(ctx: RunContext[Any], task: str) -> str:
537
643
  """Assign a task related to Users to the Users Agent."""
538
- return (
539
- await child_agents["people"].run(task, usage=ctx.usage, deps=ctx.deps)
540
- ).output
644
+ try:
645
+ return (
646
+ await child_agents["people"].run(task, usage=ctx.usage, deps=ctx.deps)
647
+ ).output
648
+ except Exception as e:
649
+ logger.exception(f"Error in Users Agent: {e}")
650
+ return f"Error executing task for Users Agent: {e}"
541
651
 
542
652
  @supervisor.tool
543
653
  async def assign_task_to_copilot_agent(ctx: RunContext[Any], task: str) -> str:
544
654
  """Assign a task related to GitHub Copilot coding tasks to the Copilot Agent."""
545
- return (
546
- await child_agents["copilot"].run(task, usage=ctx.usage, deps=ctx.deps)
547
- ).output
655
+ try:
656
+ return (
657
+ await child_agents["copilot"].run(task, usage=ctx.usage, deps=ctx.deps)
658
+ ).output
659
+ except Exception as e:
660
+ logger.exception(f"Error in Copilot Agent: {e}")
661
+ return f"Error executing task for Copilot Agent: {e}"
548
662
 
549
663
  @supervisor.tool
550
664
  async def assign_task_to_copilot_spaces_agent(
551
665
  ctx: RunContext[Any], task: str
552
666
  ) -> str:
553
667
  """Assign a task related to Copilot Spaces to the Copilot Spaces Agent."""
554
- return (
555
- await child_agents["copilot_spaces"].run(
556
- task, usage=ctx.usage, deps=ctx.deps
557
- )
558
- ).output
668
+ try:
669
+ return (
670
+ await child_agents["copilot_spaces"].run(
671
+ task, usage=ctx.usage, deps=ctx.deps
672
+ )
673
+ ).output
674
+ except Exception as e:
675
+ logger.exception(f"Error in Copilot Spaces Agent: {e}")
676
+ return f"Error executing task for Copilot Spaces Agent: {e}"
559
677
 
560
678
  @supervisor.tool
561
679
  async def assign_task_to_support_docs_agent(ctx: RunContext[Any], task: str) -> str:
562
680
  """Assign a task to search GitHub Support Docs to the Support Docs Agent."""
563
- return (
564
- await child_agents["github_support_docs_search"].run(
565
- task, usage=ctx.usage, deps=ctx.deps
566
- )
567
- ).output
681
+ try:
682
+ return (
683
+ await child_agents["github_support_docs_search"].run(
684
+ task, usage=ctx.usage, deps=ctx.deps
685
+ )
686
+ ).output
687
+ except Exception as e:
688
+ logger.exception(f"Error in Support Docs Agent: {e}")
689
+ return f"Error executing task for Support Docs Agent: {e}"
568
690
 
569
691
  return supervisor
570
692
 
@@ -600,7 +722,6 @@ def create_agent_server(
600
722
  mcp_config=mcp_config,
601
723
  skills_directory=skills_directory,
602
724
  ssl_verify=ssl_verify,
603
- timeout=DEFAULT_TIMEOUT,
604
725
  )
605
726
 
606
727
  if skills_directory and os.path.exists(skills_directory):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: github-agent
3
- Version: 0.2.7
3
+ Version: 0.2.8
4
4
  Summary: GitHub Agent for MCP
5
5
  Author-email: Audel Rouhi <knucklessg1@gmail.com>
6
6
  License: MIT
@@ -43,7 +43,7 @@ Dynamic: license-file
43
43
  ![PyPI - Wheel](https://img.shields.io/pypi/wheel/github-agent)
44
44
  ![PyPI - Implementation](https://img.shields.io/pypi/implementation/github-agent)
45
45
 
46
- *Version: 0.2.7*
46
+ *Version: 0.2.8*
47
47
 
48
48
  ## Overview
49
49
 
@@ -9,4 +9,5 @@ github_agent.egg-info/SOURCES.txt
9
9
  github_agent.egg-info/dependency_links.txt
10
10
  github_agent.egg-info/entry_points.txt
11
11
  github_agent.egg-info/requires.txt
12
- github_agent.egg-info/top_level.txt
12
+ github_agent.egg-info/top_level.txt
13
+ scripts/validate_a2a_agent.py
@@ -1,2 +1,3 @@
1
1
  dist
2
2
  github_agent
3
+ scripts
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "github-agent"
7
- version = "0.2.7"
7
+ version = "0.2.8"
8
8
  readme = "README.md"
9
9
  description = "GitHub Agent for MCP"
10
10
  requires-python = ">=3.10"
@@ -0,0 +1,139 @@
1
+ #!/usr/bin/env python3
2
+ import asyncio
3
+ import httpx
4
+ import json
5
+ import uuid
6
+
7
+ A2A_URL = "http://audio-transcriber-agent.arpa/a2a/"
8
+
9
+
10
+ async def main():
11
+ print(f"Validating A2A Agent at {A2A_URL}...")
12
+
13
+ questions = [
14
+ "What tools do you have available?",
15
+ ]
16
+
17
+ async with httpx.AsyncClient(timeout=10000.0) as client:
18
+
19
+ for q in questions:
20
+ print(f"\n\n\nUser: {q}")
21
+ print("--- Sending Request ---")
22
+
23
+ payload = {
24
+ "jsonrpc": "2.0",
25
+ "method": "message/send",
26
+ "params": {
27
+ "message": {
28
+ "kind": "message",
29
+ "role": "user",
30
+ "parts": [{"kind": "text", "text": q}],
31
+ "messageId": str(uuid.uuid4()),
32
+ }
33
+ },
34
+ "id": 1,
35
+ }
36
+
37
+ try:
38
+ url = A2A_URL
39
+ print(f"Trying POST {url} with JSON-RPC (message/send)...")
40
+ resp = await client.post(
41
+ url, json=payload, headers={"Content-Type": "application/json"}
42
+ )
43
+
44
+ print(f"Status Code: {resp.status_code}")
45
+ if resp.status_code == 200:
46
+ try:
47
+ data = resp.json()
48
+ print(f"Response (JSON):\n{json.dumps(data, indent=2)}")
49
+
50
+ if "result" in data and "id" in data["result"]:
51
+ task_id = data["result"]["id"]
52
+ print(
53
+ f"\nTask Submitted with ID: {task_id}. Polling for result..."
54
+ )
55
+
56
+ while True:
57
+ await asyncio.sleep(2)
58
+ poll_payload = {
59
+ "jsonrpc": "2.0",
60
+ "method": "tasks/get",
61
+ "params": {"id": task_id},
62
+ "id": 2,
63
+ }
64
+ poll_resp = await client.post(
65
+ url,
66
+ json=poll_payload,
67
+ headers={"Content-Type": "application/json"},
68
+ )
69
+ if poll_resp.status_code == 200:
70
+ poll_data = poll_resp.json()
71
+ if "result" in poll_data:
72
+ state = poll_data["result"]["status"]["state"]
73
+ print(f"Task State: {state}")
74
+ if state not in [
75
+ "submitted",
76
+ "running",
77
+ "working",
78
+ ]:
79
+ print(
80
+ f"\nTask Finished with state: {state}"
81
+ )
82
+
83
+ if "history" in poll_data["result"]:
84
+ history = poll_data["result"]["history"]
85
+ if history:
86
+ last_msg = None
87
+ for msg in reversed(history):
88
+ if msg.get("role") != "user":
89
+ last_msg = msg
90
+ break
91
+
92
+ if last_msg and "parts" in last_msg:
93
+ print(
94
+ "\n--- Agent Response ---"
95
+ )
96
+ for part in last_msg["parts"]:
97
+ if "text" in part:
98
+ print(part["text"])
99
+ elif "content" in part:
100
+ print(part["content"])
101
+ elif last_msg:
102
+ print(
103
+ f"Final Message (No parts): {last_msg}"
104
+ )
105
+ else:
106
+ print(
107
+ "\n--- No Agent Response Found in History ---"
108
+ )
109
+
110
+ print(
111
+ f"Full Result Debug:\n{json.dumps(poll_data, indent=2)}"
112
+ )
113
+ break
114
+ else:
115
+ print("Starting polling error key check...")
116
+ if "error" in poll_data:
117
+ print(
118
+ f"Polling Error: {poll_data['error']}"
119
+ )
120
+ break
121
+ else:
122
+ print(f"Polling Failed: {poll_resp.status_code}")
123
+ print(f"Polling Error Details: {poll_resp.text}")
124
+ break
125
+
126
+ if "error" in data:
127
+ print(f"JSON-RPC Error: {data['error']}")
128
+ except json.JSONDecodeError:
129
+ print(f"Response (Text):\n{resp.text}")
130
+ else:
131
+ print(f"Error: {resp.status_code}")
132
+ print(resp.text)
133
+
134
+ except httpx.RequestError as e:
135
+ print(f"Connection failed to {url}: {e}")
136
+
137
+
138
+ if __name__ == "__main__":
139
+ asyncio.run(main())
File without changes
File without changes