feat(delegate-job): support --role parameter in submit and update commands to resolve role suitability mismatches
This commit is contained in:
@@ -33,6 +33,7 @@ multi-agent-mux-delegate-job submit \
|
|||||||
--agent <claude-code|hermes-agent|agy-agent|cline-agent|human> \
|
--agent <claude-code|hermes-agent|agy-agent|cline-agent|human> \
|
||||||
--agent-session tmux:<session_name> \
|
--agent-session tmux:<session_name> \
|
||||||
--prompt "Task description or instructions here" \
|
--prompt "Task description or instructions here" \
|
||||||
|
--role <Worker|Planner|Reviewer> \
|
||||||
--timeout 3600 --idle-timeout 120
|
--timeout 3600 --idle-timeout 120
|
||||||
|
|
||||||
# 2) Submit a job with a feedback loop (Worker-Reviewer Loop)
|
# 2) Submit a job with a feedback loop (Worker-Reviewer Loop)
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ multi-agent-mux-delegate-job <command> [options]
|
|||||||
|
|
||||||
submit --agent <name> --prompt <text> [--workdir <dir>] [--agent-session <label>]
|
submit --agent <name> --prompt <text> [--workdir <dir>] [--agent-session <label>]
|
||||||
[--timeout <sec>] [--idle-timeout <sec>] [--validate <script>]
|
[--timeout <sec>] [--idle-timeout <sec>] [--validate <script>]
|
||||||
[--registry-dir <dir>] [--dry-run]
|
[--registry-dir <dir>] [--dry-run] [--role <role_name>]
|
||||||
[--type <direct|loop|discuss>] [--reviewer <reviewer_agent>]
|
[--type <direct|loop|discuss>] [--reviewer <reviewer_agent>]
|
||||||
[--reviewer-session <reviewer_session>] [--max-iterations <count>]
|
[--reviewer-session <reviewer_session>] [--max-iterations <count>]
|
||||||
# The skill is tmux-interactive only; --mode print was removed.
|
# The skill is tmux-interactive only; --mode print was removed.
|
||||||
@@ -67,7 +67,7 @@ EOF
|
|||||||
# ---- arg parsing helpers --------------------------------------------------
|
# ---- arg parsing helpers --------------------------------------------------
|
||||||
AGENT="claude-code"; PROMPT=""; WORKDIR="$(pwd)"; AGENT_SESSION="tmux:claude"
|
AGENT="claude-code"; PROMPT=""; WORKDIR="$(pwd)"; AGENT_SESSION="tmux:claude"
|
||||||
TIMEOUT=3600; IDLE_TIMEOUT=120; VALIDATE=""; DRY_RUN=0
|
TIMEOUT=3600; IDLE_TIMEOUT=120; VALIDATE=""; DRY_RUN=0
|
||||||
JOB_ID=""; REGISTRY_DIR="$REGISTRY_DIR_DEFAULT"
|
JOB_ID=""; REGISTRY_DIR="$REGISTRY_DIR_DEFAULT"; DELEGATE_ROLE="Worker"
|
||||||
TYPE="direct"; REVIEWER="hermes"; REVIEWER_SESSION="tmux:hermes"; MAX_ITERATIONS=5
|
TYPE="direct"; REVIEWER="hermes"; REVIEWER_SESSION="tmux:hermes"; MAX_ITERATIONS=5
|
||||||
|
|
||||||
parse_opts() {
|
parse_opts() {
|
||||||
@@ -83,6 +83,7 @@ parse_opts() {
|
|||||||
--job) JOB_ID="$2"; shift 2;;
|
--job) JOB_ID="$2"; shift 2;;
|
||||||
--registry-dir) REGISTRY_DIR="$2"; shift 2;;
|
--registry-dir) REGISTRY_DIR="$2"; shift 2;;
|
||||||
--dry-run) DRY_RUN=1; shift;;
|
--dry-run) DRY_RUN=1; shift;;
|
||||||
|
--role) DELEGATE_ROLE="$2"; shift 2;;
|
||||||
--type) TYPE="$2"; shift 2;;
|
--type) TYPE="$2"; shift 2;;
|
||||||
--reviewer) REVIEWER="$2"; shift 2;;
|
--reviewer) REVIEWER="$2"; shift 2;;
|
||||||
--reviewer-session) REVIEWER_SESSION="$2"; shift 2;;
|
--reviewer-session) REVIEWER_SESSION="$2"; shift 2;;
|
||||||
@@ -101,7 +102,7 @@ cmd_submit() {
|
|||||||
|
|
||||||
# 1) register job (prints the new job id)
|
# 1) register job (prints the new job id)
|
||||||
JOB_ID="$("$PY" "$SCRIPT_DIR/scripts/registry.py" --registry-dir "$REGISTRY_DIR" register \
|
JOB_ID="$("$PY" "$SCRIPT_DIR/scripts/registry.py" --registry-dir "$REGISTRY_DIR" register \
|
||||||
--prompt "$PROMPT" --agent "$AGENT" --agent-session "$AGENT_SESSION" \
|
--prompt "$PROMPT" --agent "$AGENT" --agent-session "$AGENT_SESSION" --role "$DELEGATE_ROLE" \
|
||||||
--timeout "$TIMEOUT" --idle-timeout "$IDLE_TIMEOUT" \
|
--timeout "$TIMEOUT" --idle-timeout "$IDLE_TIMEOUT" \
|
||||||
--job-type "$TYPE" --reviewer "$REVIEWER" --reviewer-session "$REVIEWER_SESSION" \
|
--job-type "$TYPE" --reviewer "$REVIEWER" --reviewer-session "$REVIEWER_SESSION" \
|
||||||
--max-iterations "$MAX_ITERATIONS")"
|
--max-iterations "$MAX_ITERATIONS")"
|
||||||
@@ -116,7 +117,7 @@ cmd_submit() {
|
|||||||
|
|
||||||
- **Job ID**: $JOB_ID
|
- **Job ID**: $JOB_ID
|
||||||
- **Target Agent**: $AGENT (session: $AGENT_SESSION)
|
- **Target Agent**: $AGENT (session: $AGENT_SESSION)
|
||||||
- **Role**: Worker
|
- **Role**: $DELEGATE_ROLE
|
||||||
- **Timeout**: $TIMEOUT s (Idle: $IDLE_TIMEOUT s)
|
- **Timeout**: $TIMEOUT s (Idle: $IDLE_TIMEOUT s)
|
||||||
- **Output Report Path**: .mam/jobs/$JOB_ID/$AGENT-reports/report-final.md
|
- **Output Report Path**: .mam/jobs/$JOB_ID/$AGENT-reports/report-final.md
|
||||||
|
|
||||||
@@ -238,6 +239,7 @@ EOF
|
|||||||
--agent-session "$current_session" \
|
--agent-session "$current_session" \
|
||||||
--prompt "$current_prompt" \
|
--prompt "$current_prompt" \
|
||||||
--iteration "$iteration" \
|
--iteration "$iteration" \
|
||||||
|
--role "$current_role" \
|
||||||
--status "pending"
|
--status "pending"
|
||||||
|
|
||||||
# Start subscriber
|
# Start subscriber
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ def register_job(
|
|||||||
prompt: str,
|
prompt: str,
|
||||||
agent: str = "claude-code",
|
agent: str = "claude-code",
|
||||||
agent_session: str = "tmux:claude",
|
agent_session: str = "tmux:claude",
|
||||||
|
role: str = "Worker",
|
||||||
broker: Optional[Dict[str, Any]] = None,
|
broker: Optional[Dict[str, Any]] = None,
|
||||||
timeout_sec: int = 3600,
|
timeout_sec: int = 3600,
|
||||||
idle_timeout_sec: int = 120,
|
idle_timeout_sec: int = 120,
|
||||||
@@ -87,6 +88,7 @@ def register_job(
|
|||||||
"prompt": prompt,
|
"prompt": prompt,
|
||||||
"agent": agent,
|
"agent": agent,
|
||||||
"agent_session": agent_session,
|
"agent_session": agent_session,
|
||||||
|
"role": role,
|
||||||
"broker": broker,
|
"broker": broker,
|
||||||
"topic_prefix": topic_prefix_for(job_id),
|
"topic_prefix": topic_prefix_for(job_id),
|
||||||
"timeout_sec": int(timeout_sec),
|
"timeout_sec": int(timeout_sec),
|
||||||
@@ -239,6 +241,7 @@ def _build_parser() -> argparse.ArgumentParser:
|
|||||||
p_reg.add_argument("--prompt", required=True)
|
p_reg.add_argument("--prompt", required=True)
|
||||||
p_reg.add_argument("--agent", default="claude-code")
|
p_reg.add_argument("--agent", default="claude-code")
|
||||||
p_reg.add_argument("--agent-session", default="tmux:claude")
|
p_reg.add_argument("--agent-session", default="tmux:claude")
|
||||||
|
p_reg.add_argument("--role", default="Worker", help="logical role for the delegated agent (e.g. Worker, Planner, Reviewer)")
|
||||||
p_reg.add_argument("--timeout", type=int, default=3600)
|
p_reg.add_argument("--timeout", type=int, default=3600)
|
||||||
p_reg.add_argument("--idle-timeout", type=int, default=120)
|
p_reg.add_argument("--idle-timeout", type=int, default=120)
|
||||||
p_reg.add_argument("--bits", type=int, default=32, help="32 (PoC) or 128 (prod)")
|
p_reg.add_argument("--bits", type=int, default=32, help="32 (PoC) or 128 (prod)")
|
||||||
@@ -266,6 +269,7 @@ def _build_parser() -> argparse.ArgumentParser:
|
|||||||
p_update.add_argument("--agent-session", default=None)
|
p_update.add_argument("--agent-session", default=None)
|
||||||
p_update.add_argument("--prompt", default=None)
|
p_update.add_argument("--prompt", default=None)
|
||||||
p_update.add_argument("--iteration", type=int, default=None)
|
p_update.add_argument("--iteration", type=int, default=None)
|
||||||
|
p_update.add_argument("--role", default=None)
|
||||||
|
|
||||||
p_feedback = sub.add_parser("get-feedback", help="get the last feedback detail (completed/error) for a job")
|
p_feedback = sub.add_parser("get-feedback", help="get the last feedback detail (completed/error) for a job")
|
||||||
p_feedback.add_argument("--job", required=True)
|
p_feedback.add_argument("--job", required=True)
|
||||||
@@ -302,6 +306,7 @@ def main(argv: Optional[List[str]] = None) -> int:
|
|||||||
prompt=args.prompt,
|
prompt=args.prompt,
|
||||||
agent=args.agent,
|
agent=args.agent,
|
||||||
agent_session=args.agent_session,
|
agent_session=args.agent_session,
|
||||||
|
role=args.role,
|
||||||
timeout_sec=args.timeout,
|
timeout_sec=args.timeout,
|
||||||
idle_timeout_sec=args.idle_timeout,
|
idle_timeout_sec=args.idle_timeout,
|
||||||
registry_dir=rd,
|
registry_dir=rd,
|
||||||
@@ -354,6 +359,8 @@ def main(argv: Optional[List[str]] = None) -> int:
|
|||||||
fields["prompt"] = args.prompt
|
fields["prompt"] = args.prompt
|
||||||
if args.iteration is not None:
|
if args.iteration is not None:
|
||||||
fields["iteration"] = args.iteration
|
fields["iteration"] = args.iteration
|
||||||
|
if args.role is not None:
|
||||||
|
fields["role"] = args.role
|
||||||
try:
|
try:
|
||||||
mqtt_common.update_job_status(args.job, rd, **fields)
|
mqtt_common.update_job_status(args.job, rd, **fields)
|
||||||
except FileNotFoundError as exc:
|
except FileNotFoundError as exc:
|
||||||
|
|||||||
@@ -225,6 +225,7 @@ if [ "$PLAN_MODE" = true ]; then
|
|||||||
--agent-session "tmux:$PLANNER_SESSION" \
|
--agent-session "tmux:$PLANNER_SESSION" \
|
||||||
--agent "$(resolve_agent_type "$PLANNER_SESSION")" \
|
--agent "$(resolve_agent_type "$PLANNER_SESSION")" \
|
||||||
--type "direct" \
|
--type "direct" \
|
||||||
|
--role "Planner" \
|
||||||
--prompt "태스크 목표를 바탕으로 구체적인 구현 계획서를 작성해주세요. 목표: $TASK")
|
--prompt "태스크 목표를 바탕으로 구체적인 구현 계획서를 작성해주세요. 목표: $TASK")
|
||||||
|
|
||||||
PLAN_JOB_ID=$(extract_job_id "$PLAN_JOB_OUTPUT")
|
PLAN_JOB_ID=$(extract_job_id "$PLAN_JOB_OUTPUT")
|
||||||
@@ -258,6 +259,7 @@ if [ "$PLAN_MODE" = true ]; then
|
|||||||
--agent-session "tmux:$TARGET_AGENT" \
|
--agent-session "tmux:$TARGET_AGENT" \
|
||||||
--agent "$(resolve_agent_type "$TARGET_AGENT")" \
|
--agent "$(resolve_agent_type "$TARGET_AGENT")" \
|
||||||
--type "direct" \
|
--type "direct" \
|
||||||
|
--role "Worker" \
|
||||||
--prompt "Planner가 제시한 다음 계획서를 꼼꼼히 검토하고, 실제 구현 시 마주할 수 있는 맹점이나 제약사항 1가지를 발굴하여 Planner에게 이의를 제기(Challenge)해주세요. 계획서:\n$CURRENT_PLAN")
|
--prompt "Planner가 제시한 다음 계획서를 꼼꼼히 검토하고, 실제 구현 시 마주할 수 있는 맹점이나 제약사항 1가지를 발굴하여 Planner에게 이의를 제기(Challenge)해주세요. 계획서:\n$CURRENT_PLAN")
|
||||||
|
|
||||||
DEBATE_JOB_ID=$(extract_job_id "$DEBATE_JOB_OUTPUT")
|
DEBATE_JOB_ID=$(extract_job_id "$DEBATE_JOB_OUTPUT")
|
||||||
@@ -285,6 +287,7 @@ if [ "$PLAN_MODE" = true ]; then
|
|||||||
--agent-session "tmux:$PLANNER_SESSION" \
|
--agent-session "tmux:$PLANNER_SESSION" \
|
||||||
--agent "$(resolve_agent_type "$PLANNER_SESSION")" \
|
--agent "$(resolve_agent_type "$PLANNER_SESSION")" \
|
||||||
--type "direct" \
|
--type "direct" \
|
||||||
|
--role "Planner" \
|
||||||
--prompt "작업자(Creator)로부터 다음 이의제기 피드백을 받았습니다. 피드백을 반영하여 계획서를 정교하게 업데이트(Refine)하여 다시 출력해주세요. 피드백:\n$CRITIQUE_TEXT\n기존 계획서:\n$CURRENT_PLAN")
|
--prompt "작업자(Creator)로부터 다음 이의제기 피드백을 받았습니다. 피드백을 반영하여 계획서를 정교하게 업데이트(Refine)하여 다시 출력해주세요. 피드백:\n$CRITIQUE_TEXT\n기존 계획서:\n$CURRENT_PLAN")
|
||||||
|
|
||||||
REFINE_JOB_ID=$(extract_job_id "$REFINE_JOB_OUTPUT")
|
REFINE_JOB_ID=$(extract_job_id "$REFINE_JOB_OUTPUT")
|
||||||
@@ -340,6 +343,7 @@ EXEC_JOB_OUTPUT=$(bash .agents/skills/multi-agent-mux-delegate-job/multi-agent-m
|
|||||||
--agent-session "tmux:$TARGET_AGENT" \
|
--agent-session "tmux:$TARGET_AGENT" \
|
||||||
--agent "$(resolve_agent_type "$TARGET_AGENT")" \
|
--agent "$(resolve_agent_type "$TARGET_AGENT")" \
|
||||||
--type "direct" \
|
--type "direct" \
|
||||||
|
--role "Worker" \
|
||||||
--prompt "$EXECUTION_PROMPT")
|
--prompt "$EXECUTION_PROMPT")
|
||||||
|
|
||||||
EXEC_JOB_ID=$(extract_job_id "$EXEC_JOB_OUTPUT")
|
EXEC_JOB_ID=$(extract_job_id "$EXEC_JOB_OUTPUT")
|
||||||
@@ -383,6 +387,7 @@ while [ "$loop_count" -le "$MAX_LOOP" ]; do
|
|||||||
--agent-session "tmux:$TARGET_AGENT" \
|
--agent-session "tmux:$TARGET_AGENT" \
|
||||||
--agent "$(resolve_agent_type "$TARGET_AGENT")" \
|
--agent "$(resolve_agent_type "$TARGET_AGENT")" \
|
||||||
--type "direct" \
|
--type "direct" \
|
||||||
|
--role "Reviewer" \
|
||||||
--prompt "작업 완료 상태에 대해 스스로 검증(Self-Review)하여 결함이 없음을 확인하고 종결해주세요. 리뷰 리포트 마지막에 단독 행으로 반드시 '[VERDICT: PASS]' 혹은 '[VERDICT: NOT PASS]' 태그를 명시해주세요.")
|
--prompt "작업 완료 상태에 대해 스스로 검증(Self-Review)하여 결함이 없음을 확인하고 종결해주세요. 리뷰 리포트 마지막에 단독 행으로 반드시 '[VERDICT: PASS]' 혹은 '[VERDICT: NOT PASS]' 태그를 명시해주세요.")
|
||||||
|
|
||||||
SELF_REV_ID=$(extract_job_id "$SELF_REV_OUTPUT")
|
SELF_REV_ID=$(extract_job_id "$SELF_REV_OUTPUT")
|
||||||
@@ -426,6 +431,7 @@ while [ "$loop_count" -le "$MAX_LOOP" ]; do
|
|||||||
--agent-session "tmux:$rev" \
|
--agent-session "tmux:$rev" \
|
||||||
--agent "$(resolve_agent_type "$rev")" \
|
--agent "$(resolve_agent_type "$rev")" \
|
||||||
--type "direct" \
|
--type "direct" \
|
||||||
|
--role "Reviewer" \
|
||||||
--prompt "다음 구현 사항(작업 목표: $TASK) 및 누적 변경분(git diff)에 대해 린트, 동작성, 유실 등의 관점에서 교차 코드 리뷰를 수행해주세요. 확인 후 최종 Verdict로 '[VERDICT: PASS]' 혹은 '[VERDICT: NOT PASS]' 태그를 리뷰 리포트 마지막에 단독 행으로 명시적으로 작성해주세요. 만약 단순 버그 수정으로는 부족하고 설계 변경/재작업 수준의 재계획이 필요하다고 판단되면, 리포트 아무 곳에나 단독 행으로 '[ESCALATE: PLANNER]' 태그도 함께 남겨주세요. 변경분:\n$CHANGES_DIFF")
|
--prompt "다음 구현 사항(작업 목표: $TASK) 및 누적 변경분(git diff)에 대해 린트, 동작성, 유실 등의 관점에서 교차 코드 리뷰를 수행해주세요. 확인 후 최종 Verdict로 '[VERDICT: PASS]' 혹은 '[VERDICT: NOT PASS]' 태그를 리뷰 리포트 마지막에 단독 행으로 명시적으로 작성해주세요. 만약 단순 버그 수정으로는 부족하고 설계 변경/재작업 수준의 재계획이 필요하다고 판단되면, 리포트 아무 곳에나 단독 행으로 '[ESCALATE: PLANNER]' 태그도 함께 남겨주세요. 변경분:\n$CHANGES_DIFF")
|
||||||
|
|
||||||
REV_JOB_ID=$(extract_job_id "$REV_OUTPUT")
|
REV_JOB_ID=$(extract_job_id "$REV_OUTPUT")
|
||||||
@@ -496,6 +502,7 @@ while [ "$loop_count" -le "$MAX_LOOP" ]; do
|
|||||||
--agent-session "tmux:$PLANNER_SESSION" \
|
--agent-session "tmux:$PLANNER_SESSION" \
|
||||||
--agent "$(resolve_agent_type "$PLANNER_SESSION")" \
|
--agent "$(resolve_agent_type "$PLANNER_SESSION")" \
|
||||||
--type "direct" \
|
--type "direct" \
|
||||||
|
--role "Planner" \
|
||||||
--prompt "리뷰어들로부터 다음과 같이 정교한 코드 수정 피드백이 도착했습니다. 해당 피드백을 수렴하여 구현 계획서(Plan)를 갱신(Refine)하여 다시 작성해주세요. 피드백:\n$FEEDBACK_AGGREGATE\n기존 계획서:\n$CURRENT_PLAN")
|
--prompt "리뷰어들로부터 다음과 같이 정교한 코드 수정 피드백이 도착했습니다. 해당 피드백을 수렴하여 구현 계획서(Plan)를 갱신(Refine)하여 다시 작성해주세요. 피드백:\n$FEEDBACK_AGGREGATE\n기존 계획서:\n$CURRENT_PLAN")
|
||||||
|
|
||||||
REFINE_PLAN_ID=$(extract_job_id "$REFINE_PLAN_OUTPUT")
|
REFINE_PLAN_ID=$(extract_job_id "$REFINE_PLAN_OUTPUT")
|
||||||
@@ -524,6 +531,7 @@ while [ "$loop_count" -le "$MAX_LOOP" ]; do
|
|||||||
--agent-session "tmux:$TARGET_AGENT" \
|
--agent-session "tmux:$TARGET_AGENT" \
|
||||||
--agent "$(resolve_agent_type "$TARGET_AGENT")" \
|
--agent "$(resolve_agent_type "$TARGET_AGENT")" \
|
||||||
--type "direct" \
|
--type "direct" \
|
||||||
|
--role "Worker" \
|
||||||
--prompt "$CORRECTION_PROMPT")
|
--prompt "$CORRECTION_PROMPT")
|
||||||
|
|
||||||
CORRECT_JOB_ID=$(extract_job_id "$CORRECT_JOB_OUTPUT")
|
CORRECT_JOB_ID=$(extract_job_id "$CORRECT_JOB_OUTPUT")
|
||||||
|
|||||||
Reference in New Issue
Block a user