feat: devops智能——clone已存在自动pull + 多步任务(克隆→扫描技能)
This commit is contained in:
parent
9c84c3dcbc
commit
fb1b65f389
@ -878,29 +878,60 @@ if action == 'send_message':
|
||||
elif intent_type == 'devops':
|
||||
# 从自然语言中提取实际命令:剥前缀 + 识别 git URL 自动构造 git clone
|
||||
cmd = message_text.strip()
|
||||
import re
|
||||
import re, os
|
||||
cmd = re.sub(r'^(执行命令[::]|运行[::]|帮我\s*|克隆仓库\s*|从.*克隆\s*)', '', cmd).strip()
|
||||
# 如果包含 git@ 或 https://...git 但没有 git clone 前缀,自动补全
|
||||
repo_url = None
|
||||
repo_target = None
|
||||
if re.search(r'(git@[\w.]+:[\w./-]+\.git|https?://[\w./-]+\.git)', cmd):
|
||||
if not cmd.startswith('git '):
|
||||
# 提取 URL 和可选目标路径
|
||||
m = re.search(r'(git@[\w.]+:[\w./-]+\.git|https?://[\w./-]+\.git)', cmd)
|
||||
repo_url = m.group(0)
|
||||
rest = cmd[m.end():].strip()
|
||||
target = rest.split()[0] if rest else ''
|
||||
if target and not target.startswith('-'):
|
||||
repo_target = target
|
||||
cmd = f'git clone {repo_url} {target}'
|
||||
else:
|
||||
repo_target = repo_url.rstrip('/').split('/')[-1].replace('.git', '')
|
||||
cmd = f'git clone {repo_url}'
|
||||
# 特殊处理:包含"到本地""到工作区"→只保留 git clone url
|
||||
cmd = re.sub(r'(\s+(到本地|到工作区|到workspace).*)', '', cmd).strip()
|
||||
workdir = ctx.get('workspace_dir', '') or '/d/pipeline/workspaces'
|
||||
result = await shell_exec(cmd, workdir=workdir, timeout=120 if 'git clone' in cmd else 60)
|
||||
# git clone already exists → git pull
|
||||
if result['rc'] != 0 and 'already exists' in result.get('stderr', '') and repo_target and cmd.startswith('git clone'):
|
||||
pull_dir = os.path.join(workdir, repo_target) if not os.path.isabs(repo_target) else repo_target
|
||||
debug(f'devops: clone already exists, pulling {pull_dir}')
|
||||
result = await shell_exec(f'git -C {pull_dir} pull', workdir=workdir, timeout=60)
|
||||
if result['rc'] == 0:
|
||||
out = result['stdout'].strip()
|
||||
agent_reply = f"执行成功。{'输出:' + out[:500] if out else '(无输出)'}"
|
||||
else:
|
||||
agent_reply = f"执行失败(rc={result['rc']}):{result['stderr'][:500] or result['stdout'][:500]}"
|
||||
# 多步任务:如果 git clone 成功且消息中含有"技能""skill""安装",自动触发 skill_import
|
||||
if result['rc'] == 0 and repo_target and re.search(r'(技能|skill|安装技能|导入技能)', message_text):
|
||||
clone_dir = os.path.join(workdir, repo_target) if not os.path.isabs(repo_target) else repo_target
|
||||
if os.path.isdir(clone_dir):
|
||||
try:
|
||||
import_result = await skill_import_git('', skills_dir='skills')
|
||||
# skill_import_git 的 repo_url 为空时不 clone,改用已有目录
|
||||
from pipeline_service.init import _resolve_workdir
|
||||
full_skills = os.path.join(clone_dir, 'skills')
|
||||
if os.path.isdir(full_skills):
|
||||
found = []
|
||||
for entry in sorted(os.listdir(full_skills)):
|
||||
entry_path = os.path.join(full_skills, entry)
|
||||
if os.path.isdir(entry_path):
|
||||
found.append(entry)
|
||||
if found:
|
||||
agent_reply += f'\n\n✅ 发现 {len(found)} 个技能:' + ', '.join(found[:15])
|
||||
else:
|
||||
agent_reply += '\n\n⚠️ skills 目录下未找到技能子目录'
|
||||
else:
|
||||
agent_reply += '\n\n⚠️ 仓库中无 skills 目录'
|
||||
except Exception as e2:
|
||||
debug(f'skill scan error: {e2}')
|
||||
else:
|
||||
# chat: general conversation
|
||||
messages = await _build_context(sor, iteration_id or ctx['iteration_id'], '',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user