tasks
This commit is contained in:
parent
249683ab5f
commit
ff52bbeb9e
2 changed files with 129 additions and 64 deletions
|
|
@ -3,14 +3,6 @@ name: AI Agent - Planning
|
|||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
component:
|
||||
description: 'Component to plan for'
|
||||
required: true
|
||||
type: choice
|
||||
options:
|
||||
- web_v2
|
||||
- backend
|
||||
- common
|
||||
llm_model:
|
||||
description: 'LLM Model'
|
||||
required: true
|
||||
|
|
@ -49,10 +41,11 @@ jobs:
|
|||
- name: Set up Python and bash
|
||||
run: |
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq python3 python3-pip python3-venv bash
|
||||
apt-get install -y -qq python3 python3-pip python3-venv bash jq
|
||||
python3 --version
|
||||
pip3 --version
|
||||
bash --version || echo "bash check failed"
|
||||
jq --version || echo "jq check failed"
|
||||
|
||||
- name: Install Cursor CLI
|
||||
run: |
|
||||
|
|
@ -88,7 +81,7 @@ jobs:
|
|||
git config --global user.name "AI Agent"
|
||||
git config --global user.email "ai-agent@mnemo-cards.com"
|
||||
|
||||
- name: Run Planning Agent
|
||||
- name: Run Planning Agent for All Components
|
||||
env:
|
||||
CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }}
|
||||
CURSOR_MODEL: ${{ inputs.llm_model || secrets.CURSOR_MODEL }}
|
||||
|
|
@ -132,26 +125,40 @@ jobs:
|
|||
fi
|
||||
|
||||
cd ${{ github.workspace }}
|
||||
python3 tools/agent/planning_agent.py ${{ inputs.component }}
|
||||
|
||||
# Plan for all components
|
||||
COMPONENTS=("web_v2" "backend" "common")
|
||||
for COMPONENT in "${COMPONENTS[@]}"; do
|
||||
echo "📋 Planning for component: $COMPONENT"
|
||||
python3 tools/agent/planning_agent.py "$COMPONENT" || {
|
||||
echo "⚠️ Planning failed for $COMPONENT, continuing with other components..."
|
||||
}
|
||||
done
|
||||
|
||||
echo "✅ Planning completed for all components"
|
||||
|
||||
- name: Parse Task List and Create Summary
|
||||
- name: Parse Task Lists and Create Summaries
|
||||
if: success()
|
||||
id: parse_tasks
|
||||
run: |
|
||||
COMPONENT="${{ inputs.component }}"
|
||||
TASK_LIST_PATH="ai_docs/agent/${COMPONENT}/task_list.json"
|
||||
COMPONENTS=("web_v2" "backend" "common")
|
||||
|
||||
if [ ! -f "$TASK_LIST_PATH" ]; then
|
||||
echo "Task list not found"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Parse JSON with Python
|
||||
python3 << 'EOF'
|
||||
for COMPONENT in "${COMPONENTS[@]}"; do
|
||||
TASK_LIST_PATH="ai_docs/agent/${COMPONENT}/task_list.json"
|
||||
|
||||
if [ ! -f "$TASK_LIST_PATH" ]; then
|
||||
echo "⚠️ Task list not found for $COMPONENT, skipping..."
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "📊 Parsing task list for $COMPONENT..."
|
||||
|
||||
# Parse JSON with Python
|
||||
python3 << EOF
|
||||
import json
|
||||
import os
|
||||
|
||||
component = os.environ.get('COMPONENT', 'unknown')
|
||||
component = "$COMPONENT"
|
||||
task_list_path = f"ai_docs/agent/{component}/task_list.json"
|
||||
|
||||
try:
|
||||
|
|
@ -186,61 +193,119 @@ jobs:
|
|||
|
||||
body += "\\n---\\n*Generated by AI Planning Agent*"
|
||||
|
||||
# Save to file for next step
|
||||
with open('/tmp/issue_body.txt', 'w') as f:
|
||||
# Save to file for next step (component-specific)
|
||||
with open(f'/tmp/issue_body_{component}.txt', 'w') as f:
|
||||
f.write(body)
|
||||
|
||||
title = f"📋 Planning: {component} - {len(tasks)} tasks ({total_hours:.1f}h)"
|
||||
with open('/tmp/issue_title.txt', 'w') as f:
|
||||
with open(f'/tmp/issue_title_{component}.txt', 'w') as f:
|
||||
f.write(title)
|
||||
|
||||
print(f"Tasks: {len(tasks)}, High: {high}, Medium: {medium}, Low: {low}")
|
||||
print(f"✅ {component}: Tasks: {len(tasks)}, High: {high}, Medium: {medium}, Low: {low}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
exit(1)
|
||||
print(f"❌ Error processing {component}: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
EOF
|
||||
done
|
||||
|
||||
echo "✅ All task lists parsed"
|
||||
|
||||
- name: Create Issues via Forgejo API
|
||||
if: success()
|
||||
env:
|
||||
COMPONENT: ${{ inputs.component }}
|
||||
|
||||
- name: Create Issue via Forgejo API
|
||||
if: success()
|
||||
FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }}
|
||||
API_URL: ${{ github.api_url }}/repos/${{ github.repository }}/issues
|
||||
run: |
|
||||
COMPONENT="${{ inputs.component }}"
|
||||
COMPONENTS=("web_v2" "backend" "common")
|
||||
|
||||
if [ ! -f "/tmp/issue_body.txt" ] || [ ! -f "/tmp/issue_title.txt" ]; then
|
||||
echo "Issue files not found, skipping issue creation"
|
||||
exit 0
|
||||
fi
|
||||
for COMPONENT in "${COMPONENTS[@]}"; do
|
||||
if [ ! -f "/tmp/issue_body_${COMPONENT}.txt" ] || [ ! -f "/tmp/issue_title_${COMPONENT}.txt" ]; then
|
||||
echo "⚠️ Issue files not found for $COMPONENT, skipping..."
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "📝 Creating issue for $COMPONENT..."
|
||||
|
||||
# Create issue using Python for proper JSON escaping
|
||||
python3 << PYTHON_SCRIPT
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
TITLE=$(cat /tmp/issue_title.txt)
|
||||
BODY=$(cat /tmp/issue_body.txt)
|
||||
component = "$COMPONENT"
|
||||
api_url = os.environ.get('API_URL')
|
||||
token = os.environ.get('FORGEJO_TOKEN')
|
||||
|
||||
# Forgejo API endpoint (adjust to your Forgejo instance)
|
||||
API_URL="${{ github.api_url }}/repos/${{ github.repository }}/issues"
|
||||
if not all([component, api_url, token]):
|
||||
print("❌ Missing required environment variables")
|
||||
sys.exit(1)
|
||||
|
||||
# Create issue using curl
|
||||
curl -X POST "$API_URL" \
|
||||
-H "Authorization: token ${{ secrets.FORGEJO_TOKEN }}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d @- << EOF
|
||||
{
|
||||
"title": "$TITLE",
|
||||
"body": $(echo "$BODY" | jq -Rs .),
|
||||
"labels": ["ai-agent", "planning", "$COMPONENT"]
|
||||
# Read title and body
|
||||
try:
|
||||
with open(f'/tmp/issue_title_{component}.txt', 'r') as f:
|
||||
title = f.read().strip()
|
||||
|
||||
with open(f'/tmp/issue_body_{component}.txt', 'r') as f:
|
||||
body = f.read()
|
||||
except Exception as e:
|
||||
print(f"❌ Error reading files: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
# Create JSON payload
|
||||
payload = {
|
||||
"title": title,
|
||||
"body": body,
|
||||
"labels": ["ai-agent", "planning", component]
|
||||
}
|
||||
EOF
|
||||
|
||||
# Make API request
|
||||
json_payload = json.dumps(payload)
|
||||
curl_cmd = [
|
||||
"curl", "-X", "POST", api_url,
|
||||
"-H", f"Authorization: token {token}",
|
||||
"-H", "Content-Type: application/json",
|
||||
"-d", json_payload,
|
||||
"-f", "-s", "-S"
|
||||
]
|
||||
|
||||
result = subprocess.run(curl_cmd, capture_output=True, text=True)
|
||||
|
||||
if result.returncode == 0:
|
||||
print(f"✅ Issue created for {component}")
|
||||
if result.stdout:
|
||||
print(f"Response: {result.stdout[:200]}")
|
||||
else:
|
||||
print(f"❌ Failed to create issue for {component}")
|
||||
print(f"Error: {result.stderr}")
|
||||
if result.stdout:
|
||||
print(f"Response: {result.stdout}")
|
||||
sys.exit(1)
|
||||
PYTHON_SCRIPT
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "⚠️ Failed to create issue for $COMPONENT, continuing..."
|
||||
fi
|
||||
done
|
||||
|
||||
- name: Trigger Development Workflow
|
||||
- name: Trigger Development Workflow for All Components
|
||||
if: success()
|
||||
run: |
|
||||
COMPONENT="${{ inputs.component }}"
|
||||
|
||||
# Trigger via Forgejo API
|
||||
COMPONENTS=("web_v2" "backend" "common")
|
||||
API_URL="${{ github.api_url }}/repos/${{ github.repository }}/actions/workflows/agent-development.yml/dispatches"
|
||||
|
||||
curl -X POST "$API_URL" \
|
||||
-H "Authorization: token ${{ secrets.FORGEJO_TOKEN }}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"ref\":\"master\",\"inputs\":{\"component\":\"$COMPONENT\"}}"
|
||||
for COMPONENT in "${COMPONENTS[@]}"; do
|
||||
echo "🚀 Triggering development workflow for $COMPONENT..."
|
||||
|
||||
curl -X POST "$API_URL" \
|
||||
-H "Authorization: token ${{ secrets.FORGEJO_TOKEN }}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"ref\":\"master\",\"inputs\":{\"component\":\"$COMPONENT\"}}" || {
|
||||
echo "⚠️ Failed to trigger workflow for $COMPONENT, continuing..."
|
||||
}
|
||||
|
||||
echo "✅ Development workflow triggered for $COMPONENT"
|
||||
done
|
||||
|
||||
|
|
|
|||
|
|
@ -153,10 +153,12 @@ Start planning now!
|
|||
"""Gather context from existing files."""
|
||||
context = ""
|
||||
|
||||
# Read tasks.md if exists
|
||||
# Read tasks.md - check multiple locations
|
||||
# Priority: component-specific > global agent tasks.md
|
||||
tasks_md = self.config.component_root / "tasks.md"
|
||||
if not tasks_md.exists():
|
||||
tasks_md = self.config.project_root / "mnemo_cards_web_v2" / "tasks.md"
|
||||
# Fallback to global agent tasks.md
|
||||
tasks_md = self.config.project_root / "ai_docs" / "agent" / "tasks.md"
|
||||
|
||||
if tasks_md.exists():
|
||||
with open(tasks_md, 'r') as f:
|
||||
|
|
@ -166,10 +168,8 @@ Start planning now!
|
|||
content = content[:10000] + "\n... (truncated)"
|
||||
context += f"### tasks.md:\n```\n{content}\n```\n\n"
|
||||
|
||||
# Read workflow_state.md if exists
|
||||
# Read workflow_state.md - component-specific only
|
||||
workflow_state = self.config.component_root / "workflow_state.md"
|
||||
if not workflow_state.exists():
|
||||
workflow_state = self.config.project_root / "mnemo_cards_web_v2" / "workflow_state.md"
|
||||
|
||||
if workflow_state.exists():
|
||||
with open(workflow_state, 'r') as f:
|
||||
|
|
|
|||
Loading…
Reference in a new issue