This repository was archived by the owner on Apr 16, 2026. It is now read-only.
LLM Bot Runner #169
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: LLM Bot Runner | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| task: | |
| description: 'LLM的任务描述' | |
| required: true | |
| type: string | |
| context: | |
| description: '任务的JSON上下文' | |
| required: true | |
| type: string | |
| jobs: | |
| create-issue: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| issues: write | |
| outputs: | |
| issue_number: ${{ steps.create-issue.outputs.issue_number }} | |
| steps: | |
| - name: Create issue | |
| id: create-issue | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| TASK_CONTENT: ${{ inputs.task }} | |
| CONTEXT_RAW: ${{ inputs.context }} | |
| GITHUB_RUN_ID: ${{ github.run_id }} | |
| GITHUB_REPOSITORY: ${{ github.repository }} | |
| run: | | |
| # 1. 格式化 Context | |
| FORMATTED_CONTEXT=$(echo "$CONTEXT_RAW" | sed 's/^"//; s/"$//' | jq '.') | |
| # 2. 构建 Markdown 正文 | |
| printf "[工作流运行 #$GITHUB_RUN_ID](https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID)\n\n## Task\n%s\n\n## Context\n\`\`\`json\n%s\n\`\`\`" \ | |
| "$TASK_CONTENT" "$FORMATTED_CONTEXT" > body.md | |
| # 3. 创建 Issue(硬编码标签 workflow) | |
| ISSUE_URL=$(gh issue create \ | |
| --repo "$GITHUB_REPOSITORY" \ | |
| --title "[工作流] Run $GITHUB_RUN_ID" \ | |
| --body-file body.md \ | |
| --label "workflow") | |
| # 4. 提取 Issue 编号 | |
| ISSUE_NUMBER=${ISSUE_URL##*/} | |
| echo "issue_number=$ISSUE_NUMBER" >> "$GITHUB_OUTPUT" | |
| echo "成功创建 Issue: $ISSUE_NUMBER" | |
| run-llm-bot: | |
| needs: create-issue | |
| runs-on: ubuntu-latest | |
| env: | |
| LLM_TASK: ${{ inputs.task }} | |
| LLM_CONTEXT: ${{ inputs.context }} | |
| LOG_ISSUE_NUMBER: ${{ needs.create-issue.outputs.issue_number }} | |
| # GitHub身份令牌(4个名称都设置)- 使用agent的token | |
| GITHUB_TOKEN: ${{ secrets.WEINAR_API_KEY }} | |
| GH_TOKEN: ${{ secrets.WEINAR_API_KEY }} | |
| GITHUBTOKEN: ${{ secrets.WEINAR_API_KEY }} | |
| GHTOKEN: ${{ secrets.WEINAR_API_KEY }} | |
| # Claude Code环境变量配置 | |
| ANTHROPIC_API_KEY: ${{ secrets.MIMO_API_KEY }} | |
| ANTHROPIC_AUTH_TOKEN: ${{ secrets.MIMO_API_KEY }} | |
| ANTHROPIC_BASE_URL: "https://api.xiaomimimo.com/anthropic" | |
| ANTHROPIC_DEFAULT_OPUS_MODEL: "mimo-v2-flash" | |
| ANTHROPIC_DEFAULT_SONNET_MODEL: "mimo-v2-flash" | |
| ANTHROPIC_DEFAULT_HAIKU_MODEL: "mimo-v2-flash" | |
| # MCP服务器环境变量 | |
| CONTEXT7_API_KEY: ${{ secrets.CONTEXT7_API_KEY }} | |
| # 系统提示词 | |
| SYSTEM_PROMPT: ${{ vars.SYSTEM_PROMPT }} | |
| # 其他令牌 | |
| MIMO_API_KEY: ${{ secrets.MIMO_API_KEY }} | |
| WEINAR_API_KEY: ${{ secrets.WEINAR_API_KEY }} | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| issues: write | |
| discussions: write | |
| steps: | |
| - name: Install Claude CLI | |
| run: | | |
| curl -fsSL https://claude.ai/install.sh | bash | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v7 | |
| with: | |
| enable-cache: false | |
| - name: Validate tokens | |
| run: | | |
| echo "验证环境变量..." | |
| # 验证GitHub令牌 | |
| if [ -z "$GITHUB_TOKEN" ]; then | |
| echo "错误: GITHUB_TOKEN未设置" | |
| exit 1 | |
| else | |
| echo "GitHub令牌已设置" | |
| fi | |
| # 验证Anthropic认证令牌 | |
| if [ -z "$ANTHROPIC_AUTH_TOKEN" ]; then | |
| echo "错误: ANTHROPIC_AUTH_TOKEN未设置" | |
| exit 1 | |
| else | |
| echo "Anthropic认证令牌已设置" | |
| fi | |
| # 验证系统提示词 | |
| if [ -z "$SYSTEM_PROMPT" ]; then | |
| echo "错误: SYSTEM_PROMPT未设置" | |
| exit 1 | |
| else | |
| echo "系统提示词已设置" | |
| fi | |
| - name: Add MCP servers | |
| run: | | |
| # 添加DuckDuckGo搜索服务器 | |
| echo "添加DuckDuckGo搜索服务器..." | |
| claude mcp add ddg-search -- uvx duckduckgo-mcp-server | |
| # 添加Context7 HTTP服务器(如果CONTEXT7_API_KEY已设置) | |
| if [ -n "$CONTEXT7_API_KEY" ]; then | |
| echo "添加Context7 HTTP服务器..." | |
| claude mcp add --transport http context7 https://mcp.context7.com/mcp \ | |
| --header "CONTEXT7_API_KEY: $CONTEXT7_API_KEY" | |
| else | |
| echo "警告: CONTEXT7_API_KEY未设置,跳过Context7服务器添加" | |
| fi | |
| env: | |
| CONTEXT7_API_KEY: ${{ secrets.CONTEXT7_API_KEY }} | |
| - name: Configure WakaTime | |
| run: | | |
| # 安装WakaTime插件 | |
| echo "安装WakaTime插件..." | |
| claude plugin marketplace add https://github.com/wakatime/claude-code-wakatime.git | |
| claude plugin i claude-code-wakatime@wakatime | |
| # 配置WakaTime API Key | |
| if [ -n "$WAKE_TIME_API_KEY" ]; then | |
| echo "配置WakaTime API Key..." | |
| mkdir -p ~ | |
| printf "[settings]\napi_key = %s\n" "$WAKE_TIME_API_KEY" > ~/.wakatime.cfg | |
| echo "WakaTime配置完成" | |
| else | |
| echo "警告: WAKE_TIME_API_KEY未设置,跳过WakaTime配置" | |
| fi | |
| env: | |
| WAKE_TIME_API_KEY: ${{ secrets.WAKE_TIME_API_KEY }} | |
| - name: Pre-configure Git | |
| run: | | |
| echo "配置Git用户信息..." | |
| git config --global user.name "WhiteElephantIsNotARobot" | |
| git config --global user.email "257136373+WhiteElephantIsNotARobot@users.noreply.github.com" | |
| echo "配置SSH认证..." | |
| # 创建SSH目录 | |
| mkdir -p ~/.ssh | |
| chmod 700 ~/.ssh | |
| # 从环境变量写入SSH私钥(如果提供了SSH_PRIVATE_KEY) | |
| if [ -n "$SSH_PRIVATE_KEY" ]; then | |
| echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa | |
| chmod 600 ~/.ssh/id_rsa | |
| echo "SSH私钥已写入 ~/.ssh/id_rsa" | |
| # 启动ssh-agent并添加密钥 | |
| eval "$(ssh-agent -s)" | |
| ssh-add ~/.ssh/id_rsa | |
| echo "SSH密钥已添加到ssh-agent" | |
| else | |
| echo "警告: SSH_PRIVATE_KEY环境变量未设置,跳过SSH配置" | |
| fi | |
| # 添加GitHub到known_hosts | |
| ssh-keyscan github.com >> ~/.ssh/known_hosts 2>/dev/null | |
| chmod 644 ~/.ssh/known_hosts | |
| echo "配置GPG签名..." | |
| # 从环境变量写入GPG私钥(如果提供了GPG_PRIVATE_KEY) | |
| if [ -n "$GPG_PRIVATE_KEY" ]; then | |
| echo "$GPG_PRIVATE_KEY" | gpg --import --batch | |
| echo "GPG私钥已导入" | |
| # 获取GPG密钥ID | |
| GPG_KEY_ID=$(gpg --list-secret-keys --keyid-format LONG "257136373+WhiteElephantIsNotARobot@users.noreply.github.com" 2>/dev/null | grep sec | awk '{print $2}' | cut -d'/' -f2) | |
| if [ -n "$GPG_KEY_ID" ]; then | |
| # 配置git使用GPG签名 | |
| git config --global user.signingkey "$GPG_KEY_ID" | |
| git config --global commit.gpgsign true | |
| git config --global gpg.program gpg | |
| echo "GPG签名已配置,密钥ID: $GPG_KEY_ID" | |
| else | |
| echo "警告: 无法找到GPG密钥ID" | |
| fi | |
| else | |
| echo "警告: GPG_PRIVATE_KEY环境变量未设置,跳过GPG配置" | |
| fi | |
| echo "Git预配置完成" | |
| env: | |
| SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} | |
| GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} | |
| - name: Run Claude Code | |
| run: | | |
| # 使用bind mount将深层目录映射到根路径,避免软链接被解析 | |
| echo "GITHUB_WORKSPACE: $GITHUB_WORKSPACE" | |
| # 创建/app目录并绑定挂载 | |
| sudo mkdir -p /app | |
| sudo mount --bind "$GITHUB_WORKSPACE" /app | |
| # 切换到简洁的/app目录运行Claude Code | |
| cd /app | |
| echo "当前工作目录: $(pwd)" | |
| echo "运行Claude Code..." | |
| echo "原始任务: $LLM_TASK" | |
| echo "系统提示词长度: ${#SYSTEM_PROMPT} 字符" | |
| # 将JSON上下文写入文件(保存到/app目录) | |
| echo "$LLM_CONTEXT" > /app/context.json | |
| CONTEXT_CHARS=$(wc -m < /app/context.json) | |
| echo "上下文文件大小: $CONTEXT_CHARS 字符" | |
| # 不直接cat内容,避免日志污染 | |
| echo "" | |
| # 构建新任务字符串,包含读取context.json的指示 | |
| ENHANCED_TASK=$(printf "%s\n\n> 任务上下文已保存到/app/context.json,共%s字符。阅读该文件以了解上下文!" "$LLM_TASK" "$CONTEXT_CHARS") | |
| echo "增强任务: $ENHANCED_TASK" | |
| claude \ | |
| -p "$ENHANCED_TASK" \ | |
| --system-prompt "$SYSTEM_PROMPT" \ | |
| --allowedTools "Bash,TaskOutput,Edit,ExitPlanMode,Glob,Grep,KillShell,MCPSearch,NotebookEdit,Read,Skill,Task,TaskCreate,TaskGet,TaskList,TaskUpdate,WebFetch,WebSearch,Write,mcp__ddg-search__*,mcp__context7__*" \ | |
| --output-format=stream-json \ | |
| --verbose | |
| # 自查 | |
| claude \ | |
| -p "请快速自查是否在 GitHub 留下回复,确认是否已有回复,避免重复回复,若无回复,才应当回复。!避免重复回复!另请快速检查工作区,确保所有更改都已经提交并推送(若修改了仓库文件),确保 PR 已存在(若修改了仓库文件),任何未推送的更改都将在此会话结束后被永久销毁!" \ | |
| --system-prompt "$SYSTEM_PROMPT" \ | |
| --allowedTools "Bash,TaskOutput,Edit,ExitPlanMode,Glob,Grep,KillShell,MCPSearch,NotebookEdit,Read,Skill,Task,TaskCreate,TaskGet,TaskList,TaskUpdate,WebFetch,WebSearch,Write,mcp__ddg-search__*,mcp__context7__*" \ | |
| --output-format=stream-json \ | |
| --verbose \ | |
| --continue | |
| # 再次自查 | |
| claude \ | |
| -p "请再次确认:所有更改都已经提交并推送(若修改了文件),并且 PR 已存在(若修改了文件),任何未推送的更改都将在此会话结束后被永久销毁!" \ | |
| --system-prompt "$SYSTEM_PROMPT" \ | |
| --allowedTools "Bash,TaskOutput,Edit,ExitPlanMode,Glob,Grep,KillShell,MCPSearch,NotebookEdit,Read,Skill,Task,TaskCreate,TaskGet,TaskList,TaskUpdate,WebFetch,WebSearch,Write,mcp__ddg-search__*,mcp__context7__*" \ | |
| --output-format=stream-json \ | |
| --verbose \ | |
| --continue |