1 line
14 KiB
JSON
1 line
14 KiB
JSON
{"repo": "aimonj0729-ai/ai-office-landing-skill", "files": {"adapters/deepseek-api.sh": {"edd2c1debdcd1bac39ca52cf777c936d70348522": {"t": 1785745944.7250206, "n": 6211, "h": "41925bb7ec43580d", "c": "#!/bin/bash\nset -euo pipefail\n\n# DeepSeek API Adapter for AI Office Skill\n# 使用 DeepSeek API (OpenAI 兼容格式) 执行 Executor 任务\n# 适用场景:Claude Pro 限额用完后的降级方案,尤其擅长代码生成\n# 适合角色:Frontend (MEDIUM-HIGH), SEO (LOW)\n#\n# 用法:\n# ./adapters/deepseek-api.sh <role> <task_id> <output_path>\n# 例:\n# ./adapters/deepseek-api.sh frontend task3 /project/ai-office/outputs/index.html\n#\n# 环境变量:\n# DEEPSEEK_API_KEY - (必需) DeepSeek API Key\n# DEEPSEEK_BASE_URL - (可选) 默认 https://api.deepseek.com\n# DEEPSEEK_MODEL - (可选) 默认 deepseek-chat (也可用 deepseek-coder)\n\nROLE=\"${1:?\"Error: role is required\"}\"\nTASK_ID=\"${2:?\"Error: task_id is required\"}\"\nOUTPUT_PATH=\"${3:?\"Error: output_path is required\"}\"\n\n# API 配置\nDEEPSEEK_API_KEY=\"${DEEPSEEK_API_KEY:?\"Error: DEEPSEEK_API_KEY environment variable is required\"}\"\nDEEPSEEK_BASE_URL=\"${DEEPSEEK_BASE_URL:-https://api.deepseek.com}\"\nDEEPSEEK_MODEL=\"${DEEPSEEK_MODEL:-deepseek-chat}\"\n\n# 角色→模型自动选择:Frontend 角色默认用 deepseek-coder\nif [[ \"$ROLE\" == \"frontend\" && \"$DEEPSEEK_MODEL\" == \"deepseek-chat\" ]]; then\n DEEPSEEK_MODEL=\"deepseek-coder\"\nfi\n\n# 常量\nSKILL_ROOT=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")/..\" && pwd)\"\nPROMPT_FILE=\"${SKILL_ROOT}/prompts/${ROLE}.md\"\nTASKS_FILE=\"${SKILL_ROOT}/templates/tasks.md\"\n\n# Colors\nif [[ -t 1 ]]; then\n RED='\\033[0;31m'\n GREEN='\\033[0;32m'\n YELLOW='\\033[1;33m'\n BLUE='\\033[0;34m'\n NC='\\033[0m'\nelse\n RED='' GREEN='' YELLOW='' BLUE='' NC=''\nfi\n\nlog() { echo -e \"${BLUE}[adapter/deepseek-api]${NC} $*\" >&2; }\nwarn() { echo -e \"${YELLOW}[adapter/deepseek-api] WARN:${NC} $*\" >&2; }\nerror() { echo -e \"${RED}[adapter/deepseek-api] ERROR:${NC} $*\" >&2; exit 1; }\n\ncheck_file() {\n local file=\"$1\" desc=\"$2\"\n [[ -f \"$file\" ]] || error \"${desc} not found: ${file}\"\n}\n\n# 检查依赖\ncommand -v curl >/dev/null 2>&1 || error \"curl is required but not installed\"\ncommand -v jq >/dev/null 2>&1 || error \"jq is required but not installed\"\n\n# 从 tasks.md 提取当前 task 的定义\nextract_task_def() {\n local task_id=\"$1\"\n awk -v task_id=\"$task_id\" '\n $0 ~ \"^## Task [0-9]+: \" {\n current_task = $0\n in_task = 0\n }\n current_task ~ task_id { in_task = 1 }\n in_task { print }\n in_task && /^---$/ { exit }\n ' \"$TASKS_FILE\"\n}\n\n# 项目目录\nPROJECT_DIR=\"$(pwd)\"\nAI_OFFICE_DIR=\"${PROJECT_DIR}/ai-office\"\n\nlog \"Role: ${ROLE} | Model: ${DEEPSEEK_MODEL}\"\nlog \"Task ID: ${TASK_ID}\"\nlog \"Output: ${OUTPUT_PATH}\"\n\n# 检查必要文件\ncheck_file \"$PROMPT_FILE\" \"Role prompt\"\ncheck_file \"$TASKS_FILE\" \"Tasks template\"\ncheck_file \"$AI_OFFICE_DIR/brief.md\" \"Brief\"\ncheck_file \"$AI_OFFICE_DIR/style-tokens.md\" \"Style tokens\"\n\n# 提取 task 定义\nTASK_DEF=$(extract_task_def \"$TASK_ID\")\n[[ -n \"$TASK_DEF\" ]] || error \"Task definition not found for: $TASK_ID\"\n\n# 组装 prompt — DeepSeek 对结构化 prompt 响应更好\nSYSTEM_PROMPT=\"You are the ${ROLE} executor for AI Office workflow. You produce production-ready output. Be precise, follow the style tokens exactly, and mark any information gaps with [GAP: description].\"\n\nUSER_PROMPT=$(cat <<EOF\n## Context (read-only)\n\n### Brief\n$(cat \"$AI_OFFICE_DIR/brief.md\")\n\n### Style Tokens\n$(cat \"$AI_OFFICE_DIR/style-tokens.md\")\n\n### Your Task Definition\n${TASK_DEF}\n\n### Role Prompt\n$(cat \"$PROMPT_FILE\")\n\n## Instructions\n\n1. Read the Brief and Style Tokens thoroughly\n2. Understand your task definition and acceptance criteria\n3. Generate the output for: ${OUTPUT_PATH}\n4. Follow your role prompt for specific implementation guidance\n5. IMPORTANT: If you encounter information gaps, mark them with [GAP: description]\n6. Ensure all style-related values reference the Style Tokens - do NOT hardcode values\n7. The output should be production-ready\n\n## Output Requirements\n\n- Output the complete content directly\n- Do NOT include meta commentary about the generation process\n- Do NOT wrap the output in markdown code blocks\n- Start directly with the content\n\nBegin generation now.\nEOF\n)\n\n# 构建 JSON 请求体\nREQUEST_BODY=$(jq -n \\\n --arg model \"$DEEPSEEK_MODEL\" \\\n --arg system \"$SYSTEM_PROMPT\" \\\n --arg user \"$USER_PROMPT\" \\\n '{\n model: $model,\n messages: [\n { role: \"system\", content: $system },\n { role: \"user\", content: $user }\n ],\n temperature: 0.7,\n max_tokens: 16384,\n stream: false\n }')\n\n# 创建输出目录\nmkdir -p \"$(dirname \"$OUTPUT_PATH\")\"\n\nlog \"Calling DeepSeek API (${DEEPSEEK_MODEL})...\"\n\n# 调用 API\nRESPONSE_FILE=$(mktemp)\nHTTP_CODE=$(curl -s -w \"%{http_code}\" \\\n -o \"$RESPONSE_FILE\" \\\n -X POST \"${DEEPSEEK_BASE_URL}/chat/completions\" \\\n -H \"Content-Type: application/json\" \\\n -H \"Authorization: Bearer ${DEEPSEEK_API_KEY}\" \\\n -d \"$REQUEST_BODY\" \\\n --max-time 300)\n\n# 检查 HTTP 状态码\nif [[ \"$HTTP_CODE\" -ne 200 ]]; then\n ERROR_MSG=$(jq -r '.error.message // .message // \"Unknown error\"' \"$RESPONSE_FILE\" 2>/dev/null || cat \"$RESPONSE_FILE\")\n rm -f \"$RESPONSE_FILE\"\n error \"DeepSeek API returned HTTP ${HTTP_CODE}: ${ERROR_MSG}\"\nfi\n\n# 提取内容\nCONTENT=$(jq -r '.choices[0].message.content // empty' \"$RESPONSE_FILE\")\nif [[ -z \"$CONTENT\" ]]; then\n rm -f \"$RESPONSE_FILE\"\n error \"DeepSeek API returned empty content\"\nfi\n\n# 提取 token 使用量\nPROMPT_TOKENS=$(jq -r '.usage.prompt_tokens // 0' \"$RESPONSE_FILE\")\nCOMPLETION_TOKENS=$(jq -r '.usage.completion_tokens // 0' \"$RESPONSE_FILE\")\nTOTAL_TOKENS=$(jq -r '.usage.total_tokens // 0' \"$RESPONSE_FILE\")\n\nrm -f \"$RESPONSE_FILE\"\n\n# 写入输出文件\necho \"$CONTENT\" > \"$OUTPUT_PATH\"\nlog \"✓ Output written to ${OUTPUT_PATH}\"\nlog \" Tokens: prompt=${PROMPT_TOKENS} completion=${COMPLETION_TOKENS} total=${TOTAL_TOKENS}\"\n\n# 记录 cost 信息\nCOST_DIR=\"${AI_OFFICE_DIR}/cost\"\nmkdir -p \"$COST_DIR\"\njq -n \\\n --arg adapter \"deepseek-api\" \\\n --arg model \"$DEEPSEEK_MODEL\" \\\n --arg role \"$ROLE\" \\\n --arg task_id \"$TASK_ID\" \\\n --argjson prompt_tokens \"$PROMPT_TOKENS\" \\\n --argjson completion_tokens \"$COMPLETION_TOKENS\" \\\n --argjson total_tokens \"$TOTAL_TOKENS\" \\\n --arg timestamp \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\" \\\n '{\n adapter: $adapter,\n model: $model,\n role: $role,\n task_id: $task_id,\n tokens: { prompt: $prompt_tokens, completion: $completion_tokens, total: $total_tokens },\n timestamp: $timestamp\n }' >> \"${COST_DIR}/usage.jsonl\"\n\n# 标记 adapter 执行状态\necho \"${ROLE}:${TASK_ID}:deepseek-api:${DEEPSEEK_MODEL}\" >> \"${AI_OFFICE_DIR}/.adapter-status\"\n\nlog \"✓ ${ROLE} task completed via DeepSeek API\"\n"}, "dddd2e4f52a6127d48d5c4285e05e6035577a8bd": {"t": 1785758163.4794157, "n": 6211, "h": "41925bb7ec43580d", "c": "#!/bin/bash\nset -euo pipefail\n\n# DeepSeek API Adapter for AI Office Skill\n# 使用 DeepSeek API (OpenAI 兼容格式) 执行 Executor 任务\n# 适用场景:Claude Pro 限额用完后的降级方案,尤其擅长代码生成\n# 适合角色:Frontend (MEDIUM-HIGH), SEO (LOW)\n#\n# 用法:\n# ./adapters/deepseek-api.sh <role> <task_id> <output_path>\n# 例:\n# ./adapters/deepseek-api.sh frontend task3 /project/ai-office/outputs/index.html\n#\n# 环境变量:\n# DEEPSEEK_API_KEY - (必需) DeepSeek API Key\n# DEEPSEEK_BASE_URL - (可选) 默认 https://api.deepseek.com\n# DEEPSEEK_MODEL - (可选) 默认 deepseek-chat (也可用 deepseek-coder)\n\nROLE=\"${1:?\"Error: role is required\"}\"\nTASK_ID=\"${2:?\"Error: task_id is required\"}\"\nOUTPUT_PATH=\"${3:?\"Error: output_path is required\"}\"\n\n# API 配置\nDEEPSEEK_API_KEY=\"${DEEPSEEK_API_KEY:?\"Error: DEEPSEEK_API_KEY environment variable is required\"}\"\nDEEPSEEK_BASE_URL=\"${DEEPSEEK_BASE_URL:-https://api.deepseek.com}\"\nDEEPSEEK_MODEL=\"${DEEPSEEK_MODEL:-deepseek-chat}\"\n\n# 角色→模型自动选择:Frontend 角色默认用 deepseek-coder\nif [[ \"$ROLE\" == \"frontend\" && \"$DEEPSEEK_MODEL\" == \"deepseek-chat\" ]]; then\n DEEPSEEK_MODEL=\"deepseek-coder\"\nfi\n\n# 常量\nSKILL_ROOT=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")/..\" && pwd)\"\nPROMPT_FILE=\"${SKILL_ROOT}/prompts/${ROLE}.md\"\nTASKS_FILE=\"${SKILL_ROOT}/templates/tasks.md\"\n\n# Colors\nif [[ -t 1 ]]; then\n RED='\\033[0;31m'\n GREEN='\\033[0;32m'\n YELLOW='\\033[1;33m'\n BLUE='\\033[0;34m'\n NC='\\033[0m'\nelse\n RED='' GREEN='' YELLOW='' BLUE='' NC=''\nfi\n\nlog() { echo -e \"${BLUE}[adapter/deepseek-api]${NC} $*\" >&2; }\nwarn() { echo -e \"${YELLOW}[adapter/deepseek-api] WARN:${NC} $*\" >&2; }\nerror() { echo -e \"${RED}[adapter/deepseek-api] ERROR:${NC} $*\" >&2; exit 1; }\n\ncheck_file() {\n local file=\"$1\" desc=\"$2\"\n [[ -f \"$file\" ]] || error \"${desc} not found: ${file}\"\n}\n\n# 检查依赖\ncommand -v curl >/dev/null 2>&1 || error \"curl is required but not installed\"\ncommand -v jq >/dev/null 2>&1 || error \"jq is required but not installed\"\n\n# 从 tasks.md 提取当前 task 的定义\nextract_task_def() {\n local task_id=\"$1\"\n awk -v task_id=\"$task_id\" '\n $0 ~ \"^## Task [0-9]+: \" {\n current_task = $0\n in_task = 0\n }\n current_task ~ task_id { in_task = 1 }\n in_task { print }\n in_task && /^---$/ { exit }\n ' \"$TASKS_FILE\"\n}\n\n# 项目目录\nPROJECT_DIR=\"$(pwd)\"\nAI_OFFICE_DIR=\"${PROJECT_DIR}/ai-office\"\n\nlog \"Role: ${ROLE} | Model: ${DEEPSEEK_MODEL}\"\nlog \"Task ID: ${TASK_ID}\"\nlog \"Output: ${OUTPUT_PATH}\"\n\n# 检查必要文件\ncheck_file \"$PROMPT_FILE\" \"Role prompt\"\ncheck_file \"$TASKS_FILE\" \"Tasks template\"\ncheck_file \"$AI_OFFICE_DIR/brief.md\" \"Brief\"\ncheck_file \"$AI_OFFICE_DIR/style-tokens.md\" \"Style tokens\"\n\n# 提取 task 定义\nTASK_DEF=$(extract_task_def \"$TASK_ID\")\n[[ -n \"$TASK_DEF\" ]] || error \"Task definition not found for: $TASK_ID\"\n\n# 组装 prompt — DeepSeek 对结构化 prompt 响应更好\nSYSTEM_PROMPT=\"You are the ${ROLE} executor for AI Office workflow. You produce production-ready output. Be precise, follow the style tokens exactly, and mark any information gaps with [GAP: description].\"\n\nUSER_PROMPT=$(cat <<EOF\n## Context (read-only)\n\n### Brief\n$(cat \"$AI_OFFICE_DIR/brief.md\")\n\n### Style Tokens\n$(cat \"$AI_OFFICE_DIR/style-tokens.md\")\n\n### Your Task Definition\n${TASK_DEF}\n\n### Role Prompt\n$(cat \"$PROMPT_FILE\")\n\n## Instructions\n\n1. Read the Brief and Style Tokens thoroughly\n2. Understand your task definition and acceptance criteria\n3. Generate the output for: ${OUTPUT_PATH}\n4. Follow your role prompt for specific implementation guidance\n5. IMPORTANT: If you encounter information gaps, mark them with [GAP: description]\n6. Ensure all style-related values reference the Style Tokens - do NOT hardcode values\n7. The output should be production-ready\n\n## Output Requirements\n\n- Output the complete content directly\n- Do NOT include meta commentary about the generation process\n- Do NOT wrap the output in markdown code blocks\n- Start directly with the content\n\nBegin generation now.\nEOF\n)\n\n# 构建 JSON 请求体\nREQUEST_BODY=$(jq -n \\\n --arg model \"$DEEPSEEK_MODEL\" \\\n --arg system \"$SYSTEM_PROMPT\" \\\n --arg user \"$USER_PROMPT\" \\\n '{\n model: $model,\n messages: [\n { role: \"system\", content: $system },\n { role: \"user\", content: $user }\n ],\n temperature: 0.7,\n max_tokens: 16384,\n stream: false\n }')\n\n# 创建输出目录\nmkdir -p \"$(dirname \"$OUTPUT_PATH\")\"\n\nlog \"Calling DeepSeek API (${DEEPSEEK_MODEL})...\"\n\n# 调用 API\nRESPONSE_FILE=$(mktemp)\nHTTP_CODE=$(curl -s -w \"%{http_code}\" \\\n -o \"$RESPONSE_FILE\" \\\n -X POST \"${DEEPSEEK_BASE_URL}/chat/completions\" \\\n -H \"Content-Type: application/json\" \\\n -H \"Authorization: Bearer ${DEEPSEEK_API_KEY}\" \\\n -d \"$REQUEST_BODY\" \\\n --max-time 300)\n\n# 检查 HTTP 状态码\nif [[ \"$HTTP_CODE\" -ne 200 ]]; then\n ERROR_MSG=$(jq -r '.error.message // .message // \"Unknown error\"' \"$RESPONSE_FILE\" 2>/dev/null || cat \"$RESPONSE_FILE\")\n rm -f \"$RESPONSE_FILE\"\n error \"DeepSeek API returned HTTP ${HTTP_CODE}: ${ERROR_MSG}\"\nfi\n\n# 提取内容\nCONTENT=$(jq -r '.choices[0].message.content // empty' \"$RESPONSE_FILE\")\nif [[ -z \"$CONTENT\" ]]; then\n rm -f \"$RESPONSE_FILE\"\n error \"DeepSeek API returned empty content\"\nfi\n\n# 提取 token 使用量\nPROMPT_TOKENS=$(jq -r '.usage.prompt_tokens // 0' \"$RESPONSE_FILE\")\nCOMPLETION_TOKENS=$(jq -r '.usage.completion_tokens // 0' \"$RESPONSE_FILE\")\nTOTAL_TOKENS=$(jq -r '.usage.total_tokens // 0' \"$RESPONSE_FILE\")\n\nrm -f \"$RESPONSE_FILE\"\n\n# 写入输出文件\necho \"$CONTENT\" > \"$OUTPUT_PATH\"\nlog \"✓ Output written to ${OUTPUT_PATH}\"\nlog \" Tokens: prompt=${PROMPT_TOKENS} completion=${COMPLETION_TOKENS} total=${TOTAL_TOKENS}\"\n\n# 记录 cost 信息\nCOST_DIR=\"${AI_OFFICE_DIR}/cost\"\nmkdir -p \"$COST_DIR\"\njq -n \\\n --arg adapter \"deepseek-api\" \\\n --arg model \"$DEEPSEEK_MODEL\" \\\n --arg role \"$ROLE\" \\\n --arg task_id \"$TASK_ID\" \\\n --argjson prompt_tokens \"$PROMPT_TOKENS\" \\\n --argjson completion_tokens \"$COMPLETION_TOKENS\" \\\n --argjson total_tokens \"$TOTAL_TOKENS\" \\\n --arg timestamp \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\" \\\n '{\n adapter: $adapter,\n model: $model,\n role: $role,\n task_id: $task_id,\n tokens: { prompt: $prompt_tokens, completion: $completion_tokens, total: $total_tokens },\n timestamp: $timestamp\n }' >> \"${COST_DIR}/usage.jsonl\"\n\n# 标记 adapter 执行状态\necho \"${ROLE}:${TASK_ID}:deepseek-api:${DEEPSEEK_MODEL}\" >> \"${AI_OFFICE_DIR}/.adapter-status\"\n\nlog \"✓ ${ROLE} task completed via DeepSeek API\"\n"}}}} |