File size: 5,668 Bytes
51f80a0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4f82d26
 
51f80a0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import anyio
import argparse
import shutil
import subprocess
from claude_agent_sdk import (
    ClaudeSDKClient,
    ClaudeAgentOptions,
    AgentDefinition,
    AssistantMessage,
    TextBlock,
    ToolUseBlock,
    ToolResultBlock
)

import os
import sys
from pathlib import Path
from utils import copy_project_resources, clone_github_repo, prepare_folder_structure
from prompts.tasks import step1_environment_setup_and_tutorial_discovery, step2_tutorial_execution, step3_tool_extraction_and_testing, step4_mcp_integration

# Read API key from environment variable
api_key_anthropic = os.environ["ANTHROPIC_API_KEY"]

async def fully_automatic(tasks: list, task_descriptions: list = None, log_file_path: str = None):
    options = ClaudeAgentOptions(
        allowed_tools=["Bash", "Edit", "Glob", "Grep", "NotebookEdit", "NotebookRead", "Read", "SlashCommand", "Task", "TodoWrite", "WebFetch", "WebSearch", "Write"],
        permission_mode='acceptEdits',
        cwd=str(Path.cwd()),
        setting_sources=["project"],
    )

    async with ClaudeSDKClient(options=options) as client:
        for i, task in enumerate(tasks, 1):
            # Simple print for UI
            print(f"\n{'='*70}")
            if task_descriptions and i <= len(task_descriptions):
                print(f"πŸš€ Starting {task_descriptions[i-1]}")
            else:
                print(f"πŸš€ Starting Task {i}")
            print('='*70 + "\n")

            try:
                await client.query(task)
                async for message in client.receive_response():
                    # Write detailed logs to file
                    if log_file_path:
                        with open(f"Task_{i}_{log_file_path}", 'a', encoding='utf-8') as log_file:
                            if isinstance(message, AssistantMessage):
                                for block in message.content:
                                    if isinstance(block, TextBlock):
                                        log_file.write(f"πŸ’­ Claude: {block.text}\n")
                                    elif isinstance(block, ToolUseBlock):
                                        if hasattr(block, 'input') and block.input:
                                            if isinstance(block.input, dict):
                                                for key, value in block.input.items():
                                                    val_str = str(value)
                                                    log_file.write(f"[ToolUseBlock] {key}: {val_str}\n")
                            elif isinstance(message, ToolResultBlock):
                                if hasattr(message, 'content'):
                                    result = str(message.content)
                                    log_file.write(f"  βœ… Result: {result}\n")

                    # Only print brief progress to stdout for UI
                    if isinstance(message, AssistantMessage):
                        for block in message.content:
                            if isinstance(block, TextBlock):
                                # Only print short text blocks
                                text = block.text.strip()
                                if len(text) < 150:
                                    print(f"πŸ’­ {text}")

                print(f"\nβœ… Task {i} Completed\n")

            except Exception as e:
                print(f"❌ Task {i} Failed: {e}\n")
                if log_file_path:
                    with open(log_file_path, 'a', encoding='utf-8') as log_file:
                        log_file.write(f"❌ Task {i} Failed: {e}\n")


def main():

    parser = argparse.ArgumentParser(description="Script for running tasks with configurable options.")
    parser.add_argument('--github_url', dest='github_repo_url', default="", help='GitHub repository URL')
    parser.add_argument('--tutorials', dest='tutorial_filter', default="", help='Tutorial filter')
    parser.add_argument('--api', dest='api_key', default="", help='API key')
    args = parser.parse_args()

    GITHUB_REPO_URL = args.github_repo_url
    FOLDER_NAME = "Results"
    TUTORIAL_FILTER = args.tutorial_filter
    API_KEY = args.api_key

    # Extract repo_name from the GITHUB_REPO_URL (strip .git suffix if present)
    if GITHUB_REPO_URL:
        repo_name = os.path.basename(GITHUB_REPO_URL)
        if repo_name.endswith(".git"):
            repo_name = repo_name[:-4]
    else:
        repo_name = ""

    
    os.makedirs(FOLDER_NAME, exist_ok=True)

    # step 1: copy .claude, templates, tools to the project directory
    copy_project_resources(FOLDER_NAME)
    
    # step 2: prepare the folder structure
    prepare_folder_structure(FOLDER_NAME)

    os.chdir(FOLDER_NAME)
    
    # step 3: clone the github repository
    clone_github_repo(GITHUB_REPO_URL, repo_name)

    task_descriptions = [
        "Task 1: Environment Setup and Tutorial Discovery",
        "Task 2: Tutorial Execution",
        "Task 3: Tool Extraction and Testing",
        "Task 4: MCP Integration"
    ]

    tasks = [
        step1_environment_setup_and_tutorial_discovery(repo_name,TUTORIAL_FILTER),
        step2_tutorial_execution(repo_name,API_KEY),
        step3_tool_extraction_and_testing(repo_name,API_KEY),
        step4_mcp_integration(repo_name),
    ]

    print("\n" + "="*70)
    print("πŸ“‹ Pipeline Tasks:")
    for i, desc in enumerate(task_descriptions, 1):
        print(f"   {i}. {desc}")
    print("="*70 + "\n")

    # Define log file path
    log_file_path = "log.log"

    #print(tasks[0])
    anyio.run(fully_automatic, tasks, task_descriptions, log_file_path)


if __name__ == "__main__":
    main()