titan-cli 0.1.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 (146) hide show
  1. titan_cli/__init__.py +3 -0
  2. titan_cli/__main__.py +4 -0
  3. titan_cli/ai/__init__.py +0 -0
  4. titan_cli/ai/agents/__init__.py +15 -0
  5. titan_cli/ai/agents/base.py +152 -0
  6. titan_cli/ai/client.py +170 -0
  7. titan_cli/ai/constants.py +56 -0
  8. titan_cli/ai/exceptions.py +48 -0
  9. titan_cli/ai/models.py +34 -0
  10. titan_cli/ai/oauth_helper.py +120 -0
  11. titan_cli/ai/providers/__init__.py +9 -0
  12. titan_cli/ai/providers/anthropic.py +117 -0
  13. titan_cli/ai/providers/base.py +75 -0
  14. titan_cli/ai/providers/gemini.py +278 -0
  15. titan_cli/cli.py +59 -0
  16. titan_cli/clients/__init__.py +1 -0
  17. titan_cli/clients/gcloud_client.py +52 -0
  18. titan_cli/core/__init__.py +3 -0
  19. titan_cli/core/config.py +274 -0
  20. titan_cli/core/discovery.py +51 -0
  21. titan_cli/core/errors.py +81 -0
  22. titan_cli/core/models.py +52 -0
  23. titan_cli/core/plugins/available.py +36 -0
  24. titan_cli/core/plugins/models.py +67 -0
  25. titan_cli/core/plugins/plugin_base.py +108 -0
  26. titan_cli/core/plugins/plugin_registry.py +163 -0
  27. titan_cli/core/secrets.py +141 -0
  28. titan_cli/core/workflows/__init__.py +22 -0
  29. titan_cli/core/workflows/models.py +88 -0
  30. titan_cli/core/workflows/project_step_source.py +86 -0
  31. titan_cli/core/workflows/workflow_exceptions.py +17 -0
  32. titan_cli/core/workflows/workflow_filter_service.py +137 -0
  33. titan_cli/core/workflows/workflow_registry.py +419 -0
  34. titan_cli/core/workflows/workflow_sources.py +307 -0
  35. titan_cli/engine/__init__.py +39 -0
  36. titan_cli/engine/builder.py +159 -0
  37. titan_cli/engine/context.py +82 -0
  38. titan_cli/engine/mock_context.py +176 -0
  39. titan_cli/engine/results.py +91 -0
  40. titan_cli/engine/steps/ai_assistant_step.py +185 -0
  41. titan_cli/engine/steps/command_step.py +93 -0
  42. titan_cli/engine/utils/__init__.py +3 -0
  43. titan_cli/engine/utils/venv.py +31 -0
  44. titan_cli/engine/workflow_executor.py +187 -0
  45. titan_cli/external_cli/__init__.py +0 -0
  46. titan_cli/external_cli/configs.py +17 -0
  47. titan_cli/external_cli/launcher.py +65 -0
  48. titan_cli/messages.py +121 -0
  49. titan_cli/ui/tui/__init__.py +205 -0
  50. titan_cli/ui/tui/__previews__/statusbar_preview.py +88 -0
  51. titan_cli/ui/tui/app.py +113 -0
  52. titan_cli/ui/tui/icons.py +70 -0
  53. titan_cli/ui/tui/screens/__init__.py +24 -0
  54. titan_cli/ui/tui/screens/ai_config.py +498 -0
  55. titan_cli/ui/tui/screens/ai_config_wizard.py +882 -0
  56. titan_cli/ui/tui/screens/base.py +110 -0
  57. titan_cli/ui/tui/screens/cli_launcher.py +151 -0
  58. titan_cli/ui/tui/screens/global_setup_wizard.py +363 -0
  59. titan_cli/ui/tui/screens/main_menu.py +162 -0
  60. titan_cli/ui/tui/screens/plugin_config_wizard.py +550 -0
  61. titan_cli/ui/tui/screens/plugin_management.py +377 -0
  62. titan_cli/ui/tui/screens/project_setup_wizard.py +686 -0
  63. titan_cli/ui/tui/screens/workflow_execution.py +592 -0
  64. titan_cli/ui/tui/screens/workflows.py +249 -0
  65. titan_cli/ui/tui/textual_components.py +537 -0
  66. titan_cli/ui/tui/textual_workflow_executor.py +405 -0
  67. titan_cli/ui/tui/theme.py +102 -0
  68. titan_cli/ui/tui/widgets/__init__.py +40 -0
  69. titan_cli/ui/tui/widgets/button.py +108 -0
  70. titan_cli/ui/tui/widgets/header.py +116 -0
  71. titan_cli/ui/tui/widgets/panel.py +81 -0
  72. titan_cli/ui/tui/widgets/status_bar.py +115 -0
  73. titan_cli/ui/tui/widgets/table.py +77 -0
  74. titan_cli/ui/tui/widgets/text.py +177 -0
  75. titan_cli/utils/__init__.py +0 -0
  76. titan_cli/utils/autoupdate.py +155 -0
  77. titan_cli-0.1.0.dist-info/METADATA +149 -0
  78. titan_cli-0.1.0.dist-info/RECORD +146 -0
  79. titan_cli-0.1.0.dist-info/WHEEL +4 -0
  80. titan_cli-0.1.0.dist-info/entry_points.txt +9 -0
  81. titan_cli-0.1.0.dist-info/licenses/LICENSE +201 -0
  82. titan_plugin_git/__init__.py +1 -0
  83. titan_plugin_git/clients/__init__.py +8 -0
  84. titan_plugin_git/clients/git_client.py +772 -0
  85. titan_plugin_git/exceptions.py +40 -0
  86. titan_plugin_git/messages.py +112 -0
  87. titan_plugin_git/models.py +39 -0
  88. titan_plugin_git/plugin.py +118 -0
  89. titan_plugin_git/steps/__init__.py +1 -0
  90. titan_plugin_git/steps/ai_commit_message_step.py +171 -0
  91. titan_plugin_git/steps/branch_steps.py +104 -0
  92. titan_plugin_git/steps/commit_step.py +80 -0
  93. titan_plugin_git/steps/push_step.py +63 -0
  94. titan_plugin_git/steps/status_step.py +59 -0
  95. titan_plugin_git/workflows/__previews__/__init__.py +1 -0
  96. titan_plugin_git/workflows/__previews__/commit_ai_preview.py +124 -0
  97. titan_plugin_git/workflows/commit-ai.yaml +28 -0
  98. titan_plugin_github/__init__.py +11 -0
  99. titan_plugin_github/agents/__init__.py +6 -0
  100. titan_plugin_github/agents/config_loader.py +130 -0
  101. titan_plugin_github/agents/issue_generator.py +353 -0
  102. titan_plugin_github/agents/pr_agent.py +528 -0
  103. titan_plugin_github/clients/__init__.py +8 -0
  104. titan_plugin_github/clients/github_client.py +1105 -0
  105. titan_plugin_github/config/__init__.py +0 -0
  106. titan_plugin_github/config/pr_agent.toml +85 -0
  107. titan_plugin_github/exceptions.py +28 -0
  108. titan_plugin_github/messages.py +88 -0
  109. titan_plugin_github/models.py +330 -0
  110. titan_plugin_github/plugin.py +131 -0
  111. titan_plugin_github/steps/__init__.py +12 -0
  112. titan_plugin_github/steps/ai_pr_step.py +172 -0
  113. titan_plugin_github/steps/create_pr_step.py +86 -0
  114. titan_plugin_github/steps/github_prompt_steps.py +171 -0
  115. titan_plugin_github/steps/issue_steps.py +143 -0
  116. titan_plugin_github/steps/preview_step.py +40 -0
  117. titan_plugin_github/utils.py +82 -0
  118. titan_plugin_github/workflows/__previews__/__init__.py +1 -0
  119. titan_plugin_github/workflows/__previews__/create_pr_ai_preview.py +140 -0
  120. titan_plugin_github/workflows/create-issue-ai.yaml +32 -0
  121. titan_plugin_github/workflows/create-pr-ai.yaml +49 -0
  122. titan_plugin_jira/__init__.py +8 -0
  123. titan_plugin_jira/agents/__init__.py +6 -0
  124. titan_plugin_jira/agents/config_loader.py +154 -0
  125. titan_plugin_jira/agents/jira_agent.py +553 -0
  126. titan_plugin_jira/agents/prompts.py +364 -0
  127. titan_plugin_jira/agents/response_parser.py +435 -0
  128. titan_plugin_jira/agents/token_tracker.py +223 -0
  129. titan_plugin_jira/agents/validators.py +246 -0
  130. titan_plugin_jira/clients/jira_client.py +745 -0
  131. titan_plugin_jira/config/jira_agent.toml +92 -0
  132. titan_plugin_jira/config/templates/issue_analysis.md.j2 +78 -0
  133. titan_plugin_jira/exceptions.py +37 -0
  134. titan_plugin_jira/formatters/__init__.py +6 -0
  135. titan_plugin_jira/formatters/markdown_formatter.py +245 -0
  136. titan_plugin_jira/messages.py +115 -0
  137. titan_plugin_jira/models.py +89 -0
  138. titan_plugin_jira/plugin.py +264 -0
  139. titan_plugin_jira/steps/ai_analyze_issue_step.py +105 -0
  140. titan_plugin_jira/steps/get_issue_step.py +82 -0
  141. titan_plugin_jira/steps/prompt_select_issue_step.py +80 -0
  142. titan_plugin_jira/steps/search_saved_query_step.py +238 -0
  143. titan_plugin_jira/utils/__init__.py +13 -0
  144. titan_plugin_jira/utils/issue_sorter.py +140 -0
  145. titan_plugin_jira/utils/saved_queries.py +150 -0
  146. titan_plugin_jira/workflows/analyze-jira-issues.yaml +34 -0
