Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions examples/python/tools/jira_agent_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#!/usr/bin/env python3
"""
JIRA Agent Watch Example

This example demonstrates how to use the JIRA watch tools with PraisonAI agents.
The agent can monitor JIRA issues and projects for changes, search for issues,
and get detailed issue information.

Setup:
1. Install JIRA library: pip install jira
2. Set environment variables:
- JIRA_EMAIL=your_email@example.com (for cloud JIRA)
- JIRA_API_TOKEN=your_api_token
- Or use JIRA_USERNAME + JIRA_API_TOKEN for server JIRA

Usage:
python jira_agent_example.py
"""

import os
from praisonaiagents import Agent
from praisonaiagents.tools import jira_tools


def main():
"""Demonstrate JIRA agent watch capabilities."""

# Check if JIRA credentials are available
jira_email = os.getenv('JIRA_EMAIL')
jira_token = os.getenv('JIRA_API_TOKEN')
jira_username = os.getenv('JIRA_USERNAME')

if not jira_token:
print("❌ JIRA_API_TOKEN environment variable not set")
print("Please set your JIRA API token:")
print("export JIRA_API_TOKEN='your_token_here'")
return

if not (jira_email or jira_username):
print("❌ JIRA credentials incomplete")
print("Please set either:")
print("- JIRA_EMAIL (for cloud JIRA)")
print("- JIRA_USERNAME (for server JIRA)")
return

# Create agent with JIRA tools
agent = Agent(
name="JIRA Monitor Agent",
instructions="""
You are a JIRA monitoring agent. You can:

1. Watch specific JIRA issues for changes
2. Monitor JIRA projects for new issues and updates
3. Search for issues using JQL queries
4. Get detailed information about specific issues

When using JIRA tools, always provide the full JIRA URL
(e.g., https://yourcompany.atlassian.net).

Be helpful and provide clear summaries of JIRA activity.
""",
tools=jira_tools(), # Add all JIRA tools
llm="gpt-4o-mini"
)

print("🎯 JIRA Agent Watch Example")
print("=" * 50)
print()
print("Available JIRA tools:")
print("- jira_watch_issue: Monitor a specific issue for changes")
print("- jira_watch_project: Monitor a project for new/updated issues")
print("- jira_get_issue_info: Get detailed info about an issue")
print("- jira_search_issues: Search issues using JQL")
print()

# Example interactions
example_prompts = [
"Get information about JIRA issue DEMO-1 from https://praisonai.atlassian.net",
"Search for open issues in project DEMO from https://praisonai.atlassian.net using JQL: 'project = DEMO AND status = Open'",
"Watch JIRA issue DEMO-1 from https://praisonai.atlassian.net for 2 minutes (check every 60 seconds, max 2 checks)",
]

print("πŸ“ Example prompts you can try:")
for i, prompt in enumerate(example_prompts, 1):
print(f"{i}. {prompt}")
print()

# Interactive mode
print("πŸ’¬ Interactive JIRA Agent (type 'quit' to exit)")
print("-" * 50)

while True:
try:
user_input = input("\nπŸ§‘ You: ").strip()

if user_input.lower() in ['quit', 'exit', 'q']:
print("πŸ‘‹ Goodbye!")
break

if not user_input:
continue

print("πŸ€– Agent: ", end="", flush=True)
response = agent.start(user_input)
print(response)

except KeyboardInterrupt:
print("\nπŸ‘‹ Goodbye!")
break
except Exception as e:
print(f"❌ Error: {e}")

Comment on lines +107 to +112

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟑 Minor

Handle EOF explicitly and stop the REPL loop on failures.

input() raises EOFError on Ctrl-D; with only except Exception it’s treated as a generic error and the loop continues (poor UX). Add an except EOFError exit path and break after unexpected exceptions.

Suggested patch
-        except KeyboardInterrupt:
+        except KeyboardInterrupt:
             print("\nπŸ‘‹ Goodbye!")
             break
+        except EOFError:
+            print("\nπŸ‘‹ Goodbye!")
+            break
         except Exception as e:
             print(f"❌ Error: {e}")
+            break
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
except KeyboardInterrupt:
print("\nπŸ‘‹ Goodbye!")
break
except Exception as e:
print(f"❌ Error: {e}")
except KeyboardInterrupt:
print("\nπŸ‘‹ Goodbye!")
break
except EOFError:
print("\nπŸ‘‹ Goodbye!")
break
except Exception as e:
print(f"❌ Error: {e}")
break
🧰 Tools
πŸͺ› Ruff (0.15.15)

[warning] 110-110: Do not catch blind exception: Exception

(BLE001)

πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/python/tools/jira_agent_example.py` around lines 107 - 112, The REPL
currently catches KeyboardInterrupt and a broad Exception but treats EOF
(Ctrl-D) as a generic error and continues; update the try/except around the
input()/REPL loop to add an explicit except EOFError branch that prints a
goodbye message and breaks, and ensure the existing generic except Exception as
e prints the error and then breaks the loop as well (modify the except Exception
handling in this file’s REPL block so it doesn’t continue after unexpected
failures).


if __name__ == "__main__":
main()
10 changes: 9 additions & 1 deletion src/praisonai-agents/praisonaiagents/tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,13 @@
'github_create_pull_request': ('.github_tools', None),
'github_tools': ('.github_tools', None),

# JIRA Tools (watch and monitor JIRA issues/projects)
'jira_watch_issue': ('.jira_tools', None),
'jira_watch_project': ('.jira_tools', None),
'jira_get_issue_info': ('.jira_tools', None),
'jira_search_issues': ('.jira_tools', None),
'jira_tools': ('.jira_tools', None),

# Schedule Tools (agent-centric scheduling)
'schedule_add': ('.schedule_tools', None),
'schedule_list': ('.schedule_tools', None),
Expand Down Expand Up @@ -338,6 +345,7 @@ def __getattr__(name: str) -> Any:
'web_crawl', 'crawl_web', 'get_available_crawl_providers',
'run_skill_script', 'read_skill_file', 'list_skill_scripts', 'create_skill_tools',
'github_create_branch', 'github_commit_and_push', 'github_create_pull_request',
'jira_watch_issue', 'jira_watch_project', 'jira_get_issue_info', 'jira_search_issues',
'schedule_add', 'schedule_list', 'schedule_remove',
'ast_grep_search', 'ast_grep_rewrite', 'ast_grep_scan', 'is_ast_grep_available', 'get_ast_grep_tools',
'store_memory', 'search_memory',
Expand All @@ -348,7 +356,7 @@ def __getattr__(name: str) -> Any:
'clarify'
]:
return getattr(module, name)
if name in ['file_tools', 'spider_tools', 'python_tools', 'shell_tools', 'cot_tools', 'tavily_tools', 'youdotcom_tools', 'exa_tools', 'crawl4ai_tools', 'skill_tools', 'github_tools', 'schedule_tools', 'ast_grep_tools', 'email_tools']:
if name in ['file_tools', 'spider_tools', 'python_tools', 'shell_tools', 'cot_tools', 'tavily_tools', 'youdotcom_tools', 'exa_tools', 'crawl4ai_tools', 'skill_tools', 'github_tools', 'jira_tools', 'schedule_tools', 'ast_grep_tools', 'email_tools']:
return module # Returns the callable module
return getattr(module, name)
else:
Expand Down
Loading
Loading