Compare commits

...
6 changed files with 227 additions and 1 deletions
+1 -1
View File
@@ -51,7 +51,7 @@ def seed_base_models():
pid = 'provider.openai' if m['provider']=='openai' else 'provider.one-api'
exec_sql('''INSERT OR IGNORE INTO llm_models(id,provider_id,owner_username,model_name,display_name,context_window,input_modalities,output_modalities,supports_tools,supports_vision,supports_reasoning,cost_tier,is_base,scope,status,created_at,updated_at) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''', (m['id'], pid, 'system', m['model'], m['display'], m['context'], '["text"]', '["text"]', m['tools'], m['vision'], m['reasoning'], m['tier'], 1, 'global', 'active', now(), now()))
if not one('SELECT * FROM gitops_baseline WHERE id=?', ('current',)):
exec_sql('INSERT INTO gitops_baseline(id,active_version,active_tag,source_package,entry,update_mode,status,created_at,updated_at) VALUES(?,?,?,?,?,?,?,?,?)', ('current','V1R1C0','V1R1C0','AIOS_V1R1C0_MULTIUSER_GITOPS_CUSTOM_LLM_PROD_FULL_DEPLOY_20260706',ENTRY,'git_patch_only','active',now(),now()))
exec_sql('INSERT INTO gitops_baseline(id,active_version,active_tag,source_package,entry,update_mode,status,created_at,updated_at) VALUES(?,?,?,?,?,?,?,?,?)', ('current','V1R1C0','V1R1C0-baseline-20260706','AIOS_V1R1C0_MULTIUSER_GITOPS_CUSTOM_LLM_PROD_FULL_DEPLOY_20260706.zip',ENTRY,'git_patch_only','active',now(),now()))
if not one('SELECT * FROM gitops_versions WHERE version=?', ('V1R1C0',)):
exec_sql('INSERT INTO gitops_versions(version,tag,level,summary,status,created_by,created_at) VALUES(?,?,?,?,?,?,?)', ('V1R1C0','V1R1C0','R','MultiUser runtime selector + GitOps + custom LLM priority registry','ready','system',now()))
+17
View File
@@ -0,0 +1,17 @@
[Unit]
Description=AIOS GitOps Gitea
After=network.target
[Service]
Type=simple
User=aiman
Group=aiman
WorkingDirectory=/data/aios-gitops/runtime/gitea-bin
ExecStart=/data/aios-gitops/runtime/bin/gitea web --config /data/aios-gitops/runtime/gitea-bin/custom/conf/app.ini
Restart=always
RestartSec=3
Environment=USER=aiman
Environment=HOME=/home/aiman
[Install]
WantedBy=multi-user.target
+38
View File
@@ -0,0 +1,38 @@
APP_NAME = AIOS GitOps
RUN_USER = aiman
WORK_PATH = /data/aios-gitops/runtime/gitea-bin
[server]
PROTOCOL = http
HTTP_ADDR = 127.0.0.1
HTTP_PORT = 3000
DOMAIN = cnnetmkt.top
ROOT_URL = https://cnnetmkt.top/git/
SERVE_FROM_SUB_PATH = true
DISABLE_SSH = true
OFFLINE_MODE = false
[database]
DB_TYPE = sqlite3
PATH = /data/aios-gitops/runtime/gitea-bin/data/gitea.db
[repository]
ROOT = /data/aios-gitops/runtime/gitea-bin/data/repositories
DEFAULT_BRANCH = main
[security]
INSTALL_LOCK = true
SECRET_KEY = __SECRET_KEY__
INTERNAL_TOKEN = __INTERNAL_TOKEN__
[service]
DISABLE_REGISTRATION = true
REQUIRE_SIGNIN_VIEW = false
[webhook]
ALLOWED_HOST_LIST = *
[log]
MODE = console
LEVEL = Info
ROOT_PATH = /data/aios-gitops/runtime/gitea-bin/log
+22
View File
@@ -0,0 +1,22 @@
services:
gitea:
image: gitea/gitea:1.22
container_name: aios-gitea
restart: unless-stopped
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__server__DOMAIN=cnnetmkt.top
- GITEA__server__ROOT_URL=https://cnnetmkt.top/git/
- GITEA__server__SERVE_FROM_SUB_PATH=true
- GITEA__server__HTTP_PORT=3000
- GITEA__server__SSH_DOMAIN=cnnetmkt.top
- GITEA__server__SSH_PORT=2222
- GITEA__service__DISABLE_REGISTRATION=true
- GITEA__webhook__ALLOWED_HOST_LIST=*
- GITEA__database__DB_TYPE=sqlite3
volumes:
- /data/aios-gitops/runtime/gitea:/data
ports:
- "127.0.0.1:3000:3000"
- "127.0.0.1:2222:22"
@@ -0,0 +1,20 @@
[Unit]
Description=AIOS V1R1C0 GitOps Model API
After=network.target
[Service]
Type=simple
User=aiman
Group=aiman
Environment=AIOS_GITOPS_ROOT=/data/aios-gitops
Environment=AIOS_GITOPS_WORKSPACE=/data/aios-gitops/workspace
Environment=AIOS_GITOPS_DB=/data/aios-gitops/runtime/gitops_model.sqlite3
Environment=AIOS_GITOPS_TOKEN_FILE=/data/aios-gitops/runtime/secrets/gitops.tokens
Environment=AIOS_GITOPS_HOST=127.0.0.1
Environment=AIOS_GITOPS_PORT=18890
ExecStart=/usr/bin/python3 /data/aios-gitops/workspace/active-runtime/app/aios_gitops_model_api.py
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
+129
View File
@@ -0,0 +1,129 @@
#!/usr/bin/env python3
from __future__ import annotations
import concurrent.futures
import json
import os
import subprocess
import sys
import time
import urllib.request
from pathlib import Path
ROOT = Path("/data/aios-gitops")
WORKSPACE = ROOT / "workspace"
AGENT_DIR = ROOT / "runtime" / "agents"
REPORT = ROOT / "artifacts" / "AIOS_V1R1C0_PARALLEL_AGENT_STATUS.json"
HERMES_EXECUTE = "http://127.0.0.1:18792/internal/hermes/execute"
def run(cmd: str, timeout: int = 90) -> dict:
p = subprocess.run(cmd, shell=True, text=True, capture_output=True, timeout=timeout)
return {
"cmd": cmd,
"returncode": p.returncode,
"stdout": p.stdout[-8000:],
"stderr": p.stderr[-8000:],
}
def hermes_plan(name: str, prompt: str) -> dict:
payload = {
"route_id": f"wx-hermes-{time.strftime('%Y%m%d-%H%M%S')}-{name[:8].replace('_','')}",
"route_target": "hermes",
"route_reason": "explicit_user_prefix",
"channel": "openclaw-weixin",
"source": "server_parallel_agent",
"tenant_id": "cnnetmkt",
"user_id": f"agent:{name}",
"user_prompt": prompt,
}
data = json.dumps(payload, ensure_ascii=False).encode("utf-8")
req = urllib.request.Request(HERMES_EXECUTE, data=data, method="POST", headers={"Content-Type": "application/json"})
try:
with urllib.request.urlopen(req, timeout=45) as resp:
raw = resp.read().decode("utf-8", errors="replace")
return {"ok": resp.status < 300, "status": resp.status, "response": json.loads(raw or "{}")}
except Exception as exc:
return {"ok": False, "error": f"{type(exc).__name__}: {exc}"}
TASKS = {
"git_service_agent": {
"prompt": "AIOS V1R1C0 GitOps: 评估 Gitea 拉取失败后的 Git Web 服务补救方案,要求不直接暴露公网端口。",
"commands": [
"docker ps -a --format '{{.Names}} {{.Image}} {{.Status}} {{.Ports}}' | grep -E '^aios-gitea ' || true",
"docker compose -f /data/aios-gitops/adapters/gitea/docker-compose.yml ps 2>&1 || true",
"docker pull gitea/gitea:1.22 2>&1 | tail -80 || true",
"apt-cache policy cgit gitweb gitea 2>/dev/null | sed -n '1,120p' || true",
],
},
"entry_proxy_agent": {
"prompt": "AIOS V1R1C0 GitOps: 探测 cnnetmkt.top 当前入口代理,区分 NPM 与裸 nginx,并给出最小安全路由方案。",
"commands": [
"sudo ss -lntp | grep -E ':(80|443|3000|18890|18891)' || true",
"ps -ef | grep -Ei 'nginx|npm|proxy-manager|caddy|traefik' | grep -v grep || true",
"sudo nginx -T 2>/tmp/aios-nginx-t.err | grep -nE 'server_name|proxy_pass|cnnetmkt|user.cnnetmkt|git|base|model|run' | head -200 || true",
"cat /tmp/aios-nginx-t.err 2>/dev/null || true",
],
},
"gitops_api_uat_agent": {
"prompt": "AIOS V1R1C0 GitOps: 验证 GitOps API、custom LLM、priority、runtime selector 和 baseline current 状态。",
"commands": [
"curl -fsS http://127.0.0.1:18890/health || true",
"curl -fsS http://127.0.0.1:18890/api/status || true",
"TOKEN=$(head -1 /data/aios-gitops/runtime/secrets/gitops.tokens); curl -fsS -H \"Authorization: Bearer $TOKEN\" -H 'X-AIOS-User: agent-uat' -H 'X-AIOS-Role: owner' -H 'Content-Type: application/json' -d '{\"username\":\"agent-uat\",\"role\":\"owner\",\"tier\":\"ultra\"}' http://127.0.0.1:18890/api/runtime/select || true",
"TOKEN=$(head -1 /data/aios-gitops/runtime/secrets/gitops.tokens); curl -fsS -H \"Authorization: Bearer $TOKEN\" -H 'X-AIOS-User: agent-uat' -H 'X-AIOS-Role: owner' -H 'Content-Type: application/json' -d '{\"provider_name\":\"agent-local-openai-compatible\",\"base_url\":\"http://127.0.0.1:13000/v1\",\"model_name\":\"agent-test-model\",\"display_name\":\"Agent Test Model\",\"priority\":10,\"api_key_secret_ref\":\"secret://llm/agent-uat/pre-provisioned-test\"}' http://127.0.0.1:18890/api/model/custom/add || true",
"TOKEN=$(head -1 /data/aios-gitops/runtime/secrets/gitops.tokens); curl -fsS -H \"Authorization: Bearer $TOKEN\" -H 'X-AIOS-User: agent-uat' -H 'X-AIOS-Role: owner' -H 'Content-Type: application/json' -d '{\"username\":\"agent-uat\"}' http://127.0.0.1:18890/api/model/route/resolve || true",
"grep -R -E 'sk-[A-Za-z0-9_-]{20,}|AIza[0-9A-Za-z_-]{20,}|xox[baprs]-[0-9A-Za-z-]{20,}' -n /data/aios-gitops/workspace /data/aios-gitops/logs 2>/dev/null || true",
],
},
"acceptance_report_agent": {
"prompt": "AIOS V1R1C0 GitOps: 汇总当前部署证据、已完成项、阻塞项,生成验收报告更新建议。",
"commands": [
"cd /data/aios-gitops/workspace && git status --short && git log --oneline -10 && git tag | grep V1R1C0 || true",
"tail -40 /data/aios-gitops/logs/package_contract_check_v1r1c0.log; tail -40 /data/aios-gitops/logs/run_v1r1c0_acceptance.log; tail -40 /data/aios-gitops/logs/package_verify_full.log",
"systemctl is-active aios-gitops-model-api.service aios-hermes-executor.service aios-hermes-router.service openclaw-gateway.service || true",
"openclaw models status --json 2>&1 | head -120 || true",
],
},
}
def execute_agent(name: str, spec: dict) -> dict:
AGENT_DIR.mkdir(parents=True, exist_ok=True)
log_path = AGENT_DIR / f"{name}.json"
started = time.strftime("%Y-%m-%dT%H:%M:%S%z")
result = {
"name": name,
"started_at": started,
"hermes_plan": hermes_plan(name, spec["prompt"]),
"commands": [],
}
for cmd in spec["commands"]:
result["commands"].append(run(cmd))
result["finished_at"] = time.strftime("%Y-%m-%dT%H:%M:%S%z")
result["status"] = "completed"
log_path.write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8")
return result
def main() -> int:
AGENT_DIR.mkdir(parents=True, exist_ok=True)
with concurrent.futures.ThreadPoolExecutor(max_workers=len(TASKS)) as pool:
futures = {pool.submit(execute_agent, name, spec): name for name, spec in TASKS.items()}
results = []
for future in concurrent.futures.as_completed(futures):
results.append(future.result())
summary = {
"generated_at": time.strftime("%Y-%m-%dT%H:%M:%S%z"),
"agent_count": len(results),
"agents": [{"name": r["name"], "status": r["status"], "log": str(AGENT_DIR / f"{r['name']}.json")} for r in results],
}
REPORT.write_text(json.dumps({"summary": summary, "results": results}, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
return 0
if __name__ == "__main__":
raise SystemExit(main())