aiagent-runner 0.1.1__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.
@@ -0,0 +1,47 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+
27
+ # Virtual environments
28
+ .venv/
29
+ venv/
30
+ ENV/
31
+
32
+ # Testing
33
+ .coverage
34
+ .pytest_cache/
35
+ htmlcov/
36
+ .tox/
37
+ .nox/
38
+
39
+ # IDE
40
+ .idea/
41
+ .vscode/
42
+ *.swp
43
+ *.swo
44
+
45
+ # Logs
46
+ logs/
47
+ *.log
@@ -0,0 +1,148 @@
1
+ Metadata-Version: 2.4
2
+ Name: aiagent-runner
3
+ Version: 0.1.1
4
+ Summary: Runner for AI Agent PM - executes tasks via MCP and CLI
5
+ Author: AI Agent PM Team
6
+ License-Expression: MIT
7
+ Keywords: agent,ai,automation,mcp,orchestration,task-management
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Requires-Python: >=3.9
18
+ Requires-Dist: pyyaml>=6.0
19
+ Provides-Extra: dev
20
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
21
+ Requires-Dist: pytest-cov>=4.1; extra == 'dev'
22
+ Requires-Dist: pytest>=8.0; extra == 'dev'
23
+ Description-Content-Type: text/markdown
24
+
25
+ # AI Agent PM Coordinator
26
+
27
+ 全エージェントのタスク実行を統合管理するオーケストレーションデーモン。
28
+
29
+ ---
30
+
31
+ ## クイックスタート
32
+
33
+ ```bash
34
+ cd runner
35
+ pip install -e .
36
+
37
+ # デフォルト設定で起動(config/coordinator_default.yaml を使用)
38
+ python -m aiagent_runner --coordinator
39
+ ```
40
+
41
+ ---
42
+
43
+ ## Coordinatorモード(推奨)
44
+
45
+ 単一のCoordinatorが全ての(agent_id, project_id)ペアを管理します。
46
+
47
+ ### 基本起動
48
+
49
+ ```bash
50
+ # デフォルト設定で起動
51
+ python -m aiagent_runner --coordinator
52
+
53
+ # 詳細ログ出力
54
+ python -m aiagent_runner --coordinator -v
55
+ ```
56
+
57
+ ### カスタム設定ファイル
58
+
59
+ ```bash
60
+ python -m aiagent_runner --coordinator -c /path/to/config.yaml
61
+ ```
62
+
63
+ ### 設定ファイル例
64
+
65
+ ```yaml
66
+ # config/coordinator_default.yaml がデフォルトで読み込まれます
67
+ # カスタム設定で上書き可能
68
+
69
+ polling_interval: 10
70
+ max_concurrent: 3
71
+
72
+ # MCP server configuration (Agent Instance用)
73
+ mcp_server_command: /path/to/mcp-server-pm
74
+ mcp_database_path: /path/to/database.db
75
+
76
+ # AI providers
77
+ ai_providers:
78
+ claude:
79
+ cli_command: claude
80
+ cli_args:
81
+ - "--dangerously-skip-permissions"
82
+ - "--max-turns"
83
+ - "50"
84
+
85
+ # Agents (passkeyのみ - ai_type等はMCPから取得)
86
+ agents:
87
+ agt_developer:
88
+ passkey: secret123
89
+ agt_reviewer:
90
+ passkey: ${REVIEWER_PASSKEY} # 環境変数展開対応
91
+
92
+ log_directory: /tmp/coordinator_logs
93
+ ```
94
+
95
+ ### バックグラウンド実行
96
+
97
+ ```bash
98
+ nohup python -m aiagent_runner --coordinator -v > coordinator.log 2>&1 &
99
+ ```
100
+
101
+ ---
102
+
103
+ ## 設定の優先順位
104
+
105
+ 1. **コマンドライン引数** (`--polling-interval` 等)
106
+ 2. **指定した設定ファイル** (`-c /path/to/config.yaml`)
107
+ 3. **デフォルト設定** (`runner/config/coordinator_default.yaml`)
108
+ 4. **組み込みデフォルト値**
109
+
110
+ ---
111
+
112
+ ## 動作フロー
113
+
114
+ 1. MCPサーバーに接続(Unixソケット)
115
+ 2. `list_active_projects_with_agents()` で全プロジェクト・エージェントを取得
116
+ 3. 各(agent_id, project_id)ペアに対して `should_start()` を呼び出し
117
+ 4. 作業が必要な場合、Agent Instance(Claude CLI等)をスポーン
118
+ 5. Agent Instanceが `authenticate` → `get_my_task` → 実行 → `report_completed`
119
+ 6. 待機して2に戻る
120
+
121
+ ---
122
+
123
+ ## 前提条件
124
+
125
+ - MCPサーバーが起動していること
126
+ - エージェントがアプリで登録済みで、passkeyが設定されていること
127
+ - 該当エージェントがプロジェクトに割り当てられていること
128
+ - タスクが `in_progress` ステータスであること
129
+
130
+ ---
131
+
132
+ ## Legacy Runnerモード(非推奨)
133
+
134
+ 1エージェント = 1デーモン の旧アーキテクチャ。
135
+
136
+ ```bash
137
+ # 非推奨: Coordinatorモードを使用してください
138
+ aiagent-runner --agent-id <AGENT_ID> --passkey <PASSKEY> --project-id <PROJECT_ID>
139
+ ```
140
+
141
+ ---
142
+
143
+ ## 開発
144
+
145
+ ```bash
146
+ pip install -e ".[dev]"
147
+ pytest
148
+ ```
@@ -0,0 +1,8 @@
1
+ 451f1656bb31ff63
2
+ b54f42bd24f0408c
3
+ a04e46d8c63c69e4
4
+ 77583aa829569de1
5
+ a981dae769dc06b6
6
+ 7de76ea4637fa972
7
+ c12dd9e50e39392d
8
+ c33e519d5d61d312
@@ -0,0 +1,124 @@
1
+ # AI Agent PM Coordinator
2
+
3
+ 全エージェントのタスク実行を統合管理するオーケストレーションデーモン。
4
+
5
+ ---
6
+
7
+ ## クイックスタート
8
+
9
+ ```bash
10
+ cd runner
11
+ pip install -e .
12
+
13
+ # デフォルト設定で起動(config/coordinator_default.yaml を使用)
14
+ python -m aiagent_runner --coordinator
15
+ ```
16
+
17
+ ---
18
+
19
+ ## Coordinatorモード(推奨)
20
+
21
+ 単一のCoordinatorが全ての(agent_id, project_id)ペアを管理します。
22
+
23
+ ### 基本起動
24
+
25
+ ```bash
26
+ # デフォルト設定で起動
27
+ python -m aiagent_runner --coordinator
28
+
29
+ # 詳細ログ出力
30
+ python -m aiagent_runner --coordinator -v
31
+ ```
32
+
33
+ ### カスタム設定ファイル
34
+
35
+ ```bash
36
+ python -m aiagent_runner --coordinator -c /path/to/config.yaml
37
+ ```
38
+
39
+ ### 設定ファイル例
40
+
41
+ ```yaml
42
+ # config/coordinator_default.yaml がデフォルトで読み込まれます
43
+ # カスタム設定で上書き可能
44
+
45
+ polling_interval: 10
46
+ max_concurrent: 3
47
+
48
+ # MCP server configuration (Agent Instance用)
49
+ mcp_server_command: /path/to/mcp-server-pm
50
+ mcp_database_path: /path/to/database.db
51
+
52
+ # AI providers
53
+ ai_providers:
54
+ claude:
55
+ cli_command: claude
56
+ cli_args:
57
+ - "--dangerously-skip-permissions"
58
+ - "--max-turns"
59
+ - "50"
60
+
61
+ # Agents (passkeyのみ - ai_type等はMCPから取得)
62
+ agents:
63
+ agt_developer:
64
+ passkey: secret123
65
+ agt_reviewer:
66
+ passkey: ${REVIEWER_PASSKEY} # 環境変数展開対応
67
+
68
+ log_directory: /tmp/coordinator_logs
69
+ ```
70
+
71
+ ### バックグラウンド実行
72
+
73
+ ```bash
74
+ nohup python -m aiagent_runner --coordinator -v > coordinator.log 2>&1 &
75
+ ```
76
+
77
+ ---
78
+
79
+ ## 設定の優先順位
80
+
81
+ 1. **コマンドライン引数** (`--polling-interval` 等)
82
+ 2. **指定した設定ファイル** (`-c /path/to/config.yaml`)
83
+ 3. **デフォルト設定** (`runner/config/coordinator_default.yaml`)
84
+ 4. **組み込みデフォルト値**
85
+
86
+ ---
87
+
88
+ ## 動作フロー
89
+
90
+ 1. MCPサーバーに接続(Unixソケット)
91
+ 2. `list_active_projects_with_agents()` で全プロジェクト・エージェントを取得
92
+ 3. 各(agent_id, project_id)ペアに対して `should_start()` を呼び出し
93
+ 4. 作業が必要な場合、Agent Instance(Claude CLI等)をスポーン
94
+ 5. Agent Instanceが `authenticate` → `get_my_task` → 実行 → `report_completed`
95
+ 6. 待機して2に戻る
96
+
97
+ ---
98
+
99
+ ## 前提条件
100
+
101
+ - MCPサーバーが起動していること
102
+ - エージェントがアプリで登録済みで、passkeyが設定されていること
103
+ - 該当エージェントがプロジェクトに割り当てられていること
104
+ - タスクが `in_progress` ステータスであること
105
+
106
+ ---
107
+
108
+ ## Legacy Runnerモード(非推奨)
109
+
110
+ 1エージェント = 1デーモン の旧アーキテクチャ。
111
+
112
+ ```bash
113
+ # 非推奨: Coordinatorモードを使用してください
114
+ aiagent-runner --agent-id <AGENT_ID> --passkey <PASSKEY> --project-id <PROJECT_ID>
115
+ ```
116
+
117
+ ---
118
+
119
+ ## 開発
120
+
121
+ ```bash
122
+ pip install -e ".[dev]"
123
+ pytest
124
+ ```
@@ -0,0 +1,28 @@
1
+ # AI Agent PM Coordinator - Default Configuration
2
+ # このファイルはデフォルト設定を定義します
3
+ # テスト時は -c オプションで上書き可能
4
+
5
+ # Polling settings
6
+ polling_interval: 10
7
+ max_concurrent: 3
8
+
9
+ # MCP connection (default socket path)
10
+ # mcp_socket_path: ~/Library/Application Support/AIAgentPM/mcp.sock
11
+
12
+ # AI providers - how to launch each AI type
13
+ ai_providers:
14
+ claude:
15
+ cli_command: claude
16
+ cli_args:
17
+ - "--dangerously-skip-permissions"
18
+ - "--max-turns"
19
+ - "50"
20
+
21
+ # Agents configuration
22
+ # 本番環境では環境変数または別ファイルでpasskeyを管理
23
+ # agents:
24
+ # agt_example:
25
+ # passkey: ${AGENT_PASSKEY}
26
+
27
+ # Logging (optional)
28
+ # log_directory: /tmp/coordinator_logs
@@ -0,0 +1,46 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "aiagent-runner"
7
+ version = "0.1.1"
8
+ description = "Runner for AI Agent PM - executes tasks via MCP and CLI"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = "MIT"
12
+ authors = [
13
+ { name = "AI Agent PM Team" }
14
+ ]
15
+ keywords = ["ai", "agent", "mcp", "automation", "task-management", "orchestration"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Environment :: Console",
19
+ "Intended Audience :: Developers",
20
+ "License :: OSI Approved :: MIT License",
21
+ "Operating System :: OS Independent",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Topic :: Software Development :: Libraries :: Python Modules",
26
+ ]
27
+ dependencies = [
28
+ "pyyaml>=6.0",
29
+ ]
30
+
31
+ [project.optional-dependencies]
32
+ dev = [
33
+ "pytest>=8.0",
34
+ "pytest-asyncio>=0.23",
35
+ "pytest-cov>=4.1",
36
+ ]
37
+
38
+ [project.scripts]
39
+ aiagent-runner = "aiagent_runner.__main__:main"
40
+
41
+ [tool.hatch.build.targets.wheel]
42
+ packages = ["src/aiagent_runner"]
43
+
44
+ [tool.pytest.ini_options]
45
+ asyncio_mode = "auto"
46
+ testpaths = ["tests"]
@@ -0,0 +1,9 @@
1
+ # aiagent_runner - Runner for AI Agent PM
2
+ # Executes tasks via MCP protocol and CLI tools (claude, gemini, etc.)
3
+
4
+ __version__ = "0.1.0"
5
+
6
+ from aiagent_runner.config import RunnerConfig
7
+ from aiagent_runner.runner import Runner, run, run_async
8
+
9
+ __all__ = ["RunnerConfig", "Runner", "run", "run_async", "__version__"]
@@ -0,0 +1,282 @@
1
+ # src/aiagent_runner/__main__.py
2
+ # Entry point for AI Agent PM Runner/Coordinator
3
+ # Reference: docs/plan/PHASE3_PULL_ARCHITECTURE.md - Phase 3-5 (legacy Runner)
4
+ # Reference: docs/plan/PHASE4_COORDINATOR_ARCHITECTURE.md (Coordinator)
5
+
6
+ import argparse
7
+ import logging
8
+ import sys
9
+ from pathlib import Path
10
+
11
+ from aiagent_runner.config import RunnerConfig
12
+ from aiagent_runner.coordinator import run_coordinator
13
+ from aiagent_runner.coordinator_config import CoordinatorConfig
14
+ from aiagent_runner.runner import run
15
+
16
+
17
+ def setup_logging(verbose: bool = False) -> None:
18
+ """Configure logging.
19
+
20
+ Args:
21
+ verbose: If True, enable debug logging
22
+ """
23
+ level = logging.DEBUG if verbose else logging.INFO
24
+ logging.basicConfig(
25
+ level=level,
26
+ format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
27
+ datefmt="%Y-%m-%d %H:%M:%S"
28
+ )
29
+
30
+
31
+ def parse_args() -> argparse.Namespace:
32
+ """Parse command line arguments.
33
+
34
+ Returns:
35
+ Parsed arguments
36
+ """
37
+ parser = argparse.ArgumentParser(
38
+ prog="aiagent-runner",
39
+ description="Runner/Coordinator for AI Agent PM - executes tasks via MCP and CLI"
40
+ )
41
+
42
+ # Mode selection
43
+ parser.add_argument(
44
+ "--coordinator",
45
+ action="store_true",
46
+ help="Run in Coordinator mode (Phase 4: single orchestrator for all agents)"
47
+ )
48
+
49
+ # Common arguments
50
+ parser.add_argument(
51
+ "-c", "--config",
52
+ type=Path,
53
+ help="Path to YAML configuration file"
54
+ )
55
+ parser.add_argument(
56
+ "-v", "--verbose",
57
+ action="store_true",
58
+ help="Enable verbose (debug) logging"
59
+ )
60
+
61
+ # Legacy Runner arguments (deprecated, use Coordinator mode instead)
62
+ parser.add_argument(
63
+ "--agent-id",
64
+ help="[Legacy Runner] Agent ID (overrides config/env)"
65
+ )
66
+ parser.add_argument(
67
+ "--passkey",
68
+ help="[Legacy Runner] Agent passkey (overrides config/env)"
69
+ )
70
+ parser.add_argument(
71
+ "--project-id",
72
+ help="[Legacy Runner] Project ID (Phase 4 required)"
73
+ )
74
+ parser.add_argument(
75
+ "--polling-interval",
76
+ type=int,
77
+ help="Polling interval in seconds (default: 5 for Runner, 10 for Coordinator)"
78
+ )
79
+ parser.add_argument(
80
+ "--cli-command",
81
+ help="[Legacy Runner] CLI command to use (default: claude)"
82
+ )
83
+ parser.add_argument(
84
+ "--working-directory",
85
+ type=Path,
86
+ help="[Legacy Runner] Working directory for CLI execution"
87
+ )
88
+ parser.add_argument(
89
+ "--log-directory",
90
+ type=Path,
91
+ help="Directory for execution logs"
92
+ )
93
+
94
+ return parser.parse_args()
95
+
96
+
97
+ def load_runner_config(args: argparse.Namespace) -> RunnerConfig:
98
+ """Load configuration for legacy Runner mode.
99
+
100
+ Priority (highest to lowest):
101
+ 1. CLI arguments
102
+ 2. Config file
103
+ 3. Environment variables
104
+
105
+ Args:
106
+ args: Parsed CLI arguments
107
+
108
+ Returns:
109
+ RunnerConfig instance
110
+ """
111
+ # Start with config file or environment
112
+ if args.config and args.config.exists():
113
+ config = RunnerConfig.from_yaml(args.config)
114
+ else:
115
+ try:
116
+ config = RunnerConfig.from_env()
117
+ except ValueError as e:
118
+ # If no config file and env vars missing, check CLI args
119
+ if args.agent_id and args.passkey and args.project_id:
120
+ config = RunnerConfig(
121
+ agent_id=args.agent_id,
122
+ passkey=args.passkey,
123
+ project_id=args.project_id
124
+ )
125
+ else:
126
+ raise e
127
+
128
+ # Override with CLI arguments
129
+ if args.agent_id:
130
+ config.agent_id = args.agent_id
131
+ if args.passkey:
132
+ config.passkey = args.passkey
133
+ if args.project_id:
134
+ config.project_id = args.project_id
135
+ if args.polling_interval:
136
+ config.polling_interval = args.polling_interval
137
+ if args.cli_command:
138
+ config.cli_command = args.cli_command
139
+ if args.working_directory:
140
+ config.working_directory = str(args.working_directory)
141
+ if args.log_directory:
142
+ config.log_directory = str(args.log_directory)
143
+
144
+ return config
145
+
146
+
147
+ def get_default_config_path() -> Path:
148
+ """Get the default configuration file path.
149
+
150
+ The default config is located at:
151
+ runner/config/coordinator_default.yaml
152
+
153
+ Returns:
154
+ Path to default config file
155
+ """
156
+ # Find the runner package root (where config/ directory is)
157
+ # __file__ is runner/src/aiagent_runner/__main__.py
158
+ # parent = runner/src/aiagent_runner/
159
+ # parent.parent = runner/src/
160
+ # parent.parent.parent = runner/
161
+ runner_root = Path(__file__).parent.parent.parent
162
+ return runner_root / "config" / "coordinator_default.yaml"
163
+
164
+
165
+ def load_coordinator_config(args: argparse.Namespace) -> CoordinatorConfig:
166
+ """Load configuration for Coordinator mode.
167
+
168
+ Configuration loading priority:
169
+ 1. User-specified config file (-c/--config) - full override
170
+ 2. Default config file (runner/config/coordinator_default.yaml)
171
+
172
+ Note: When using default config, agents must be configured via
173
+ environment variables or a separate config file.
174
+
175
+ Args:
176
+ args: Parsed CLI arguments
177
+
178
+ Returns:
179
+ CoordinatorConfig instance
180
+ """
181
+ logger = logging.getLogger(__name__)
182
+
183
+ if args.config and args.config.exists():
184
+ # User specified a config file - use it directly
185
+ logger.info(f"Loading config from: {args.config}")
186
+ config = CoordinatorConfig.from_yaml(args.config)
187
+ else:
188
+ # Try to load default config
189
+ default_config_path = get_default_config_path()
190
+ if default_config_path.exists():
191
+ logger.info(f"Loading default config from: {default_config_path}")
192
+ config = CoordinatorConfig.from_yaml(default_config_path)
193
+ else:
194
+ # No config available - use built-in defaults
195
+ logger.warning(
196
+ "No config file found. Using built-in defaults.\n"
197
+ f"Expected default config at: {default_config_path}\n"
198
+ "Note: Agents must be configured to run tasks."
199
+ )
200
+ config = CoordinatorConfig()
201
+
202
+ # Override with CLI arguments
203
+ if args.polling_interval:
204
+ config.polling_interval = args.polling_interval
205
+ if args.log_directory:
206
+ config.log_directory = str(args.log_directory)
207
+
208
+ return config
209
+
210
+
211
+ def main() -> int:
212
+ """Main entry point.
213
+
214
+ Returns:
215
+ Exit code (0 for success)
216
+ """
217
+ args = parse_args()
218
+ setup_logging(args.verbose)
219
+
220
+ logger = logging.getLogger(__name__)
221
+
222
+ if args.coordinator:
223
+ # Phase 4: Coordinator mode
224
+ logger.info("Running in Coordinator mode (Phase 4)")
225
+ try:
226
+ config = load_coordinator_config(args)
227
+ except ValueError as e:
228
+ logger.error(f"Configuration error: {e}")
229
+ print(f"Error: {e}", file=sys.stderr)
230
+ return 1
231
+
232
+ logger.info(f"Configured agents: {list(config.agents.keys())}")
233
+ logger.info(f"Polling interval: {config.polling_interval}s")
234
+ logger.info(f"Max concurrent: {config.max_concurrent}")
235
+
236
+ try:
237
+ run_coordinator(config)
238
+ except KeyboardInterrupt:
239
+ logger.info("Coordinator stopped by user")
240
+ return 0
241
+ except Exception as e:
242
+ logger.exception(f"Coordinator failed: {e}")
243
+ return 1
244
+ else:
245
+ # Legacy Runner mode (deprecated)
246
+ logger.warning(
247
+ "Running in legacy Runner mode. "
248
+ "Consider using --coordinator mode for Phase 4 architecture."
249
+ )
250
+ try:
251
+ config = load_runner_config(args)
252
+ except ValueError as e:
253
+ logger.error(f"Configuration error: {e}")
254
+ print(f"Error: {e}", file=sys.stderr)
255
+ print(
256
+ "\nProvide configuration via:\n"
257
+ " 1. YAML config file (-c/--config)\n"
258
+ " 2. Environment variables (AGENT_ID, AGENT_PASSKEY, PROJECT_ID)\n"
259
+ " 3. CLI arguments (--agent-id, --passkey, --project-id)",
260
+ file=sys.stderr
261
+ )
262
+ return 1
263
+
264
+ logger.info(f"Starting runner for agent: {config.agent_id}")
265
+ logger.info(f"Project: {config.project_id}")
266
+ logger.info(f"CLI command: {config.cli_command}")
267
+ logger.info(f"Polling interval: {config.polling_interval}s")
268
+
269
+ try:
270
+ run(config)
271
+ except KeyboardInterrupt:
272
+ logger.info("Runner stopped by user")
273
+ return 0
274
+ except Exception as e:
275
+ logger.exception(f"Runner failed: {e}")
276
+ return 1
277
+
278
+ return 0
279
+
280
+
281
+ if __name__ == "__main__":
282
+ sys.exit(main())