@@ -0,0 +1,140 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Create PR with AI Workflow Preview
4
+
5
+ Preview the create-pr-ai workflow by executing real steps with mocked data.
6
+ Run: titan preview workflow create-pr-ai
7
+ """
8
+
9
+ from titan_cli.ui.components.typography import TextRenderer
10
+ from titan_cli.ui.components.spacer import SpacerRenderer
11
+ from titan_cli.engine.mock_context import (
12
+ MockGitClient,
13
+ MockAIClient,
14
+ MockGitHubClient,
15
+ MockSecretManager,
16
+ )
17
+ from titan_cli.engine import WorkflowContext
18
+ from titan_cli.engine.ui_container import UIComponents
19
+ from titan_cli.engine.views_container import UIViews
20
+ from titan_cli.engine.results import Success, Error, Skip
21
+
22
+
23
+ def create_create_pr_ai_mock_context() -> WorkflowContext:
24
+ """
25
+ Create mock context specifically for create-pr-ai workflow.
26
+
27
+ Customizes mock data to simulate the create-pr-ai workflow scenario:
28
+ - Git status with uncommitted changes
29
+ - AI generates commit message and PR description
30
+ - GitHub creates PR on feature branch
31
+
32
+ Pre-populates context data to ensure all steps execute successfully
33
+ and display their full UI in the preview.
34
+ """
35
+ # Create UI components
36
+ ui = UIComponents.create()
37
+ views = UIViews.create(ui)
38
+
39
+ # Override prompts to auto-confirm (non-interactive preview)
40
+ views.prompts.ask_confirm = lambda question, default=True: True
41
+
42
+ # Create mock clients with workflow-specific data
43
+ git = MockGitClient()
44
+ git.current_branch = "feat/workflow-preview"
45
+ git.main_branch = "master"
46
+ git.default_remote = "origin"
47
+
48
+ ai = MockAIClient()
49
+
50
+ github = MockGitHubClient()
51
+ github.repo_owner = "mockuser"
52
+ github.repo_name = "titan-cli"
53
+
54
+ secrets = MockSecretManager()
55
+
56
+ # Build context
57
+ ctx = WorkflowContext(
58
+ secrets=secrets,
59
+ ui=ui,
60
+ views=views
61
+ )
62
+
63
+ # Inject mocked clients
64
+ ctx.git = git
65
+ ctx.ai = ai
66
+ ctx.github = github
67
+
68
+ # Pre-populate initial data for complete workflow execution
69
+ # This simulates data that would come from command-line or earlier setup
70
+ ctx.set("base_branch", "master")
71
+ ctx.set("draft", False)
72
+
73
+ return ctx
74
+
75
+
76
+ def preview_workflow():
77
+ """
78
+ Preview the create-pr-ai workflow by executing real steps with mocked context.
79
+
80
+ This ensures the preview always matches the real workflow execution.
81
+ """
82
+ text = TextRenderer()
83
+ spacer = SpacerRenderer()
84
+
85
+ # Header
86
+ text.title("Create Pull Request with AI - PREVIEW")
87
+ text.subtitle("(Executing real steps with mocked data)")
88
+ spacer.line()
89
+
90
+ # Create workflow-specific mock context
91
+ ctx = create_create_pr_ai_mock_context()
92
+
93
+ # Import steps
94
+ from titan_plugin_git.steps.status_step import get_git_status_step
95
+ from titan_plugin_git.steps.ai_commit_message_step import ai_generate_commit_message
96
+ from titan_plugin_git.steps.commit_step import create_git_commit_step
97
+ from titan_plugin_git.steps.push_step import create_git_push_step
98
+ from titan_plugin_github.steps.ai_pr_step import ai_suggest_pr_description_step
99
+ from titan_plugin_github.steps.prompt_steps import prompt_for_pr_title_step, prompt_for_pr_body_step
100
+
101
+ # Execute steps in order
102
+ steps = [
103
+ ("git_status", get_git_status_step),
104
+ ("ai_commit_message", ai_generate_commit_message),
105
+ ("create_commit", create_git_commit_step),
106
+ ("push", create_git_push_step),
107
+ ("ai_pr_description", ai_suggest_pr_description_step),
108
+ ("prompt_pr_title", prompt_for_pr_title_step),
109
+ ("prompt_pr_body", prompt_for_pr_body_step),
110
+ ]
111
+
112
+ text.info("Executing workflow...")
113
+ spacer.small()
114
+
115
+ # Inject workflow metadata (like the real executor does)
116
+ ctx.workflow_name = "create-pr-ai"
117
+ ctx.total_steps = len(steps)
118
+
119
+ for i, (step_name, step_fn) in enumerate(steps, 1):
120
+ # Inject current step number (like the real executor does)
121
+ ctx.current_step = i
122
+
123
+ # Execute the step - it will handle all its own UI
124
+ result = step_fn(ctx)
125
+
126
+ # Merge metadata into context (like the real executor does)
127
+ if isinstance(result, (Success, Skip)) and result.metadata:
128
+ ctx.data.update(result.metadata)
129
+
130
+ # Only handle errors (steps handle their own success/skip UI)
131
+ if isinstance(result, Error):
132
+ text.error(f"Step '{step_name}' failed: {result.message}")
133
+ break
134
+
135
+ spacer.line()
136
+ text.info("(This was a preview - no actual git/GitHub operations were performed)")
137
+
138
+
139
+ if __name__ == "__main__":
140
+ preview_workflow()
@@ -0,0 +1,32 @@
1
+ name: "Create GitHub Issue (AI-Powered)"
2
+ description: "Create a GitHub issue with AI-generated description and auto-categorization"
3
+ params:
4
+ assignees: []
5
+ steps:
6
+ - id: prompt_for_issue_body
7
+ name: "Prompt for Issue Body"
8
+ plugin: github
9
+ step: prompt_for_issue_body_step
10
+
11
+ - id: ai_suggest_issue
12
+ name: "Categorize and Generate Issue"
13
+ plugin: github
14
+ step: ai_suggest_issue_title_and_body
15
+
16
+ - id: preview_and_confirm_issue
17
+ name: "Preview and Confirm Issue"
18
+ plugin: github
19
+ step: preview_and_confirm_issue
20
+
21
+ - id: prompt_for_self_assign
22
+ name: "Prompt for Self Assign"
23
+ plugin: github
24
+ step: prompt_for_self_assign
25
+
26
+ - id: create_issue
27
+ name: "Create Issue"
28
+ plugin: github
29
+ step: create_issue
30
+ params:
31
+ assignees: "${assignees}"
32
+ labels: "${labels}"
@@ -0,0 +1,49 @@
1
+ name: "Create Pull Request with AI"
2
+ description: "AI-powered PR creation with intelligent analysis and suggestions"
3
+
4
+ params:
5
+ draft: false
6
+
7
+ hooks:
8
+ - before_push
9
+ - after_pr
10
+
11
+ steps:
12
+ # Use the commit-ai workflow (respects project override for linting/testing)
13
+ - id: commit_changes
14
+ name: "Commit changes with AI"
15
+ workflow: "commit-ai"
16
+
17
+ - id: get_head_branch
18
+ name: "Get Head Branch"
19
+ plugin: git
20
+ step: get_current_branch
21
+
22
+ # AI generates PR title and description from branch commits
23
+ - id: ai_pr_description
24
+ name: "AI PR Description"
25
+ plugin: github
26
+ step: ai_suggest_pr_description
27
+
28
+ - hook: before_push
29
+
30
+ # Fallback to manual prompts if AI was rejected
31
+ - id: prompt_pr_title
32
+ name: "Prompt for PR Title"
33
+ plugin: github
34
+ step: prompt_for_pr_title
35
+
36
+ - id: prompt_pr_body
37
+ name: "Prompt for PR Body"
38
+ plugin: github
39
+ step: prompt_for_pr_body
40
+
41
+ - id: create_pr
42
+ name: "Create Pull Request"
43
+ plugin: github
44
+ step: create_pr
45
+ requires:
46
+ - pr_title
47
+ - pr_head_branch
48
+
49
+ - hook: after_pr
@@ -0,0 +1,8 @@
1
+ # plugins/titan-plugin-jira/titan_plugin_jira/__init__.py
2
+ """
3
+ Titan Plugin: JIRA
4
+
5
+ AI-powered JIRA integration plugin for Titan CLI.
6
+ """
7
+
8
+ __version__ = "1.0.0"
@@ -0,0 +1,6 @@
1
+ # plugins/titan-plugin-jira/titan_plugin_jira/agents/__init__.py
2
+ """AI agents for JIRA automation."""
3
+
4
+ from .jira_agent import JiraAgent, IssueAnalysis
5
+
6
+ __all__ = ["JiraAgent", "IssueAnalysis"]
@@ -0,0 +1,154 @@
1
+ # plugins/titan-plugin-jira/titan_plugin_jira/agents/config_loader.py
2
+ """Configuration loader for JIRA Agent."""
3
+
4
+ import tomli
5
+ from pathlib import Path
6
+ from typing import Optional, Dict, Any
7
+ from pydantic import BaseModel, Field, ConfigDict
8
+
9
+ try:
10
+ # Python 3.9+
11
+ from importlib.resources import files
12
+ except ImportError:
13
+ # Python 3.7-3.8 fallback
14
+ from importlib_resources import files
15
+
16
+
17
+ class JiraAgentConfig(BaseModel):
18
+ """JIRA Agent configuration loaded from TOML."""
19
+
20
+ name: str = Field(..., description="Agent name")
21
+ description: str = Field("", description="Agent description")
22
+ version: str = Field("1.0.0", description="Agent version")
23
+
24
+ # Prompts
25
+ requirements_system_prompt: str = Field("", description="System prompt for requirements analysis")
26
+ description_enhancement_prompt: str = Field("", description="System prompt for description enhancement")
27
+ comment_generation_prompt: str = Field("", description="System prompt for comment generation")
28
+ subtask_suggestion_prompt: str = Field("", description="System prompt for subtask suggestion")
29
+ smart_labeling_prompt: str = Field("", description="System prompt for smart labeling")
30
+
31
+ # Limits
32
+ max_description_length: int = Field(5000, ge=0, description="Maximum description length")
33
+ max_subtasks: int = Field(10, ge=1, description="Maximum subtasks to suggest")
34
+ max_comments_to_analyze: int = Field(20, ge=1, description="Maximum comments to analyze")
35
+ max_linked_issues: int = Field(15, ge=1, description="Maximum linked issues to consider")
36
+
37
+ # AI Parameters
38
+ temperature: float = Field(0.7, ge=0.0, le=2.0, description="AI temperature for generation")
39
+ max_tokens: int = Field(2000, ge=1, description="Maximum tokens per AI request")
40
+
41
+ # Features (Active)
42
+ enable_requirement_extraction: bool = Field(True, description="Enable requirement extraction")
43
+ enable_subtasks: bool = Field(True, description="Enable subtask suggestion")
44
+ enable_risk_analysis: bool = Field(True, description="Enable risk analysis")
45
+ enable_dependency_detection: bool = Field(True, description="Enable dependency detection")
46
+ enable_acceptance_criteria: bool = Field(True, description="Enable acceptance criteria generation")
47
+ enable_debug_output: bool = Field(False, description="Enable debug output (logs AI responses)")
48
+
49
+ # Features (Planned - Not Yet Implemented)
50
+ # These flags are reserved for future functionality
51
+ # TODO: Implement Gherkin test generation (PR #74 comment: remove unused flags)
52
+ # enable_gherkin_tests: bool = Field(False, description="Enable Gherkin/BDD test scenario generation")
53
+ # TODO: Implement strict label classification
54
+ # enable_strict_labeling: bool = Field(False, description="Enable strict label classification")
55
+ # TODO: Implement token optimization strategies
56
+ # enable_token_saving: bool = Field(False, description="Enable token optimization strategies")
57
+
58
+ # Formatting
59
+ template: str = Field("", description="Optional Jinja2 template filename for formatting output")
60
+
61
+ # Raw config for custom access
62
+ raw: Dict[str, Any] = Field(default_factory=dict, description="Raw TOML data")
63
+
64
+ model_config = ConfigDict(frozen=False) # Allow mutation for caching
65
+
66
+
67
+ def load_agent_config(
68
+ agent_name: str = "jira_agent",
69
+ config_dir: Optional[Path] = None
70
+ ) -> JiraAgentConfig:
71
+ """
72
+ Load agent configuration from TOML file.
73
+
74
+ Args:
75
+ agent_name: Name of the agent (e.g., "jira_agent")
76
+ config_dir: Optional custom config directory
77
+
78
+ Returns:
79
+ JiraAgentConfig instance
80
+
81
+ Raises:
82
+ FileNotFoundError: If config file doesn't exist
83
+ ValueError: If config is invalid
84
+ """
85
+ # Determine config file path
86
+ if config_dir:
87
+ config_path = config_dir / f"{agent_name}.toml"
88
+ else:
89
+ # Use importlib.resources for robust path resolution
90
+ config_files = files("titan_plugin_jira.config")
91
+ config_file = config_files.joinpath(f"{agent_name}.toml")
92
+
93
+ # Convert Traversable to Path
94
+ if hasattr(config_file, "__fspath__"):
95
+ config_path = Path(config_file.__fspath__())
96
+ else:
97
+ config_path = Path(str(config_file))
98
+
99
+ if not config_path.exists():
100
+ raise FileNotFoundError(f"Agent config not found: {config_path}")
101
+
102
+ # Load TOML
103
+ try:
104
+ with open(config_path, "rb") as f:
105
+ data = tomli.load(f)
106
+ except tomli.TOMLDecodeError as e:
107
+ raise ValueError(f"Invalid TOML in {config_path}: {e}")
108
+ except Exception as e:
109
+ raise ValueError(f"Failed to read config {config_path}: {e}")
110
+
111
+ # Validate config structure
112
+ if "agent" not in data:
113
+ raise ValueError(f"Missing [agent] section in {config_path}")
114
+
115
+ # Extract sections
116
+ agent_meta = data.get("agent", {})
117
+ prompts = data.get("agent", {}).get("prompts", {})
118
+ limits = data.get("agent", {}).get("limits", {})
119
+ features = data.get("agent", {}).get("features", {})
120
+ formatting = data.get("agent", {}).get("formatting", {})
121
+
122
+ # Build JiraAgentConfig
123
+ return JiraAgentConfig(
124
+ name=agent_meta.get("name", agent_name),
125
+ description=agent_meta.get("description", ""),
126
+ version=agent_meta.get("version", "1.0.0"),
127
+ # Prompts
128
+ requirements_system_prompt=prompts.get("requirements_analysis", {}).get("system", ""),
129
+ description_enhancement_prompt=prompts.get("description_enhancement", {}).get("system", ""),
130
+ comment_generation_prompt=prompts.get("comment_generation", {}).get("system", ""),
131
+ subtask_suggestion_prompt=prompts.get("subtask_suggestion", {}).get("system", ""),
132
+ smart_labeling_prompt=prompts.get("smart_labeling", {}).get("system", ""),
133
+ # Limits
134
+ max_description_length=limits.get("max_description_length", 5000),
135
+ max_subtasks=limits.get("max_subtasks", 10),
136
+ max_comments_to_analyze=limits.get("max_comments_to_analyze", 20),
137
+ max_linked_issues=limits.get("max_linked_issues", 15),
138
+ # AI Parameters
139
+ temperature=limits.get("temperature", agent_meta.get("temperature", 0.7)),
140
+ max_tokens=limits.get("max_tokens", agent_meta.get("max_tokens", 2000)),
141
+ # Features (Active)
142
+ enable_requirement_extraction=features.get("enable_requirement_extraction", True),
143
+ enable_subtasks=features.get("enable_subtasks", True),
144
+ enable_risk_analysis=features.get("enable_risk_analysis", True),
145
+ enable_dependency_detection=features.get("enable_dependency_detection", True),
146
+ enable_acceptance_criteria=features.get("enable_acceptance_criteria", True),
147
+ enable_debug_output=features.get("enable_debug_output", False),
148
+ # Note: Removed unused flags (enable_gherkin_tests, enable_strict_labeling, enable_token_saving)
149
+ # These will be added back when functionality is implemented
150
+ # Formatting
151
+ template=formatting.get("template", ""),
152
+ # Raw for custom access
153
+ raw=data
154
+ )