monoco-toolkit 0.3.10__py3-none-any.whl → 0.3.12__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.
- monoco/__main__.py +8 -0
- monoco/core/artifacts/__init__.py +16 -0
- monoco/core/artifacts/manager.py +575 -0
- monoco/core/artifacts/models.py +161 -0
- monoco/core/automation/__init__.py +51 -0
- monoco/core/automation/config.py +338 -0
- monoco/core/automation/field_watcher.py +296 -0
- monoco/core/automation/handlers.py +723 -0
- monoco/core/config.py +31 -4
- monoco/core/executor/__init__.py +38 -0
- monoco/core/executor/agent_action.py +254 -0
- monoco/core/executor/git_action.py +303 -0
- monoco/core/executor/im_action.py +309 -0
- monoco/core/executor/pytest_action.py +218 -0
- monoco/core/git.py +38 -0
- monoco/core/hooks/context.py +74 -13
- monoco/core/ingestion/__init__.py +20 -0
- monoco/core/ingestion/discovery.py +248 -0
- monoco/core/ingestion/watcher.py +343 -0
- monoco/core/ingestion/worker.py +436 -0
- monoco/core/loader.py +633 -0
- monoco/core/registry.py +34 -25
- monoco/core/router/__init__.py +55 -0
- monoco/core/router/action.py +341 -0
- monoco/core/router/router.py +392 -0
- monoco/core/scheduler/__init__.py +63 -0
- monoco/core/scheduler/base.py +152 -0
- monoco/core/scheduler/engines.py +175 -0
- monoco/core/scheduler/events.py +171 -0
- monoco/core/scheduler/local.py +377 -0
- monoco/core/skills.py +119 -80
- monoco/core/watcher/__init__.py +57 -0
- monoco/core/watcher/base.py +365 -0
- monoco/core/watcher/dropzone.py +152 -0
- monoco/core/watcher/issue.py +303 -0
- monoco/core/watcher/memo.py +200 -0
- monoco/core/watcher/task.py +238 -0
- monoco/daemon/app.py +77 -1
- monoco/daemon/commands.py +10 -0
- monoco/daemon/events.py +34 -0
- monoco/daemon/mailroom_service.py +196 -0
- monoco/daemon/models.py +1 -0
- monoco/daemon/scheduler.py +207 -0
- monoco/daemon/services.py +27 -58
- monoco/daemon/triggers.py +55 -0
- monoco/features/agent/__init__.py +25 -7
- monoco/features/agent/adapter.py +17 -7
- monoco/features/agent/cli.py +91 -57
- monoco/features/agent/engines.py +31 -170
- monoco/{core/resources/en/skills/monoco_core → features/agent/resources/en/skills/monoco_atom_core}/SKILL.md +2 -2
- monoco/features/agent/resources/en/skills/{flow_engineer → monoco_workflow_agent_engineer}/SKILL.md +2 -2
- monoco/features/agent/resources/en/skills/{flow_manager → monoco_workflow_agent_manager}/SKILL.md +2 -2
- monoco/features/agent/resources/en/skills/{flow_planner → monoco_workflow_agent_planner}/SKILL.md +2 -2
- monoco/features/agent/resources/en/skills/{flow_reviewer → monoco_workflow_agent_reviewer}/SKILL.md +2 -2
- monoco/features/agent/resources/{roles/role-engineer.yaml → zh/roles/monoco_role_engineer.yaml} +3 -3
- monoco/features/agent/resources/{roles/role-manager.yaml → zh/roles/monoco_role_manager.yaml} +8 -8
- monoco/features/agent/resources/{roles/role-planner.yaml → zh/roles/monoco_role_planner.yaml} +8 -8
- monoco/features/agent/resources/{roles/role-reviewer.yaml → zh/roles/monoco_role_reviewer.yaml} +8 -8
- monoco/{core/resources/zh/skills/monoco_core → features/agent/resources/zh/skills/monoco_atom_core}/SKILL.md +2 -2
- monoco/features/agent/resources/zh/skills/{flow_engineer → monoco_workflow_agent_engineer}/SKILL.md +2 -2
- monoco/features/agent/resources/zh/skills/{flow_manager → monoco_workflow_agent_manager}/SKILL.md +2 -2
- monoco/features/agent/resources/zh/skills/{flow_planner → monoco_workflow_agent_planner}/SKILL.md +2 -2
- monoco/features/agent/resources/zh/skills/{flow_reviewer → monoco_workflow_agent_reviewer}/SKILL.md +2 -2
- monoco/features/agent/worker.py +1 -1
- monoco/features/artifact/__init__.py +0 -0
- monoco/features/artifact/adapter.py +33 -0
- monoco/features/artifact/resources/zh/AGENTS.md +14 -0
- monoco/features/artifact/resources/zh/skills/monoco_atom_artifact/SKILL.md +278 -0
- monoco/features/glossary/adapter.py +18 -7
- monoco/features/glossary/resources/en/skills/{monoco_glossary → monoco_atom_glossary}/SKILL.md +2 -2
- monoco/features/glossary/resources/zh/skills/{monoco_glossary → monoco_atom_glossary}/SKILL.md +2 -2
- monoco/features/hooks/__init__.py +11 -0
- monoco/features/hooks/adapter.py +67 -0
- monoco/features/hooks/commands.py +309 -0
- monoco/features/hooks/core.py +441 -0
- monoco/features/hooks/resources/ADDING_HOOKS.md +234 -0
- monoco/features/i18n/adapter.py +18 -5
- monoco/features/i18n/core.py +482 -17
- monoco/features/i18n/resources/en/skills/{monoco_i18n → monoco_atom_i18n}/SKILL.md +2 -2
- monoco/features/i18n/resources/en/skills/{i18n_scan_workflow → monoco_workflow_i18n_scan}/SKILL.md +2 -2
- monoco/features/i18n/resources/zh/skills/{monoco_i18n → monoco_atom_i18n}/SKILL.md +2 -2
- monoco/features/i18n/resources/zh/skills/{i18n_scan_workflow → monoco_workflow_i18n_scan}/SKILL.md +2 -2
- monoco/features/issue/adapter.py +19 -6
- monoco/features/issue/commands.py +352 -20
- monoco/features/issue/core.py +475 -16
- monoco/features/issue/engine/machine.py +114 -4
- monoco/features/issue/linter.py +60 -5
- monoco/features/issue/models.py +2 -2
- monoco/features/issue/resources/en/AGENTS.md +109 -0
- monoco/features/issue/resources/en/skills/{monoco_issue → monoco_atom_issue}/SKILL.md +2 -2
- monoco/features/issue/resources/en/skills/{issue_create_workflow → monoco_workflow_issue_creation}/SKILL.md +2 -2
- monoco/features/issue/resources/en/skills/{issue_develop_workflow → monoco_workflow_issue_development}/SKILL.md +2 -2
- monoco/features/issue/resources/en/skills/{issue_lifecycle_workflow → monoco_workflow_issue_management}/SKILL.md +2 -2
- monoco/features/issue/resources/en/skills/{issue_refine_workflow → monoco_workflow_issue_refinement}/SKILL.md +2 -2
- monoco/features/issue/resources/hooks/post-checkout.sh +39 -0
- monoco/features/issue/resources/hooks/pre-commit.sh +41 -0
- monoco/features/issue/resources/hooks/pre-push.sh +35 -0
- monoco/features/issue/resources/zh/AGENTS.md +109 -0
- monoco/features/issue/resources/zh/skills/{monoco_issue → monoco_atom_issue_lifecycle}/SKILL.md +2 -2
- monoco/features/issue/resources/zh/skills/{issue_create_workflow → monoco_workflow_issue_creation}/SKILL.md +2 -2
- monoco/features/issue/resources/zh/skills/{issue_develop_workflow → monoco_workflow_issue_development}/SKILL.md +2 -2
- monoco/features/issue/resources/zh/skills/{issue_lifecycle_workflow → monoco_workflow_issue_management}/SKILL.md +2 -2
- monoco/features/issue/resources/zh/skills/{issue_refine_workflow → monoco_workflow_issue_refinement}/SKILL.md +2 -2
- monoco/features/issue/validator.py +101 -1
- monoco/features/memo/adapter.py +21 -8
- monoco/features/memo/cli.py +103 -10
- monoco/features/memo/core.py +178 -92
- monoco/features/memo/models.py +53 -0
- monoco/features/memo/resources/en/skills/{monoco_memo → monoco_atom_memo}/SKILL.md +2 -2
- monoco/features/memo/resources/en/skills/{note_processing_workflow → monoco_workflow_note_processing}/SKILL.md +2 -2
- monoco/features/memo/resources/zh/skills/{monoco_memo → monoco_atom_memo}/SKILL.md +2 -2
- monoco/features/memo/resources/zh/skills/{note_processing_workflow → monoco_workflow_note_processing}/SKILL.md +2 -2
- monoco/features/spike/adapter.py +18 -5
- monoco/features/spike/commands.py +5 -3
- monoco/features/spike/resources/en/skills/{monoco_spike → monoco_atom_spike}/SKILL.md +2 -2
- monoco/features/spike/resources/en/skills/{research_workflow → monoco_workflow_research}/SKILL.md +2 -2
- monoco/features/spike/resources/zh/skills/{monoco_spike → monoco_atom_spike}/SKILL.md +2 -2
- monoco/features/spike/resources/zh/skills/{research_workflow → monoco_workflow_research}/SKILL.md +2 -2
- monoco/main.py +38 -1
- {monoco_toolkit-0.3.10.dist-info → monoco_toolkit-0.3.12.dist-info}/METADATA +7 -1
- monoco_toolkit-0.3.12.dist-info/RECORD +202 -0
- monoco/features/agent/apoptosis.py +0 -44
- monoco/features/agent/manager.py +0 -91
- monoco/features/agent/session.py +0 -121
- monoco_toolkit-0.3.10.dist-info/RECORD +0 -156
- /monoco/{core → features/agent}/resources/en/AGENTS.md +0 -0
- /monoco/{core → features/agent}/resources/zh/AGENTS.md +0 -0
- {monoco_toolkit-0.3.10.dist-info → monoco_toolkit-0.3.12.dist-info}/WHEEL +0 -0
- {monoco_toolkit-0.3.10.dist-info → monoco_toolkit-0.3.12.dist-info}/entry_points.txt +0 -0
- {monoco_toolkit-0.3.10.dist-info → monoco_toolkit-0.3.12.dist-info}/licenses/LICENSE +0 -0
monoco/features/agent/cli.py
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import typer
|
|
2
2
|
import time
|
|
3
|
+
import asyncio
|
|
3
4
|
from pathlib import Path
|
|
4
5
|
from typing import Optional
|
|
5
6
|
from monoco.core.output import print_output, print_error
|
|
6
7
|
from monoco.core.config import get_config
|
|
7
|
-
from monoco.features.agent import
|
|
8
|
+
from monoco.features.agent import load_scheduler_config
|
|
9
|
+
from monoco.core.scheduler import AgentTask, LocalProcessScheduler
|
|
8
10
|
|
|
9
11
|
app = typer.Typer(name="agent", help="Manage agent sessions and roles")
|
|
10
12
|
session_app = typer.Typer(name="session", help="Manage active agent sessions")
|
|
@@ -50,12 +52,10 @@ def list_providers():
|
|
|
50
52
|
"""
|
|
51
53
|
from monoco.core.integrations import get_all_integrations
|
|
52
54
|
|
|
53
|
-
# Ideally we'd pass project-specific integrations here if they existed in config objects
|
|
54
55
|
integrations = get_all_integrations(enabled_only=False)
|
|
55
56
|
|
|
56
57
|
output = []
|
|
57
58
|
for key, integration in integrations.items():
|
|
58
|
-
# Perform health check
|
|
59
59
|
health = integration.check_health()
|
|
60
60
|
status_icon = "✅" if health.available else "❌"
|
|
61
61
|
|
|
@@ -127,14 +127,9 @@ def run(
|
|
|
127
127
|
full_prompt = " ".join(prompt) if prompt else ""
|
|
128
128
|
|
|
129
129
|
if issue:
|
|
130
|
-
# User explicitly linked an issue
|
|
131
130
|
issue_id = issue.upper()
|
|
132
131
|
description = full_prompt or None
|
|
133
132
|
else:
|
|
134
|
-
# Ad-hoc task check
|
|
135
|
-
import re
|
|
136
|
-
# Heuristic: if prompt looks like an ID and is short, maybe they meant ID?
|
|
137
|
-
# But explicit is better. Let's assume everything in prompt is instructions.
|
|
138
133
|
issue_id = "NEW_TASK"
|
|
139
134
|
description = full_prompt
|
|
140
135
|
|
|
@@ -156,13 +151,11 @@ def run(
|
|
|
156
151
|
|
|
157
152
|
integration = get_integration(target_engine)
|
|
158
153
|
|
|
159
|
-
# If integration is found, check health
|
|
160
154
|
is_available = False
|
|
161
155
|
if integration:
|
|
162
156
|
health = integration.check_health()
|
|
163
157
|
is_available = health.available
|
|
164
158
|
if not is_available and provider:
|
|
165
|
-
# If user explicitly requested this provider, fail hard
|
|
166
159
|
print_error(f"Requested provider '{target_engine}' is not available.")
|
|
167
160
|
print_error(f"Error: {health.error}")
|
|
168
161
|
raise typer.Exit(code=1)
|
|
@@ -173,23 +166,18 @@ def run(
|
|
|
173
166
|
|
|
174
167
|
all_integrations = get_all_integrations(enabled_only=True)
|
|
175
168
|
fallback_found = None
|
|
176
|
-
|
|
177
|
-
# Priority list for fallback
|
|
178
169
|
priority = ["cursor", "claude", "gemini", "qwen", "kimi"]
|
|
179
170
|
|
|
180
|
-
# Try priority matches first
|
|
181
171
|
for key in priority:
|
|
182
172
|
if key in all_integrations:
|
|
183
173
|
if all_integrations[key].check_health().available:
|
|
184
174
|
fallback_found = key
|
|
185
175
|
break
|
|
186
176
|
|
|
187
|
-
# Determine strict fallback
|
|
188
177
|
if fallback_found:
|
|
189
178
|
print_output(f"🔄 Falling back to available provider: [bold green]{fallback_found}[/bold green]")
|
|
190
179
|
selected_role.engine = fallback_found
|
|
191
180
|
else:
|
|
192
|
-
# If NO CLI tools available, maybe generic agent?
|
|
193
181
|
if "agent" in all_integrations:
|
|
194
182
|
print_output("🔄 Falling back to Generic Agent (No CLI execution).", style="yellow")
|
|
195
183
|
selected_role.engine = "agent"
|
|
@@ -198,7 +186,6 @@ def run(
|
|
|
198
186
|
print_error("Please install Cursor, Claude Code, or Gemini CLI.")
|
|
199
187
|
raise typer.Exit(code=1)
|
|
200
188
|
elif provider:
|
|
201
|
-
# If available and user overrode it
|
|
202
189
|
print_output(f"Overriding provider: {selected_role.engine} -> {provider}")
|
|
203
190
|
selected_role.engine = provider
|
|
204
191
|
|
|
@@ -208,89 +195,136 @@ def run(
|
|
|
208
195
|
title="Agent Framework",
|
|
209
196
|
)
|
|
210
197
|
|
|
211
|
-
# 4. Initialize
|
|
212
|
-
|
|
213
|
-
|
|
198
|
+
# 4. Initialize AgentScheduler and schedule task
|
|
199
|
+
scheduler = LocalProcessScheduler(
|
|
200
|
+
max_concurrent=5,
|
|
201
|
+
project_root=project_root,
|
|
202
|
+
)
|
|
214
203
|
|
|
204
|
+
task = AgentTask(
|
|
205
|
+
task_id=f"cli-{issue_id}-{int(time.time())}",
|
|
206
|
+
role_name=selected_role.name,
|
|
207
|
+
issue_id=issue_id,
|
|
208
|
+
prompt=description or "Execute task",
|
|
209
|
+
engine=selected_role.engine,
|
|
210
|
+
timeout=selected_role.timeout or 900,
|
|
211
|
+
metadata={
|
|
212
|
+
"role_description": selected_role.description,
|
|
213
|
+
"role_goal": selected_role.goal,
|
|
214
|
+
},
|
|
215
|
+
)
|
|
215
216
|
|
|
216
217
|
try:
|
|
217
|
-
#
|
|
218
|
-
|
|
219
|
-
|
|
218
|
+
# Run async scheduler in sync context
|
|
219
|
+
asyncio.run(scheduler.start())
|
|
220
|
+
session_id = asyncio.run(scheduler.schedule(task))
|
|
221
|
+
|
|
222
|
+
print_output(f"Session {session_id} started.")
|
|
220
223
|
|
|
221
224
|
if detach:
|
|
222
225
|
print_output(
|
|
223
|
-
f"Session {
|
|
226
|
+
f"Session {session_id} running in background (detached)."
|
|
224
227
|
)
|
|
225
228
|
return
|
|
226
229
|
|
|
227
|
-
# Monitoring Loop
|
|
228
|
-
while
|
|
230
|
+
# Monitoring Loop - poll for task status
|
|
231
|
+
while True:
|
|
232
|
+
status = scheduler.get_task_status(session_id)
|
|
233
|
+
if status in ["completed", "failed", "crashed"]:
|
|
234
|
+
break
|
|
229
235
|
time.sleep(1)
|
|
230
236
|
|
|
231
|
-
|
|
237
|
+
final_status = scheduler.get_task_status(session_id)
|
|
238
|
+
if final_status == "failed":
|
|
232
239
|
print_error(
|
|
233
|
-
f"Session {
|
|
240
|
+
f"Session {session_id} FAILED. Review logs for details."
|
|
234
241
|
)
|
|
235
242
|
else:
|
|
236
243
|
print_output(
|
|
237
|
-
f"Session finished with status: {
|
|
244
|
+
f"Session finished with status: {final_status}",
|
|
238
245
|
title="Agent Framework",
|
|
239
246
|
)
|
|
240
247
|
|
|
241
248
|
except KeyboardInterrupt:
|
|
242
249
|
print("\nStopping...")
|
|
243
|
-
|
|
250
|
+
asyncio.run(scheduler.cancel_task(session_id))
|
|
244
251
|
print_output("Session terminated.")
|
|
252
|
+
finally:
|
|
253
|
+
asyncio.run(scheduler.stop())
|
|
245
254
|
|
|
246
255
|
|
|
247
256
|
@session_app.command(name="kill")
|
|
248
257
|
def kill_session(session_id: str):
|
|
249
258
|
"""
|
|
250
259
|
Terminate a specific session.
|
|
260
|
+
|
|
261
|
+
Note: Uses AgentScheduler to cancel the task.
|
|
251
262
|
"""
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
263
|
+
settings = get_config()
|
|
264
|
+
project_root = Path(settings.paths.root).resolve()
|
|
265
|
+
|
|
266
|
+
scheduler = LocalProcessScheduler(
|
|
267
|
+
max_concurrent=5,
|
|
268
|
+
project_root=project_root,
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
try:
|
|
272
|
+
asyncio.run(scheduler.start())
|
|
273
|
+
asyncio.run(scheduler.cancel_task(session_id))
|
|
256
274
|
print_output(f"Session {session_id} terminated.")
|
|
257
|
-
|
|
258
|
-
|
|
275
|
+
except Exception as e:
|
|
276
|
+
print_error(f"Failed to terminate session: {e}")
|
|
277
|
+
finally:
|
|
278
|
+
asyncio.run(scheduler.stop())
|
|
259
279
|
|
|
260
280
|
|
|
261
281
|
@session_app.command(name="list")
|
|
262
282
|
def list_sessions():
|
|
263
283
|
"""
|
|
264
284
|
List active agent sessions.
|
|
285
|
+
|
|
286
|
+
Note: Shows tasks from AgentScheduler.
|
|
265
287
|
"""
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
{
|
|
273
|
-
"id": s.model.id,
|
|
274
|
-
"issue": s.model.issue_id,
|
|
275
|
-
"role": s.model.role_name,
|
|
276
|
-
"status": s.model.status,
|
|
277
|
-
"branch": s.model.branch_name,
|
|
278
|
-
}
|
|
279
|
-
)
|
|
280
|
-
|
|
281
|
-
print_output(
|
|
282
|
-
output
|
|
283
|
-
or "No active sessions found (Note: Persistence not implemented in CLI list yet).",
|
|
284
|
-
title="Active Sessions",
|
|
288
|
+
settings = get_config()
|
|
289
|
+
project_root = Path(settings.paths.root).resolve()
|
|
290
|
+
|
|
291
|
+
scheduler = LocalProcessScheduler(
|
|
292
|
+
max_concurrent=5,
|
|
293
|
+
project_root=project_root,
|
|
285
294
|
)
|
|
295
|
+
|
|
296
|
+
try:
|
|
297
|
+
asyncio.run(scheduler.start())
|
|
298
|
+
stats = scheduler.get_stats()
|
|
299
|
+
|
|
300
|
+
output = {
|
|
301
|
+
"scheduler_status": "running" if stats.get("running") else "stopped",
|
|
302
|
+
"active_tasks": stats.get("active_tasks", 0),
|
|
303
|
+
"completed_tasks": stats.get("completed_tasks", 0),
|
|
304
|
+
"failed_tasks": stats.get("failed_tasks", 0),
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
print_output(output, title="Agent Scheduler Status")
|
|
308
|
+
finally:
|
|
309
|
+
asyncio.run(scheduler.stop())
|
|
286
310
|
|
|
287
311
|
|
|
288
312
|
@session_app.command(name="logs")
|
|
289
313
|
def session_logs(session_id: str):
|
|
290
314
|
"""
|
|
291
315
|
Stream logs for a session.
|
|
316
|
+
|
|
317
|
+
Note: Logs are stored in .monoco/sessions/{session_id}.log
|
|
292
318
|
"""
|
|
319
|
+
settings = get_config()
|
|
320
|
+
project_root = Path(settings.paths.root).resolve()
|
|
321
|
+
log_path = project_root / ".monoco" / "sessions" / f"{session_id}.log"
|
|
322
|
+
|
|
293
323
|
print_output(f"Streaming logs for {session_id}...", title="Session Logs")
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
324
|
+
|
|
325
|
+
if log_path.exists():
|
|
326
|
+
print(log_path.read_text())
|
|
327
|
+
else:
|
|
328
|
+
print(f"[12:00:00] Session {session_id} started")
|
|
329
|
+
print("[12:00:01] Worker initialized")
|
|
330
|
+
print("(Log file not found - showing placeholder)")
|
monoco/features/agent/engines.py
CHANGED
|
@@ -1,175 +1,36 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Agent Engine Adapters for Monoco Scheduler.
|
|
3
3
|
|
|
4
|
-
This module
|
|
5
|
-
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from abc import ABC, abstractmethod
|
|
9
|
-
from typing import List
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class EngineAdapter(ABC):
|
|
13
|
-
"""
|
|
14
|
-
Abstract base class for agent engine adapters.
|
|
15
|
-
|
|
16
|
-
Each adapter is responsible for:
|
|
17
|
-
1. Constructing the correct CLI command for its engine
|
|
18
|
-
2. Handling engine-specific error scenarios
|
|
19
|
-
3. Providing metadata about the engine's capabilities
|
|
20
|
-
"""
|
|
21
|
-
|
|
22
|
-
@abstractmethod
|
|
23
|
-
def build_command(self, prompt: str) -> List[str]:
|
|
24
|
-
"""
|
|
25
|
-
Build the CLI command to execute the agent with the given prompt.
|
|
26
|
-
|
|
27
|
-
Args:
|
|
28
|
-
prompt: The instruction/context to send to the agent
|
|
29
|
-
|
|
30
|
-
Returns:
|
|
31
|
-
List of command arguments (e.g., ["gemini", "-y", "prompt text"])
|
|
32
|
-
"""
|
|
33
|
-
pass
|
|
34
|
-
|
|
35
|
-
@property
|
|
36
|
-
@abstractmethod
|
|
37
|
-
def name(self) -> str:
|
|
38
|
-
"""Return the canonical name of this engine."""
|
|
39
|
-
pass
|
|
40
|
-
|
|
41
|
-
@property
|
|
42
|
-
def supports_yolo_mode(self) -> bool:
|
|
43
|
-
"""Whether this engine supports auto-approval mode."""
|
|
44
|
-
return False
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
class GeminiAdapter(EngineAdapter):
|
|
48
|
-
"""
|
|
49
|
-
Adapter for Google Gemini CLI.
|
|
50
|
-
|
|
51
|
-
Command format: gemini -p <prompt> -y
|
|
52
|
-
The -y flag enables "YOLO mode" (auto-approval of actions).
|
|
53
|
-
"""
|
|
54
|
-
|
|
55
|
-
def build_command(self, prompt: str) -> List[str]:
|
|
56
|
-
# Based on Gemini CLI help: -p <prompt> for non-interactive
|
|
57
|
-
return ["gemini", "-p", prompt, "-y"]
|
|
58
|
-
|
|
59
|
-
@property
|
|
60
|
-
def name(self) -> str:
|
|
61
|
-
return "gemini"
|
|
62
|
-
|
|
63
|
-
@property
|
|
64
|
-
def supports_yolo_mode(self) -> bool:
|
|
65
|
-
return True
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
class ClaudeAdapter(EngineAdapter):
|
|
69
|
-
"""
|
|
70
|
-
Adapter for Anthropic Claude CLI.
|
|
71
|
-
|
|
72
|
-
Command format: claude -p <prompt>
|
|
73
|
-
The -p/--print flag enables non-interactive mode.
|
|
74
|
-
"""
|
|
75
|
-
|
|
76
|
-
def build_command(self, prompt: str) -> List[str]:
|
|
77
|
-
# Based on Claude CLI help: -p <prompt> is NOT standard, usually -p means print/non-interactive.
|
|
78
|
-
# But for one-shot execution, we do passing prompt as argument with -p flag.
|
|
79
|
-
return ["claude", "-p", prompt]
|
|
80
|
-
|
|
81
|
-
@property
|
|
82
|
-
def name(self) -> str:
|
|
83
|
-
return "claude"
|
|
4
|
+
DEPRECATED: This module has been moved to monoco.core.scheduler.
|
|
5
|
+
This file is kept for backward compatibility and re-exports from the new location.
|
|
84
6
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
class QwenAdapter(EngineAdapter):
|
|
92
|
-
"""
|
|
93
|
-
Adapter for Qwen Code CLI.
|
|
94
|
-
|
|
95
|
-
Command format: qwen -p <prompt> -y
|
|
96
|
-
"""
|
|
97
|
-
|
|
98
|
-
def build_command(self, prompt: str) -> List[str]:
|
|
99
|
-
# Assuming Qwen follows similar patterns (based on user feedback)
|
|
100
|
-
return ["qwen", "-p", prompt, "-y"]
|
|
101
|
-
|
|
102
|
-
@property
|
|
103
|
-
def name(self) -> str:
|
|
104
|
-
return "qwen"
|
|
105
|
-
|
|
106
|
-
@property
|
|
107
|
-
def supports_yolo_mode(self) -> bool:
|
|
108
|
-
return True
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
class KimiAdapter(EngineAdapter):
|
|
112
|
-
"""
|
|
113
|
-
Adapter for Kimi CLI (Moonshot AI).
|
|
114
|
-
|
|
115
|
-
Command format: kimi -p <prompt> --print
|
|
116
|
-
Note: --print implicitly adds --yolo.
|
|
117
|
-
"""
|
|
118
|
-
|
|
119
|
-
def build_command(self, prompt: str) -> List[str]:
|
|
120
|
-
# Based on Kimi CLI help: -p, --prompt TEXT.
|
|
121
|
-
# Also using --print for non-interactive mode (which enables yolo).
|
|
122
|
-
return ["kimi", "-p", prompt, "--print"]
|
|
123
|
-
|
|
124
|
-
@property
|
|
125
|
-
def name(self) -> str:
|
|
126
|
-
return "kimi"
|
|
127
|
-
|
|
128
|
-
@property
|
|
129
|
-
def supports_yolo_mode(self) -> bool:
|
|
130
|
-
return True
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
class EngineFactory:
|
|
134
|
-
"""
|
|
135
|
-
Factory for creating engine adapter instances.
|
|
136
|
-
|
|
137
|
-
Usage:
|
|
138
|
-
adapter = EngineFactory.create("gemini")
|
|
139
|
-
command = adapter.build_command("Write a test")
|
|
140
|
-
"""
|
|
141
|
-
|
|
142
|
-
_adapters = {
|
|
143
|
-
"gemini": GeminiAdapter,
|
|
144
|
-
"claude": ClaudeAdapter,
|
|
145
|
-
"qwen": QwenAdapter,
|
|
146
|
-
"kimi": KimiAdapter,
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
@classmethod
|
|
150
|
-
def create(cls, engine_name: str) -> EngineAdapter:
|
|
151
|
-
"""
|
|
152
|
-
Create an adapter instance for the specified engine.
|
|
153
|
-
|
|
154
|
-
Args:
|
|
155
|
-
engine_name: Name of the engine (e.g., "gemini", "claude")
|
|
156
|
-
|
|
157
|
-
Returns:
|
|
158
|
-
An instance of the appropriate EngineAdapter
|
|
159
|
-
|
|
160
|
-
Raises:
|
|
161
|
-
ValueError: If the engine is not supported
|
|
162
|
-
"""
|
|
163
|
-
adapter_class = cls._adapters.get(engine_name.lower())
|
|
164
|
-
if not adapter_class:
|
|
165
|
-
supported = ", ".join(cls._adapters.keys())
|
|
166
|
-
raise ValueError(
|
|
167
|
-
f"Unsupported engine: '{engine_name}'. "
|
|
168
|
-
f"Supported engines: {supported}"
|
|
169
|
-
)
|
|
170
|
-
return adapter_class()
|
|
7
|
+
Migration:
|
|
8
|
+
Old: from monoco.features.agent.engines import EngineAdapter, EngineFactory
|
|
9
|
+
New: from monoco.core.scheduler import EngineAdapter, EngineFactory
|
|
10
|
+
"""
|
|
171
11
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
12
|
+
import warnings
|
|
13
|
+
from monoco.core.scheduler import (
|
|
14
|
+
EngineAdapter,
|
|
15
|
+
EngineFactory,
|
|
16
|
+
GeminiAdapter,
|
|
17
|
+
ClaudeAdapter,
|
|
18
|
+
QwenAdapter,
|
|
19
|
+
KimiAdapter,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
warnings.warn(
|
|
23
|
+
"monoco.features.agent.engines is deprecated. "
|
|
24
|
+
"Use monoco.core.scheduler instead.",
|
|
25
|
+
DeprecationWarning,
|
|
26
|
+
stacklevel=2
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
__all__ = [
|
|
30
|
+
"EngineAdapter",
|
|
31
|
+
"EngineFactory",
|
|
32
|
+
"GeminiAdapter",
|
|
33
|
+
"ClaudeAdapter",
|
|
34
|
+
"QwenAdapter",
|
|
35
|
+
"KimiAdapter",
|
|
36
|
+
]
|
monoco/features/agent/resources/en/skills/{flow_engineer → monoco_workflow_agent_engineer}/SKILL.md
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: monoco_workflow_agent_engineer
|
|
3
3
|
description: Standardized workflow for the Engineer role (Flow Skill). Defines the standard operating procedure from requirement investigation to code submission, ensuring test coverage and code quality.
|
|
4
|
-
type:
|
|
4
|
+
type: workflow
|
|
5
5
|
role: engineer
|
|
6
6
|
version: 1.0.0
|
|
7
7
|
---
|
monoco/features/agent/resources/en/skills/{flow_manager → monoco_workflow_agent_manager}/SKILL.md
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: monoco_workflow_agent_manager
|
|
3
3
|
description: Standardized workflow for the Manager role (Flow Skill). Defines the standard operating procedure from inbox organization to task assignment, ensuring clear requirements and reasonable task breakdown.
|
|
4
|
-
type:
|
|
4
|
+
type: workflow
|
|
5
5
|
role: manager
|
|
6
6
|
version: 1.0.0
|
|
7
7
|
---
|
monoco/features/agent/resources/en/skills/{flow_reviewer → monoco_workflow_agent_reviewer}/SKILL.md
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: monoco_workflow_agent_reviewer
|
|
3
3
|
description: Standardized workflow for the Reviewer role (Flow Skill). Defines the standard operating procedure from code checkout to adversarial testing to review completion, ensuring code quality and process compliance.
|
|
4
|
-
type:
|
|
4
|
+
type: workflow
|
|
5
5
|
role: reviewer
|
|
6
6
|
version: 1.0.0
|
|
7
7
|
---
|
monoco/features/agent/resources/{roles/role-engineer.yaml → zh/roles/monoco_role_engineer.yaml}
RENAMED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: monoco_role_engineer
|
|
3
3
|
type: role
|
|
4
|
-
description: Engineer 角色 -
|
|
4
|
+
description: Engineer 角色 - 负责代码生成、测试和维护
|
|
5
5
|
version: 1.0.0
|
|
6
6
|
author: Monoco Toolkit
|
|
7
7
|
|
|
8
8
|
# 默认工作流
|
|
9
|
-
workflow:
|
|
9
|
+
workflow: monoco_workflow_agent_engineer
|
|
10
10
|
|
|
11
11
|
# 默认执行模式
|
|
12
12
|
default_mode: autopilot
|
monoco/features/agent/resources/{roles/role-manager.yaml → zh/roles/monoco_role_manager.yaml}
RENAMED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: monoco_role_manager
|
|
3
3
|
type: role
|
|
4
|
-
description: Manager 角色 -
|
|
4
|
+
description: Manager 角色 - 负责 Issue 管理、进度跟踪和决策
|
|
5
5
|
version: 1.0.0
|
|
6
6
|
author: Monoco Toolkit
|
|
7
7
|
|
|
8
8
|
# 默认工作流
|
|
9
|
-
workflow:
|
|
9
|
+
workflow: monoco_workflow_issue_creation
|
|
10
10
|
|
|
11
11
|
# 默认执行模式
|
|
12
12
|
default_mode: copilot
|
|
13
13
|
|
|
14
14
|
# 触发条件
|
|
15
|
-
trigger:
|
|
15
|
+
trigger: 'incoming.requirement'
|
|
16
16
|
goal: 将模糊需求转化为清晰、可执行的任务
|
|
17
17
|
|
|
18
18
|
# 角色偏好 / Mindset
|
|
19
19
|
preferences:
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
20
|
+
- '5W2H: 使用 5W2H 分析法澄清需求'
|
|
21
|
+
- 'Vertical Slicing: 垂直切片分解任务'
|
|
22
|
+
- 'Clear Acceptance Criteria: 每个任务必须有清晰的验收标准'
|
|
23
|
+
- 'No Unclear Assignment: 禁止指派没有澄清的需求给 Engineer'
|
|
24
24
|
|
|
25
25
|
# 系统提示
|
|
26
26
|
system_prompt: |
|
monoco/features/agent/resources/{roles/role-planner.yaml → zh/roles/monoco_role_planner.yaml}
RENAMED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: monoco_role_planner
|
|
3
3
|
type: role
|
|
4
4
|
description: Planner 角色 - 负责架构设计、技术规划和交接
|
|
5
5
|
version: 1.0.0
|
|
6
6
|
author: Monoco Toolkit
|
|
7
7
|
|
|
8
8
|
# 默认工作流
|
|
9
|
-
workflow:
|
|
9
|
+
workflow: monoco_workflow_agent_planner
|
|
10
10
|
|
|
11
11
|
# 默认执行模式
|
|
12
12
|
default_mode: copilot
|
|
13
13
|
|
|
14
14
|
# 触发条件
|
|
15
|
-
trigger:
|
|
15
|
+
trigger: 'issue.needs_refine'
|
|
16
16
|
goal: 产出清晰的架构设计和可执行的计划
|
|
17
17
|
|
|
18
18
|
# 角色偏好 / Mindset
|
|
19
19
|
preferences:
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
20
|
+
- 'Evidence Based: 所有架构决策必须有代码或文档证据支持'
|
|
21
|
+
- 'Incremental Design: 优先采用增量式设计,避免过度设计'
|
|
22
|
+
- 'Clear Boundaries: 明确模块边界和接口契约'
|
|
23
|
+
- 'Document First: 先写设计文档,再创建实现任务'
|
|
24
|
+
- 'Review Loop: 复杂设计应经过 Review 后再交接'
|
|
25
25
|
|
|
26
26
|
# 系统提示
|
|
27
27
|
system_prompt: |
|
monoco/features/agent/resources/{roles/role-reviewer.yaml → zh/roles/monoco_role_reviewer.yaml}
RENAMED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: monoco_role_reviewer
|
|
3
3
|
type: role
|
|
4
|
-
description: Reviewer 角色 -
|
|
4
|
+
description: Reviewer 角色 - 负责代码审计、架构合规检查和反馈
|
|
5
5
|
version: 1.0.0
|
|
6
6
|
author: Monoco Toolkit
|
|
7
7
|
|
|
8
8
|
# 默认工作流
|
|
9
|
-
workflow:
|
|
9
|
+
workflow: monoco_workflow_agent_reviewer
|
|
10
10
|
|
|
11
11
|
# 默认执行模式
|
|
12
12
|
default_mode: autopilot
|
|
13
13
|
|
|
14
14
|
# 触发条件
|
|
15
|
-
trigger:
|
|
15
|
+
trigger: 'issue.submitted'
|
|
16
16
|
goal: 确保代码质量和流程合规
|
|
17
17
|
|
|
18
18
|
# 角色偏好 / Mindset
|
|
19
19
|
preferences:
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
20
|
+
- 'Double Defense: 双层防御体系 - Engineer 自证 (Verify) + Reviewer 对抗 (Challenge)'
|
|
21
|
+
- 'Try to Break It: 尝试破坏代码,寻找边界情况'
|
|
22
|
+
- 'No Approve Without Test: 禁止未经测试直接 Approve'
|
|
23
|
+
- 'Challenge Tests: 保留有价值的 Challenge Tests 并提交到代码库'
|
|
24
24
|
|
|
25
25
|
# 系统提示
|
|
26
26
|
system_prompt: |
|