Spaces:
Sleeping
Sleeping
David Prince commited on
Commit ·
cce8120
1
Parent(s): 7ee7487
fix: add all missing local module stubs (remote_mcp_registry, mcp_auth, mcp_transport, etc)
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- 20_inventory_dolor3v.sh +38 -0
- 21_integrate_dolor3v_engine.sh +116 -0
- 22_verify_dolor3v_integration.sh +49 -0
- 23_repair_main_integration.sh +58 -0
- 24_fix_fastapi_constructor.sh +46 -0
- 25_enable_dolor3v_provider.sh +47 -0
- 26_integrate_dolor3v_fastapi.sh +66 -0
- 27_replace_provider_dispatch.sh +56 -0
- 28_verify_dolor3v_runtime.sh +71 -0
- 29_restore_llm_gateway.sh +51 -0
- 30_wire_gateway_to_dolor3v.sh +49 -0
- 31_inspect_orchestrator.sh +32 -0
- 32_build_dolor3v_runtime.sh +33 -0
- 33_build_dolor3v_runtime.sh +131 -0
- 34_fix_runtime_imports.sh +40 -0
- 35_reorder_runtime_imports.sh +46 -0
- 36_fix_runtime_import_block.sh +64 -0
- 37_rebuild_provider_registry.sh +41 -0
- 38_restore_provider_package.sh +51 -0
- 39_inventory_provider_layer.sh +75 -0
- 40_restore_provider_core.sh +62 -0
- 41_rebuild_provider_init.sh +50 -0
- 42_rebuild_fallback_layer.sh +93 -0
- 43_inspect_huggingface_provider.sh +40 -0
- 44_patch_openai_generate.sh +61 -0
- 45_verify_provider_stack.sh +90 -0
- 46_move_runtime_imports.sh +61 -0
- 47_remove_duplicate_gateway_import.sh +52 -0
- 48_verify_fastapi_startup.sh +57 -0
- 49_runtime_endpoint_validation.sh +112 -0
- 50_fix_runtime_validation.sh +105 -0
- agent_logic.py +15 -0
- android_project_generator.py +109 -0
- apk_workflow.py +108 -0
- app_drive_upload.py +82 -0
- backend.log +24 -0
- backend.pid +1 -0
- builder_routes.py +40 -0
- builds.db +0 -0
- builds_e2e.db +0 -0
- builds_test.db +0 -0
- bundle_parser.py +143 -0
- capability_scanner.py +54 -0
- check_env.py +7 -0
- compiler.py +69 -0
- data/agent_memory.db +0 -0
- db_patch.py +105 -0
- deployments.db +0 -0
- deployments_e2e.db +0 -0
- deployments_test.db +0 -0
20_inventory_dolor3v.sh
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -Eeuo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT="/root/projects/website-builder-backend-clean"
|
| 5 |
+
OUT="$ROOT/interrogation/dolor3v_inventory"
|
| 6 |
+
|
| 7 |
+
mkdir -p "$OUT"
|
| 8 |
+
|
| 9 |
+
echo "[1/8] MCP servers..."
|
| 10 |
+
find "$ROOT" -type f | grep -Ei "mcp.*\.(py|json|yaml|yml|ts|js)$" | sort > "$OUT/mcp_servers.txt"
|
| 11 |
+
|
| 12 |
+
echo "[2/8] Agent modules..."
|
| 13 |
+
find "$ROOT/backend" -type f | grep -Ei "agent|planner|orchestrator|workflow|runtime" | sort > "$OUT/agents.txt"
|
| 14 |
+
|
| 15 |
+
echo "[3/8] LLM..."
|
| 16 |
+
find "$ROOT/backend" -type f | grep -Ei "gateway|provider|model|llm" | sort > "$OUT/llm.txt"
|
| 17 |
+
|
| 18 |
+
echo "[4/8] Builder..."
|
| 19 |
+
find "$ROOT/backend" -type f | grep -Ei "builder|build" | sort > "$OUT/builder.txt"
|
| 20 |
+
|
| 21 |
+
echo "[5/8] Workspace..."
|
| 22 |
+
find "$ROOT/backend" -type f | grep -Ei "workspace|session|chat|memory" | sort > "$OUT/workspace.txt"
|
| 23 |
+
|
| 24 |
+
echo "[6/8] MCP registry..."
|
| 25 |
+
grep -RIn "REGISTERED_SERVERS\|mcp_servers\|FastMCP\|tool\(" "$ROOT" > "$OUT/mcp_registry.txt" || true
|
| 26 |
+
|
| 27 |
+
echo "[7/8] Router..."
|
| 28 |
+
grep -RIn "include_router" "$ROOT/backend" > "$OUT/routes.txt" || true
|
| 29 |
+
|
| 30 |
+
echo "[8/8] Summary..."
|
| 31 |
+
|
| 32 |
+
echo "MCP=$(wc -l < "$OUT/mcp_servers.txt")" > "$OUT/summary.txt"
|
| 33 |
+
echo "AGENTS=$(wc -l < "$OUT/agents.txt")" >> "$OUT/summary.txt"
|
| 34 |
+
echo "LLM=$(wc -l < "$OUT/llm.txt")" >> "$OUT/summary.txt"
|
| 35 |
+
echo "BUILDER=$(wc -l < "$OUT/builder.txt")" >> "$OUT/summary.txt"
|
| 36 |
+
echo "WORKSPACE=$(wc -l < "$OUT/workspace.txt")" >> "$OUT/summary.txt"
|
| 37 |
+
|
| 38 |
+
cat "$OUT/summary.txt"
|
21_integrate_dolor3v_engine.sh
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -Eeuo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT="/root/projects/website-builder-backend-clean"
|
| 5 |
+
BACKEND="$ROOT/backend"
|
| 6 |
+
|
| 7 |
+
echo "========================================"
|
| 8 |
+
echo "Dolor3V Production Integration"
|
| 9 |
+
echo "========================================"
|
| 10 |
+
|
| 11 |
+
require() {
|
| 12 |
+
[ -e "$1" ] || {
|
| 13 |
+
echo "Missing: $1"
|
| 14 |
+
exit 1
|
| 15 |
+
}
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
require "$BACKEND/main.py"
|
| 19 |
+
require "$BACKEND/llm/gateway.py"
|
| 20 |
+
|
| 21 |
+
mkdir -p "$ROOT/backups"
|
| 22 |
+
|
| 23 |
+
STAMP="$(date +%Y%m%d-%H%M%S)"
|
| 24 |
+
|
| 25 |
+
cp "$BACKEND/main.py" \
|
| 26 |
+
"$ROOT/backups/main.py.$STAMP"
|
| 27 |
+
|
| 28 |
+
cp "$BACKEND/llm/gateway.py" \
|
| 29 |
+
"$ROOT/backups/gateway.py.$STAMP"
|
| 30 |
+
|
| 31 |
+
python3 <<'PY'
|
| 32 |
+
from pathlib import Path
|
| 33 |
+
|
| 34 |
+
main = Path("backend/main.py")
|
| 35 |
+
text = main.read_text()
|
| 36 |
+
|
| 37 |
+
imports = """
|
| 38 |
+
from backend.agents.orchestrator import Orchestrator
|
| 39 |
+
from backend.llm.gateway import LLMGateway
|
| 40 |
+
"""
|
| 41 |
+
|
| 42 |
+
if "from backend.agents.orchestrator import Orchestrator" not in text:
|
| 43 |
+
idx = text.find("app = FastAPI")
|
| 44 |
+
if idx != -1:
|
| 45 |
+
text = text[:idx] + imports + "\n" + text[idx:]
|
| 46 |
+
|
| 47 |
+
boot = """
|
| 48 |
+
|
| 49 |
+
# -------- Dolor3V Engine --------
|
| 50 |
+
|
| 51 |
+
llm_gateway = LLMGateway()
|
| 52 |
+
dolor3v = Orchestrator(
|
| 53 |
+
gateway=llm_gateway
|
| 54 |
+
)
|
| 55 |
+
|
| 56 |
+
app.state.dolor3v = dolor3v
|
| 57 |
+
|
| 58 |
+
"""
|
| 59 |
+
|
| 60 |
+
if "app.state.dolor3v" not in text:
|
| 61 |
+
idx = text.find("app = FastAPI")
|
| 62 |
+
if idx != -1:
|
| 63 |
+
end = text.find("\n", idx)
|
| 64 |
+
text = text[:end+1] + boot + text[end+1:]
|
| 65 |
+
|
| 66 |
+
main.write_text(text)
|
| 67 |
+
print("Integrated Dolor3V Engine")
|
| 68 |
+
PY
|
| 69 |
+
|
| 70 |
+
python3 <<'PY'
|
| 71 |
+
from pathlib import Path
|
| 72 |
+
|
| 73 |
+
gateway = Path("backend/llm/gateway.py")
|
| 74 |
+
|
| 75 |
+
text = gateway.read_text()
|
| 76 |
+
|
| 77 |
+
REMOVE = [
|
| 78 |
+
"gemini",
|
| 79 |
+
"google.generativeai",
|
| 80 |
+
"GenerativeModel",
|
| 81 |
+
]
|
| 82 |
+
|
| 83 |
+
for token in REMOVE:
|
| 84 |
+
text = text.replace(token, "__REMOVED__")
|
| 85 |
+
|
| 86 |
+
gateway.write_text(text)
|
| 87 |
+
|
| 88 |
+
print("Gemini disabled")
|
| 89 |
+
PY
|
| 90 |
+
|
| 91 |
+
python3 -m compileall backend >/dev/null
|
| 92 |
+
|
| 93 |
+
echo
|
| 94 |
+
echo "========================================"
|
| 95 |
+
echo "Verification"
|
| 96 |
+
echo "========================================"
|
| 97 |
+
|
| 98 |
+
python3 <<'PY'
|
| 99 |
+
import importlib
|
| 100 |
+
|
| 101 |
+
mods = [
|
| 102 |
+
"backend.main",
|
| 103 |
+
"backend.agents.orchestrator",
|
| 104 |
+
"backend.llm.gateway",
|
| 105 |
+
]
|
| 106 |
+
|
| 107 |
+
for m in mods:
|
| 108 |
+
try:
|
| 109 |
+
importlib.import_module(m)
|
| 110 |
+
print("[OK]",m)
|
| 111 |
+
except Exception as e:
|
| 112 |
+
print("[FAIL]",m,e)
|
| 113 |
+
PY
|
| 114 |
+
|
| 115 |
+
echo
|
| 116 |
+
echo "Completed."
|
22_verify_dolor3v_integration.sh
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -uo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT="/root/projects/website-builder-backend-clean"
|
| 5 |
+
|
| 6 |
+
cd "$ROOT"
|
| 7 |
+
|
| 8 |
+
echo "========================================"
|
| 9 |
+
echo "Dolor3V Integration Verification"
|
| 10 |
+
echo "========================================"
|
| 11 |
+
|
| 12 |
+
echo "[1/8] Python syntax..."
|
| 13 |
+
|
| 14 |
+
python3 -m compileall backend
|
| 15 |
+
|
| 16 |
+
STATUS=$?
|
| 17 |
+
|
| 18 |
+
if [ $STATUS -ne 0 ]; then
|
| 19 |
+
echo
|
| 20 |
+
echo "========================================"
|
| 21 |
+
echo "Python compile failed."
|
| 22 |
+
echo "Fix the first syntax/import error before continuing."
|
| 23 |
+
echo "========================================"
|
| 24 |
+
exit $STATUS
|
| 25 |
+
fi
|
| 26 |
+
|
| 27 |
+
echo "[2/8] Import backend.main..."
|
| 28 |
+
python3 -c "import backend.main"
|
| 29 |
+
|
| 30 |
+
echo "[3/8] Import gateway..."
|
| 31 |
+
python3 -c "import backend.llm.gateway"
|
| 32 |
+
|
| 33 |
+
echo "[4/8] Import orchestrator..."
|
| 34 |
+
python3 -c "import backend.agents.orchestrator"
|
| 35 |
+
|
| 36 |
+
echo "[5/8] Verify Dolor3V..."
|
| 37 |
+
grep -n "app.state.dolor3v" backend/main.py
|
| 38 |
+
|
| 39 |
+
echo "[6/8] Gemini..."
|
| 40 |
+
grep -RInE "gemini|google\.generativeai" backend || true
|
| 41 |
+
|
| 42 |
+
echo "[7/8] HuggingFace..."
|
| 43 |
+
grep -RIn "huggingface" backend || true
|
| 44 |
+
|
| 45 |
+
echo "[8/8] Imports..."
|
| 46 |
+
python3 verify_import.py
|
| 47 |
+
|
| 48 |
+
echo
|
| 49 |
+
echo "Verification complete."
|
23_repair_main_integration.sh
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT=/root/projects/website-builder-backend-clean
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
echo "========================================"
|
| 8 |
+
echo "Repair backend/main.py"
|
| 9 |
+
echo "========================================"
|
| 10 |
+
|
| 11 |
+
cp backend/main.py backend/main.py.bak.$(date +%Y%m%d_%H%M%S)
|
| 12 |
+
|
| 13 |
+
python3 <<'PY'
|
| 14 |
+
import pathlib
|
| 15 |
+
import re
|
| 16 |
+
|
| 17 |
+
p = pathlib.Path("backend/main.py")
|
| 18 |
+
src = p.read_text()
|
| 19 |
+
|
| 20 |
+
# Remove broken injected block
|
| 21 |
+
src = re.sub(
|
| 22 |
+
r'app\.state\.dolor3v\s*=.*?LLMGateway\(\)',
|
| 23 |
+
'',
|
| 24 |
+
src,
|
| 25 |
+
flags=re.S
|
| 26 |
+
)
|
| 27 |
+
|
| 28 |
+
# Ensure import exists once
|
| 29 |
+
if "from backend.llm.gateway import LLMGateway" not in src:
|
| 30 |
+
lines = src.splitlines()
|
| 31 |
+
pos = 0
|
| 32 |
+
for i,l in enumerate(lines):
|
| 33 |
+
if l.startswith("from ") or l.startswith("import "):
|
| 34 |
+
pos = i + 1
|
| 35 |
+
lines.insert(pos, "from backend.llm.gateway import LLMGateway")
|
| 36 |
+
src = "\n".join(lines)
|
| 37 |
+
|
| 38 |
+
# Insert initialization after app creation only
|
| 39 |
+
m = re.search(r'app\s*=\s*FastAPI\([^\)]*\)', src)
|
| 40 |
+
if m:
|
| 41 |
+
insert = (
|
| 42 |
+
"\n\n"
|
| 43 |
+
"# Dolor3V AI Runtime\n"
|
| 44 |
+
"app.state.dolor3v = LLMGateway()\n"
|
| 45 |
+
)
|
| 46 |
+
if "app.state.dolor3v" not in src:
|
| 47 |
+
src = src[:m.end()] + insert + src[m.end():]
|
| 48 |
+
|
| 49 |
+
p.write_text(src)
|
| 50 |
+
print("backend/main.py repaired")
|
| 51 |
+
PY
|
| 52 |
+
|
| 53 |
+
echo
|
| 54 |
+
echo "Compiling..."
|
| 55 |
+
python3 -m py_compile backend/main.py
|
| 56 |
+
|
| 57 |
+
echo
|
| 58 |
+
echo "SUCCESS"
|
24_fix_fastapi_constructor.sh
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT=/root/projects/website-builder-backend-clean
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
cp backend/main.py backend/main.py.bak.$(date +%Y%m%d_%H%M%S)
|
| 8 |
+
|
| 9 |
+
python3 <<'PY'
|
| 10 |
+
from pathlib import Path
|
| 11 |
+
import re
|
| 12 |
+
|
| 13 |
+
p=Path("backend/main.py")
|
| 14 |
+
src=p.read_text()
|
| 15 |
+
|
| 16 |
+
pattern=r'app\s*=\s*FastAPI\([\s\S]*?version="1\.0\.0"\s*\)'
|
| 17 |
+
|
| 18 |
+
replacement='''
|
| 19 |
+
app = FastAPI(
|
| 20 |
+
title="Website Builder Agent Backend",
|
| 21 |
+
description="Unified API combining Code Intelligence, Task Execution, Autonomous Builder, MCP JSON-RPC, and Workspace Operations",
|
| 22 |
+
version="1.0.0"
|
| 23 |
+
)
|
| 24 |
+
|
| 25 |
+
# -------- Dolor3V Engine --------
|
| 26 |
+
|
| 27 |
+
llm_gateway = LLMGateway()
|
| 28 |
+
|
| 29 |
+
dolor3v = Orchestrator(
|
| 30 |
+
gateway=llm_gateway
|
| 31 |
+
)
|
| 32 |
+
|
| 33 |
+
app.state.dolor3v = dolor3v
|
| 34 |
+
'''
|
| 35 |
+
|
| 36 |
+
src=re.sub(pattern,replacement,src,count=1)
|
| 37 |
+
|
| 38 |
+
p.write_text(src)
|
| 39 |
+
|
| 40 |
+
print("FastAPI constructor repaired.")
|
| 41 |
+
PY
|
| 42 |
+
|
| 43 |
+
python3 -m py_compile backend/main.py
|
| 44 |
+
|
| 45 |
+
echo
|
| 46 |
+
echo "SUCCESS"
|
25_enable_dolor3v_provider.sh
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT="/root/projects/website-builder-backend-clean"
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
echo "========================================"
|
| 8 |
+
echo "Enable Dolor3V Production Provider"
|
| 9 |
+
echo "========================================"
|
| 10 |
+
|
| 11 |
+
mkdir -p backups
|
| 12 |
+
cp backend/llm/gateway.py backups/gateway.py.$(date +%Y%m%d_%H%M%S)
|
| 13 |
+
|
| 14 |
+
python3 <<'PY'
|
| 15 |
+
from pathlib import Path
|
| 16 |
+
import re
|
| 17 |
+
|
| 18 |
+
p=Path("backend/llm/gateway.py")
|
| 19 |
+
src=p.read_text(encoding="utf-8",errors="ignore")
|
| 20 |
+
|
| 21 |
+
src=re.sub(
|
| 22 |
+
r"(?is).*?class\s+LLMGateway",
|
| 23 |
+
"from backend.agents.orchestrator import Orchestrator\n\nclass LLMGateway",
|
| 24 |
+
src,
|
| 25 |
+
count=1
|
| 26 |
+
)
|
| 27 |
+
|
| 28 |
+
if "self.provider = \"huggingface\"" not in src:
|
| 29 |
+
src=src.replace(
|
| 30 |
+
"def __init__(self",
|
| 31 |
+
"def __init__(self"
|
| 32 |
+
)
|
| 33 |
+
src=src.replace(
|
| 34 |
+
"):",
|
| 35 |
+
"):\n self.provider = \"huggingface\"\n self.orchestrator = Orchestrator()\n",
|
| 36 |
+
1
|
| 37 |
+
)
|
| 38 |
+
|
| 39 |
+
src=src.replace("gemini","huggingface")
|
| 40 |
+
src=src.replace("google.generativeai","")
|
| 41 |
+
|
| 42 |
+
p.write_text(src,encoding="utf-8")
|
| 43 |
+
print("gateway updated")
|
| 44 |
+
PY
|
| 45 |
+
|
| 46 |
+
echo
|
| 47 |
+
echo "[OK] Dolor3V gateway enabled"
|
26_integrate_dolor3v_fastapi.sh
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT="/root/projects/website-builder-backend-clean"
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
echo "========================================"
|
| 8 |
+
echo "Integrating Dolor3V into FastAPI"
|
| 9 |
+
echo "========================================"
|
| 10 |
+
|
| 11 |
+
mkdir -p backups
|
| 12 |
+
cp backend/main.py backups/main.py.$(date +%Y%m%d_%H%M%S)
|
| 13 |
+
|
| 14 |
+
python3 <<'PY'
|
| 15 |
+
from pathlib import Path
|
| 16 |
+
|
| 17 |
+
p=Path("backend/main.py")
|
| 18 |
+
src=p.read_text(encoding="utf-8",errors="ignore")
|
| 19 |
+
|
| 20 |
+
imports=[
|
| 21 |
+
"from backend.llm.gateway import LLMGateway",
|
| 22 |
+
"from backend.agents.orchestrator import Orchestrator"
|
| 23 |
+
]
|
| 24 |
+
|
| 25 |
+
for imp in imports:
|
| 26 |
+
if imp not in src:
|
| 27 |
+
lines=src.splitlines()
|
| 28 |
+
pos=0
|
| 29 |
+
for i,l in enumerate(lines):
|
| 30 |
+
if l.startswith("import ") or l.startswith("from "):
|
| 31 |
+
pos=i+1
|
| 32 |
+
lines.insert(pos,imp)
|
| 33 |
+
src="\n".join(lines)
|
| 34 |
+
|
| 35 |
+
marker="app = FastAPI("
|
| 36 |
+
|
| 37 |
+
if marker in src and "app.state.dolor3v" not in src:
|
| 38 |
+
|
| 39 |
+
start=src.index(marker)
|
| 40 |
+
end=src.index(")",start)+1
|
| 41 |
+
|
| 42 |
+
init="""
|
| 43 |
+
|
| 44 |
+
# -------------------------------
|
| 45 |
+
# Dolor3V Runtime
|
| 46 |
+
# -------------------------------
|
| 47 |
+
llm_gateway=LLMGateway()
|
| 48 |
+
dolor3v=Orchestrator(
|
| 49 |
+
gateway=llm_gateway
|
| 50 |
+
)
|
| 51 |
+
|
| 52 |
+
app.state.dolor3v=dolor3v
|
| 53 |
+
|
| 54 |
+
"""
|
| 55 |
+
|
| 56 |
+
src=src[:end]+init+src[end:]
|
| 57 |
+
|
| 58 |
+
p.write_text(src,encoding="utf-8")
|
| 59 |
+
print("FastAPI integration completed")
|
| 60 |
+
PY
|
| 61 |
+
|
| 62 |
+
echo
|
| 63 |
+
python3 -m py_compile backend/main.py
|
| 64 |
+
|
| 65 |
+
echo
|
| 66 |
+
echo "[OK] Dolor3V attached to FastAPI app.state"
|
27_replace_provider_dispatch.sh
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT="/root/projects/website-builder-backend-clean"
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
echo "========================================"
|
| 8 |
+
echo "Replacing Provider Dispatch"
|
| 9 |
+
echo "========================================"
|
| 10 |
+
|
| 11 |
+
mkdir -p backups
|
| 12 |
+
cp -a backend/llm/providers backups/providers.$(date +%Y%m%d_%H%M%S)
|
| 13 |
+
|
| 14 |
+
python3 <<'PY'
|
| 15 |
+
from pathlib import Path
|
| 16 |
+
|
| 17 |
+
providers=Path("backend/llm/providers")
|
| 18 |
+
|
| 19 |
+
replacement='''
|
| 20 |
+
from backend.llm.gateway import LLMGateway
|
| 21 |
+
|
| 22 |
+
_gateway = LLMGateway()
|
| 23 |
+
|
| 24 |
+
async def generate(
|
| 25 |
+
model: str,
|
| 26 |
+
prompt: str,
|
| 27 |
+
**kwargs
|
| 28 |
+
):
|
| 29 |
+
return await _gateway.generate(
|
| 30 |
+
model=model,
|
| 31 |
+
prompt=prompt,
|
| 32 |
+
**kwargs
|
| 33 |
+
)
|
| 34 |
+
'''
|
| 35 |
+
|
| 36 |
+
patched=0
|
| 37 |
+
|
| 38 |
+
for f in providers.glob("*.py"):
|
| 39 |
+
|
| 40 |
+
if f.name=="__init__.py":
|
| 41 |
+
continue
|
| 42 |
+
|
| 43 |
+
if f.name.startswith("_"):
|
| 44 |
+
continue
|
| 45 |
+
|
| 46 |
+
f.write_text(replacement,encoding="utf-8")
|
| 47 |
+
patched+=1
|
| 48 |
+
|
| 49 |
+
print(f"Providers replaced: {patched}")
|
| 50 |
+
PY
|
| 51 |
+
|
| 52 |
+
echo
|
| 53 |
+
python3 -m compileall backend/llm
|
| 54 |
+
|
| 55 |
+
echo
|
| 56 |
+
echo "[OK] Provider dispatch unified through Dolor3V gateway"
|
28_verify_dolor3v_runtime.sh
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT="/root/projects/website-builder-backend-clean"
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
echo "========================================"
|
| 8 |
+
echo "Dolor3V Runtime Verification"
|
| 9 |
+
echo "========================================"
|
| 10 |
+
|
| 11 |
+
echo
|
| 12 |
+
echo "[1/10] Compile backend..."
|
| 13 |
+
python3 -m compileall backend
|
| 14 |
+
|
| 15 |
+
echo
|
| 16 |
+
echo "[2/10] Verify gateway..."
|
| 17 |
+
python3 - <<'PY'
|
| 18 |
+
from backend.llm.gateway import LLMGateway
|
| 19 |
+
g=LLMGateway()
|
| 20 |
+
print(type(g).__name__)
|
| 21 |
+
PY
|
| 22 |
+
|
| 23 |
+
echo
|
| 24 |
+
echo "[3/10] Verify orchestrator..."
|
| 25 |
+
python3 - <<'PY'
|
| 26 |
+
from backend.agents.orchestrator import Orchestrator
|
| 27 |
+
o=Orchestrator()
|
| 28 |
+
print(type(o).__name__)
|
| 29 |
+
PY
|
| 30 |
+
|
| 31 |
+
echo
|
| 32 |
+
echo "[4/10] Verify FastAPI..."
|
| 33 |
+
python3 - <<'PY'
|
| 34 |
+
import backend.main
|
| 35 |
+
print("Dolor3V:",hasattr(backend.main.app.state,"dolor3v"))
|
| 36 |
+
PY
|
| 37 |
+
|
| 38 |
+
echo
|
| 39 |
+
echo "[5/10] Verify provider registry..."
|
| 40 |
+
python3 - <<'PY'
|
| 41 |
+
from pathlib import Path
|
| 42 |
+
|
| 43 |
+
for p in sorted(Path("backend/llm/providers").glob("*.py")):
|
| 44 |
+
if p.name!="__init__.py":
|
| 45 |
+
print(p.name)
|
| 46 |
+
PY
|
| 47 |
+
|
| 48 |
+
echo
|
| 49 |
+
echo "[6/10] Verify MCP..."
|
| 50 |
+
find backend/mcp -type f | wc -l
|
| 51 |
+
|
| 52 |
+
echo
|
| 53 |
+
echo "[7/10] Verify agents..."
|
| 54 |
+
find backend/agents -type f | wc -l
|
| 55 |
+
|
| 56 |
+
echo
|
| 57 |
+
echo "[8/10] Verify builder..."
|
| 58 |
+
find backend/builder -type f | wc -l
|
| 59 |
+
|
| 60 |
+
echo
|
| 61 |
+
echo "[9/10] Verify workspace..."
|
| 62 |
+
find backend/workspace -type f | wc -l
|
| 63 |
+
|
| 64 |
+
echo
|
| 65 |
+
echo "[10/10] Imports..."
|
| 66 |
+
python3 verify_import.py
|
| 67 |
+
|
| 68 |
+
echo
|
| 69 |
+
echo "========================================"
|
| 70 |
+
echo "Dolor3V Runtime Verified"
|
| 71 |
+
echo "========================================"
|
29_restore_llm_gateway.sh
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT="/root/projects/website-builder-backend-clean"
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
echo "========================================"
|
| 8 |
+
echo "Restore LLM Gateway"
|
| 9 |
+
echo "========================================"
|
| 10 |
+
|
| 11 |
+
echo
|
| 12 |
+
echo "[1/4] Locate gateway..."
|
| 13 |
+
|
| 14 |
+
grep -RIn "^class .*Gateway" backend/llm backend/models backend/agents || true
|
| 15 |
+
|
| 16 |
+
echo
|
| 17 |
+
echo "[2/4] Check backup..."
|
| 18 |
+
|
| 19 |
+
find backups -type f -name "gateway.py*" | sort
|
| 20 |
+
|
| 21 |
+
LATEST=$(find backups -type f -name "gateway.py*" | sort | tail -1)
|
| 22 |
+
|
| 23 |
+
if [ -z "$LATEST" ]; then
|
| 24 |
+
echo
|
| 25 |
+
echo "ERROR: No gateway backup found."
|
| 26 |
+
exit 1
|
| 27 |
+
fi
|
| 28 |
+
|
| 29 |
+
echo
|
| 30 |
+
echo "[3/4] Restoring..."
|
| 31 |
+
cp "$LATEST" backend/llm/gateway.py
|
| 32 |
+
|
| 33 |
+
echo
|
| 34 |
+
echo "[4/4] Verify..."
|
| 35 |
+
python3 -m py_compile backend/llm/gateway.py
|
| 36 |
+
|
| 37 |
+
python3 <<'PY'
|
| 38 |
+
import importlib
|
| 39 |
+
|
| 40 |
+
m=importlib.import_module("backend.llm.gateway")
|
| 41 |
+
|
| 42 |
+
print("Module :",m)
|
| 43 |
+
|
| 44 |
+
print("Exports:")
|
| 45 |
+
for n in sorted(dir(m)):
|
| 46 |
+
if not n.startswith("_"):
|
| 47 |
+
print(" ",n)
|
| 48 |
+
PY
|
| 49 |
+
|
| 50 |
+
echo
|
| 51 |
+
echo "Gateway restored successfully."
|
30_wire_gateway_to_dolor3v.sh
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT=/root/projects/website-builder-backend-clean
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
echo "========================================"
|
| 8 |
+
echo "Wire Dolor3V Runtime"
|
| 9 |
+
echo "========================================"
|
| 10 |
+
|
| 11 |
+
cp backend/main.py backend/main.py.bak.$(date +%Y%m%d_%H%M%S)
|
| 12 |
+
|
| 13 |
+
python3 <<'PY'
|
| 14 |
+
from pathlib import Path
|
| 15 |
+
import re
|
| 16 |
+
|
| 17 |
+
p=Path("backend/main.py")
|
| 18 |
+
src=p.read_text()
|
| 19 |
+
|
| 20 |
+
src=src.replace(
|
| 21 |
+
"from backend.llm.gateway import LLMGateway",
|
| 22 |
+
"from backend.llm.gateway import ModelGateway"
|
| 23 |
+
)
|
| 24 |
+
|
| 25 |
+
src=src.replace(
|
| 26 |
+
"llm_gateway=LLMGateway()",
|
| 27 |
+
"llm_gateway=ModelGateway()"
|
| 28 |
+
)
|
| 29 |
+
|
| 30 |
+
src=src.replace(
|
| 31 |
+
"llm_gateway = LLMGateway()",
|
| 32 |
+
"llm_gateway = ModelGateway()"
|
| 33 |
+
)
|
| 34 |
+
|
| 35 |
+
p.write_text(src)
|
| 36 |
+
print("main.py updated")
|
| 37 |
+
PY
|
| 38 |
+
|
| 39 |
+
echo
|
| 40 |
+
python3 -m py_compile backend/main.py
|
| 41 |
+
|
| 42 |
+
echo
|
| 43 |
+
python3 <<'PY'
|
| 44 |
+
import backend.main
|
| 45 |
+
print(type(backend.main.llm_gateway).__name__)
|
| 46 |
+
PY
|
| 47 |
+
|
| 48 |
+
echo
|
| 49 |
+
echo "[OK] ModelGateway wired into Dolor3V runtime."
|
31_inspect_orchestrator.sh
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT=/root/projects/website-builder-backend-clean
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
echo "========================================"
|
| 8 |
+
echo "Inspect Dolor3V Orchestrator"
|
| 9 |
+
echo "========================================"
|
| 10 |
+
|
| 11 |
+
echo
|
| 12 |
+
echo "[1/6] Constructor"
|
| 13 |
+
grep -n "^class Orchestrator" -A80 backend/agents/orchestrator.py
|
| 14 |
+
|
| 15 |
+
echo
|
| 16 |
+
echo "[2/6] Memory"
|
| 17 |
+
grep -RIn "class .*Memory" backend/agents backend/memory
|
| 18 |
+
|
| 19 |
+
echo
|
| 20 |
+
echo "[3/6] Event Bus"
|
| 21 |
+
grep -RInE "class .*Bus|class .*EventBus|class .*MessageBus" backend
|
| 22 |
+
|
| 23 |
+
echo
|
| 24 |
+
echo "[4/6] Agent Factory"
|
| 25 |
+
grep -RInE "class .*Factory|agent_factory|AgentFactory" backend
|
| 26 |
+
|
| 27 |
+
echo
|
| 28 |
+
echo "[5/6] Existing Orchestrator() calls"
|
| 29 |
+
grep -RIn "Orchestrator(" backend
|
| 30 |
+
|
| 31 |
+
echo
|
| 32 |
+
echo "[6/6] Finished"
|
32_build_dolor3v_runtime.sh
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT=/root/projects/website-builder-backend-clean
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
echo "========================================"
|
| 8 |
+
echo "Inspect Dolor3V Runtime Dependencies"
|
| 9 |
+
echo "========================================"
|
| 10 |
+
|
| 11 |
+
echo
|
| 12 |
+
echo "[1/5] AgentMemoryStore"
|
| 13 |
+
grep -RIn "AgentMemoryStore(" backend | grep -v "__pycache__" || true
|
| 14 |
+
|
| 15 |
+
echo
|
| 16 |
+
echo "[2/5] MessageBus"
|
| 17 |
+
grep -RIn "MessageBus(" backend | grep -v "__pycache__" || true
|
| 18 |
+
|
| 19 |
+
echo
|
| 20 |
+
echo "[3/5] agent_factory"
|
| 21 |
+
grep -RIn "def .*agent_factory" backend || true
|
| 22 |
+
grep -RIn "agent_factory =" backend || true
|
| 23 |
+
|
| 24 |
+
echo
|
| 25 |
+
echo "[4/5] BaseAgent"
|
| 26 |
+
grep -RIn "BaseAgent" backend/agents || true
|
| 27 |
+
|
| 28 |
+
echo
|
| 29 |
+
echo "[5/5] Runtime builders"
|
| 30 |
+
grep -RIn "Orchestrator(" backend | grep -v main.py || true
|
| 31 |
+
|
| 32 |
+
echo
|
| 33 |
+
echo "Inspection complete."
|
33_build_dolor3v_runtime.sh
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT="/root/projects/website-builder-backend-clean"
|
| 5 |
+
|
| 6 |
+
cd "$ROOT"
|
| 7 |
+
|
| 8 |
+
echo "========================================"
|
| 9 |
+
echo "Build Dolor3V Runtime"
|
| 10 |
+
echo "========================================"
|
| 11 |
+
|
| 12 |
+
python3 <<'PY'
|
| 13 |
+
import pathlib
|
| 14 |
+
import re
|
| 15 |
+
|
| 16 |
+
main = pathlib.Path("backend/main.py")
|
| 17 |
+
src = main.read_text()
|
| 18 |
+
|
| 19 |
+
# Remove every previous runtime block.
|
| 20 |
+
src = re.sub(
|
| 21 |
+
r'llm_gateway\s*=\s*ModelGateway\(\).*?app\.state\.dolor3v\s*=\s*dolor3v',
|
| 22 |
+
'',
|
| 23 |
+
src,
|
| 24 |
+
flags=re.S,
|
| 25 |
+
)
|
| 26 |
+
|
| 27 |
+
imports = [
|
| 28 |
+
"from backend.models.gateway import ModelGateway",
|
| 29 |
+
"from backend.agents.memory import AgentMemoryStore",
|
| 30 |
+
"from backend.agents.messaging import MessageBus",
|
| 31 |
+
"from backend.agents.base import BaseAgent",
|
| 32 |
+
"from backend.agents.orchestrator import Orchestrator",
|
| 33 |
+
]
|
| 34 |
+
|
| 35 |
+
lines = src.splitlines()
|
| 36 |
+
|
| 37 |
+
for imp in imports:
|
| 38 |
+
if imp not in src:
|
| 39 |
+
pos = 0
|
| 40 |
+
for i,l in enumerate(lines):
|
| 41 |
+
if l.startswith("from ") or l.startswith("import "):
|
| 42 |
+
pos = i + 1
|
| 43 |
+
lines.insert(pos, imp)
|
| 44 |
+
|
| 45 |
+
src = "\n".join(lines)
|
| 46 |
+
|
| 47 |
+
runtime = '''
|
| 48 |
+
|
| 49 |
+
# ---------------- Dolor3V Runtime ----------------
|
| 50 |
+
|
| 51 |
+
llm_gateway = ModelGateway()
|
| 52 |
+
|
| 53 |
+
memory = AgentMemoryStore()
|
| 54 |
+
|
| 55 |
+
bus = MessageBus()
|
| 56 |
+
|
| 57 |
+
class RuntimeAgent(BaseAgent):
|
| 58 |
+
|
| 59 |
+
async def run(self, prompt: str, **kwargs):
|
| 60 |
+
return await llm_gateway.generate(prompt=prompt)
|
| 61 |
+
|
| 62 |
+
def agent_factory(agent_id: str, role: str):
|
| 63 |
+
return RuntimeAgent(
|
| 64 |
+
agent_id=agent_id,
|
| 65 |
+
role=role,
|
| 66 |
+
gateway=llm_gateway,
|
| 67 |
+
memory=memory,
|
| 68 |
+
bus=bus,
|
| 69 |
+
)
|
| 70 |
+
|
| 71 |
+
dolor3v = Orchestrator(
|
| 72 |
+
gateway=llm_gateway,
|
| 73 |
+
memory=memory,
|
| 74 |
+
bus=bus,
|
| 75 |
+
agent_factory=agent_factory,
|
| 76 |
+
)
|
| 77 |
+
|
| 78 |
+
app.state.dolor3v = dolor3v
|
| 79 |
+
|
| 80 |
+
# -------------------------------------------------
|
| 81 |
+
|
| 82 |
+
'''
|
| 83 |
+
|
| 84 |
+
m = re.search(r'app\s*=\s*FastAPI\s*\([^)]*\)', src, re.S)
|
| 85 |
+
|
| 86 |
+
if not m:
|
| 87 |
+
raise RuntimeError("FastAPI() constructor not found")
|
| 88 |
+
|
| 89 |
+
src = src[:m.end()] + runtime + src[m.end():]
|
| 90 |
+
|
| 91 |
+
main.write_text(src)
|
| 92 |
+
|
| 93 |
+
print("Runtime generated.")
|
| 94 |
+
PY
|
| 95 |
+
|
| 96 |
+
echo
|
| 97 |
+
echo "[1/5] Compile"
|
| 98 |
+
python3 -m py_compile backend/main.py
|
| 99 |
+
|
| 100 |
+
echo
|
| 101 |
+
echo "[2/5] Import"
|
| 102 |
+
python3 <<'PY'
|
| 103 |
+
import backend.main
|
| 104 |
+
print(type(backend.main.dolor3v).__name__)
|
| 105 |
+
PY
|
| 106 |
+
|
| 107 |
+
echo
|
| 108 |
+
echo "[3/5] Gateway"
|
| 109 |
+
python3 <<'PY'
|
| 110 |
+
from backend.models.gateway import ModelGateway
|
| 111 |
+
print(ModelGateway)
|
| 112 |
+
PY
|
| 113 |
+
|
| 114 |
+
echo
|
| 115 |
+
echo "[4/5] Memory"
|
| 116 |
+
python3 <<'PY'
|
| 117 |
+
from backend.agents.memory import AgentMemoryStore
|
| 118 |
+
print(AgentMemoryStore)
|
| 119 |
+
PY
|
| 120 |
+
|
| 121 |
+
echo
|
| 122 |
+
echo "[5/5] Bus"
|
| 123 |
+
python3 <<'PY'
|
| 124 |
+
from backend.agents.messaging import MessageBus
|
| 125 |
+
print(MessageBus)
|
| 126 |
+
PY
|
| 127 |
+
|
| 128 |
+
echo
|
| 129 |
+
echo "========================================"
|
| 130 |
+
echo "Dolor3V Runtime Ready"
|
| 131 |
+
echo "========================================"
|
34_fix_runtime_imports.sh
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT=/root/projects/website-builder-backend-clean
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
python3 <<'PY'
|
| 8 |
+
from pathlib import Path
|
| 9 |
+
|
| 10 |
+
p = Path("backend/main.py")
|
| 11 |
+
lines = p.read_text().splitlines()
|
| 12 |
+
|
| 13 |
+
required = [
|
| 14 |
+
"from backend.models.gateway import ModelGateway",
|
| 15 |
+
"from backend.agents.memory import AgentMemoryStore",
|
| 16 |
+
"from backend.agents.messaging import MessageBus",
|
| 17 |
+
"from backend.agents.base import BaseAgent",
|
| 18 |
+
"from backend.agents.orchestrator import Orchestrator",
|
| 19 |
+
]
|
| 20 |
+
|
| 21 |
+
existing = set(lines)
|
| 22 |
+
|
| 23 |
+
insert_at = 0
|
| 24 |
+
for i, line in enumerate(lines):
|
| 25 |
+
if line.startswith("import ") or line.startswith("from "):
|
| 26 |
+
insert_at = i + 1
|
| 27 |
+
|
| 28 |
+
for stmt in reversed(required):
|
| 29 |
+
if stmt not in existing:
|
| 30 |
+
lines.insert(insert_at, stmt)
|
| 31 |
+
|
| 32 |
+
p.write_text("\n".join(lines) + "\n")
|
| 33 |
+
print("Imports repaired.")
|
| 34 |
+
PY
|
| 35 |
+
|
| 36 |
+
echo
|
| 37 |
+
python3 -m py_compile backend/main.py
|
| 38 |
+
|
| 39 |
+
echo
|
| 40 |
+
grep -n "AgentMemoryStore\|MessageBus\|ModelGateway" backend/main.py
|
35_reorder_runtime_imports.sh
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT=/root/projects/website-builder-backend-clean
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
python3 <<'PY'
|
| 8 |
+
from pathlib import Path
|
| 9 |
+
|
| 10 |
+
p=Path("backend/main.py")
|
| 11 |
+
lines=p.read_text().splitlines()
|
| 12 |
+
|
| 13 |
+
targets=[
|
| 14 |
+
"from backend.models.gateway import ModelGateway",
|
| 15 |
+
"from backend.agents.memory import AgentMemoryStore",
|
| 16 |
+
"from backend.agents.messaging import MessageBus",
|
| 17 |
+
]
|
| 18 |
+
|
| 19 |
+
# remove duplicates
|
| 20 |
+
new=[]
|
| 21 |
+
seen=set()
|
| 22 |
+
for line in lines:
|
| 23 |
+
if line in targets:
|
| 24 |
+
if line in seen:
|
| 25 |
+
continue
|
| 26 |
+
seen.add(line)
|
| 27 |
+
continue
|
| 28 |
+
new.append(line)
|
| 29 |
+
|
| 30 |
+
insert=0
|
| 31 |
+
for i,l in enumerate(new):
|
| 32 |
+
if l.startswith("import ") or l.startswith("from "):
|
| 33 |
+
insert=i+1
|
| 34 |
+
|
| 35 |
+
for stmt in reversed(targets):
|
| 36 |
+
new.insert(insert,stmt)
|
| 37 |
+
|
| 38 |
+
p.write_text("\n".join(new)+"\n")
|
| 39 |
+
print("Imports reordered.")
|
| 40 |
+
PY
|
| 41 |
+
|
| 42 |
+
echo
|
| 43 |
+
python3 -m py_compile backend/main.py
|
| 44 |
+
|
| 45 |
+
echo
|
| 46 |
+
nl -ba backend/main.py | sed -n '35,70p'
|
36_fix_runtime_import_block.sh
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT=/root/projects/website-builder-backend-clean
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
cp backend/main.py backend/main.py.bak.$(date +%Y%m%d_%H%M%S)
|
| 8 |
+
|
| 9 |
+
python3 <<'PY'
|
| 10 |
+
from pathlib import Path
|
| 11 |
+
|
| 12 |
+
p=Path("backend/main.py")
|
| 13 |
+
lines=p.read_text().splitlines()
|
| 14 |
+
|
| 15 |
+
required=[
|
| 16 |
+
"from backend.models.gateway import ModelGateway",
|
| 17 |
+
"from backend.agents.memory import AgentMemoryStore",
|
| 18 |
+
"from backend.agents.messaging import MessageBus",
|
| 19 |
+
"from backend.agents.base import BaseAgent",
|
| 20 |
+
]
|
| 21 |
+
|
| 22 |
+
# remove duplicates
|
| 23 |
+
clean=[]
|
| 24 |
+
for line in lines:
|
| 25 |
+
if line in required:
|
| 26 |
+
continue
|
| 27 |
+
clean.append(line)
|
| 28 |
+
|
| 29 |
+
insert=0
|
| 30 |
+
for i,line in enumerate(clean):
|
| 31 |
+
if line.startswith("import ") or line.startswith("from "):
|
| 32 |
+
insert=i+1
|
| 33 |
+
|
| 34 |
+
for stmt in reversed(required):
|
| 35 |
+
clean.insert(insert,stmt)
|
| 36 |
+
|
| 37 |
+
p.write_text("\n".join(clean)+"\n")
|
| 38 |
+
print("Import block repaired.")
|
| 39 |
+
PY
|
| 40 |
+
|
| 41 |
+
echo
|
| 42 |
+
echo "========== IMPORTS =========="
|
| 43 |
+
nl -ba backend/main.py | sed -n '35,55p'
|
| 44 |
+
|
| 45 |
+
echo
|
| 46 |
+
echo "========== COMPILE =========="
|
| 47 |
+
python3 -m py_compile backend/main.py
|
| 48 |
+
|
| 49 |
+
echo
|
| 50 |
+
echo "========== VERIFY =========="
|
| 51 |
+
python3 <<'PY'
|
| 52 |
+
from backend.agents.memory import AgentMemoryStore
|
| 53 |
+
from backend.agents.messaging import MessageBus
|
| 54 |
+
from backend.agents.base import BaseAgent
|
| 55 |
+
from backend.models.gateway import ModelGateway
|
| 56 |
+
|
| 57 |
+
print("AgentMemoryStore:",AgentMemoryStore)
|
| 58 |
+
print("MessageBus:",MessageBus)
|
| 59 |
+
print("BaseAgent:",BaseAgent)
|
| 60 |
+
print("ModelGateway:",ModelGateway)
|
| 61 |
+
PY
|
| 62 |
+
|
| 63 |
+
echo
|
| 64 |
+
echo "[OK] Runtime import block repaired."
|
37_rebuild_provider_registry.sh
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT=/root/projects/website-builder-backend-clean
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
echo "========================================"
|
| 8 |
+
echo "Rebuilding Provider Registry"
|
| 9 |
+
echo "========================================"
|
| 10 |
+
|
| 11 |
+
cat > backend/llm/provider_registry.py <<'PY'
|
| 12 |
+
from backend.llm.providers.huggingface import HuggingFaceProvider
|
| 13 |
+
|
| 14 |
+
_PROVIDER = HuggingFaceProvider()
|
| 15 |
+
|
| 16 |
+
def get_provider():
|
| 17 |
+
return _PROVIDER
|
| 18 |
+
|
| 19 |
+
def get_provider_by_name(name: str):
|
| 20 |
+
return _PROVIDER
|
| 21 |
+
|
| 22 |
+
def list_providers():
|
| 23 |
+
return [{
|
| 24 |
+
"provider_id": "huggingface",
|
| 25 |
+
"provider_type": "huggingface",
|
| 26 |
+
"enabled": True
|
| 27 |
+
}]
|
| 28 |
+
PY
|
| 29 |
+
|
| 30 |
+
echo
|
| 31 |
+
python3 -m py_compile backend/llm/provider_registry.py
|
| 32 |
+
|
| 33 |
+
echo
|
| 34 |
+
python3 <<'PY'
|
| 35 |
+
from backend.llm.provider_registry import list_providers
|
| 36 |
+
|
| 37 |
+
print(list_providers())
|
| 38 |
+
PY
|
| 39 |
+
|
| 40 |
+
echo
|
| 41 |
+
echo "[OK] HuggingFace is now the only registered provider."
|
38_restore_provider_package.sh
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT=/root/projects/website-builder-backend-clean
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
echo "========================================"
|
| 8 |
+
echo "Restore Provider Package"
|
| 9 |
+
echo "========================================"
|
| 10 |
+
|
| 11 |
+
BACKUP=$(find backend/llm/providers \
|
| 12 |
+
-name "__init__.py.bak*" \
|
| 13 |
+
| sort | tail -1)
|
| 14 |
+
|
| 15 |
+
if [ -z "$BACKUP" ]; then
|
| 16 |
+
echo "No backup found."
|
| 17 |
+
exit 1
|
| 18 |
+
fi
|
| 19 |
+
|
| 20 |
+
cp "$BACKUP" backend/llm/providers/__init__.py
|
| 21 |
+
|
| 22 |
+
python3 <<'PY'
|
| 23 |
+
from pathlib import Path
|
| 24 |
+
|
| 25 |
+
providers = Path("backend/llm/providers")
|
| 26 |
+
|
| 27 |
+
missing=[]
|
| 28 |
+
|
| 29 |
+
required=[
|
| 30 |
+
"base.py",
|
| 31 |
+
"huggingface.py",
|
| 32 |
+
"fallback.py",
|
| 33 |
+
"model_registry.py",
|
| 34 |
+
]
|
| 35 |
+
|
| 36 |
+
for f in required:
|
| 37 |
+
if not (providers/f).exists():
|
| 38 |
+
missing.append(f)
|
| 39 |
+
|
| 40 |
+
print("Missing:",missing)
|
| 41 |
+
PY
|
| 42 |
+
|
| 43 |
+
echo
|
| 44 |
+
echo "Searching backups..."
|
| 45 |
+
|
| 46 |
+
find backend -name "base.py*" | sort
|
| 47 |
+
|
| 48 |
+
echo
|
| 49 |
+
echo "========================================"
|
| 50 |
+
echo "Restore complete"
|
| 51 |
+
echo "========================================"
|
39_inventory_provider_layer.sh
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT=/root/projects/website-builder-backend-clean
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
echo "========================================"
|
| 8 |
+
echo "Dolor3V Provider Layer Inventory"
|
| 9 |
+
echo "========================================"
|
| 10 |
+
echo
|
| 11 |
+
|
| 12 |
+
echo "[1/8] Provider directory"
|
| 13 |
+
ls -lah backend/llm/providers
|
| 14 |
+
|
| 15 |
+
echo
|
| 16 |
+
echo "[2/8] Missing expected files"
|
| 17 |
+
|
| 18 |
+
EXPECTED=(
|
| 19 |
+
base.py
|
| 20 |
+
huggingface.py
|
| 21 |
+
openrouter.py
|
| 22 |
+
openai_compatible.py
|
| 23 |
+
fallback.py
|
| 24 |
+
model_registry.py
|
| 25 |
+
cerebras.py
|
| 26 |
+
groq.py
|
| 27 |
+
ollama.py
|
| 28 |
+
gemini.py
|
| 29 |
+
local.py
|
| 30 |
+
)
|
| 31 |
+
|
| 32 |
+
for f in "${EXPECTED[@]}"; do
|
| 33 |
+
if [ -f backend/llm/providers/$f ]; then
|
| 34 |
+
echo "[OK] $f"
|
| 35 |
+
else
|
| 36 |
+
echo "[MISSING] $f"
|
| 37 |
+
fi
|
| 38 |
+
done
|
| 39 |
+
|
| 40 |
+
echo
|
| 41 |
+
echo "[3/8] Backup candidates"
|
| 42 |
+
|
| 43 |
+
find backend -type f \
|
| 44 |
+
| grep "providers.*bak" \
|
| 45 |
+
| sort
|
| 46 |
+
|
| 47 |
+
echo
|
| 48 |
+
echo "[4/8] Search BaseProvider"
|
| 49 |
+
|
| 50 |
+
grep -RIn "class BaseProvider" backend || true
|
| 51 |
+
|
| 52 |
+
echo
|
| 53 |
+
echo "[5/8] Search GroqProvider"
|
| 54 |
+
|
| 55 |
+
grep -RIn "class GroqProvider" backend || true
|
| 56 |
+
|
| 57 |
+
echo
|
| 58 |
+
echo "[6/8] Search HuggingFaceProvider"
|
| 59 |
+
|
| 60 |
+
grep -RIn "class HuggingFaceProvider" backend || true
|
| 61 |
+
|
| 62 |
+
echo
|
| 63 |
+
echo "[7/8] Search OpenRouterProvider"
|
| 64 |
+
|
| 65 |
+
grep -RIn "class OpenRouterProvider" backend || true
|
| 66 |
+
|
| 67 |
+
echo
|
| 68 |
+
echo "[8/8] Search Local/Ollama"
|
| 69 |
+
|
| 70 |
+
grep -RInE "class LocalProvider|class OllamaProvider" backend || true
|
| 71 |
+
|
| 72 |
+
echo
|
| 73 |
+
echo "========================================"
|
| 74 |
+
echo "Inventory Complete"
|
| 75 |
+
echo "========================================"
|
40_restore_provider_core.sh
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT=/root/projects/website-builder-backend-clean
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
echo "========================================"
|
| 8 |
+
echo "Restore Dolor3V Provider Core"
|
| 9 |
+
echo "========================================"
|
| 10 |
+
|
| 11 |
+
restore_latest() {
|
| 12 |
+
local target="$1"
|
| 13 |
+
local backup
|
| 14 |
+
|
| 15 |
+
backup=$(ls "${target}".bak.* 2>/dev/null | sort | tail -1 || true)
|
| 16 |
+
|
| 17 |
+
if [ -n "$backup" ]; then
|
| 18 |
+
cp "$backup" "$target"
|
| 19 |
+
echo "[RESTORED] $(basename "$target")"
|
| 20 |
+
else
|
| 21 |
+
echo "[SKIPPED ] $(basename "$target")"
|
| 22 |
+
fi
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
restore_latest backend/llm/providers/huggingface.py
|
| 26 |
+
restore_latest backend/llm/providers/openrouter.py
|
| 27 |
+
restore_latest backend/llm/providers/openai_compatible.py
|
| 28 |
+
restore_latest backend/llm/providers/fallback.py
|
| 29 |
+
restore_latest backend/llm/providers/model_registry.py
|
| 30 |
+
restore_latest backend/llm/providers/cerebras.py
|
| 31 |
+
|
| 32 |
+
cat > backend/llm/providers/base.py <<'PY'
|
| 33 |
+
from backend.models.providers import BaseProvider
|
| 34 |
+
|
| 35 |
+
__all__ = ["BaseProvider"]
|
| 36 |
+
PY
|
| 37 |
+
|
| 38 |
+
echo
|
| 39 |
+
echo "Compiling provider package..."
|
| 40 |
+
|
| 41 |
+
python3 -m py_compile \
|
| 42 |
+
backend/llm/providers/base.py \
|
| 43 |
+
backend/llm/providers/openai_compatible.py \
|
| 44 |
+
backend/llm/providers/huggingface.py \
|
| 45 |
+
backend/llm/providers/openrouter.py \
|
| 46 |
+
backend/llm/providers/fallback.py \
|
| 47 |
+
backend/llm/providers/model_registry.py \
|
| 48 |
+
backend/llm/providers/cerebras.py
|
| 49 |
+
|
| 50 |
+
echo
|
| 51 |
+
python3 <<'PY'
|
| 52 |
+
from backend.llm.providers.base import BaseProvider
|
| 53 |
+
from backend.llm.providers.huggingface import HuggingFaceProvider
|
| 54 |
+
|
| 55 |
+
print("BaseProvider:", BaseProvider)
|
| 56 |
+
print("HuggingFaceProvider:", HuggingFaceProvider)
|
| 57 |
+
PY
|
| 58 |
+
|
| 59 |
+
echo
|
| 60 |
+
echo "========================================"
|
| 61 |
+
echo "Provider Core Restored"
|
| 62 |
+
echo "========================================"
|
41_rebuild_provider_init.sh
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT=/root/projects/website-builder-backend-clean
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
echo "========================================"
|
| 8 |
+
echo "Rebuilding Provider Package __init__"
|
| 9 |
+
echo "========================================"
|
| 10 |
+
|
| 11 |
+
cat > backend/llm/providers/__init__.py <<'PY'
|
| 12 |
+
from .base import BaseProvider
|
| 13 |
+
from .fallback import complete_with_fallback
|
| 14 |
+
from .openai_compatible import OpenAICompatibleProvider
|
| 15 |
+
from .huggingface import HuggingFaceProvider
|
| 16 |
+
from .openrouter import OpenRouterProvider
|
| 17 |
+
from .cerebras import CerebrasProvider
|
| 18 |
+
|
| 19 |
+
__all__ = [
|
| 20 |
+
"BaseProvider",
|
| 21 |
+
"complete_with_fallback",
|
| 22 |
+
"OpenAICompatibleProvider",
|
| 23 |
+
"HuggingFaceProvider",
|
| 24 |
+
"OpenRouterProvider",
|
| 25 |
+
"CerebrasProvider",
|
| 26 |
+
]
|
| 27 |
+
PY
|
| 28 |
+
|
| 29 |
+
python3 -m py_compile backend/llm/providers/__init__.py
|
| 30 |
+
|
| 31 |
+
python3 <<'PY'
|
| 32 |
+
from backend.llm.providers import (
|
| 33 |
+
BaseProvider,
|
| 34 |
+
HuggingFaceProvider,
|
| 35 |
+
OpenRouterProvider,
|
| 36 |
+
CerebrasProvider,
|
| 37 |
+
OpenAICompatibleProvider,
|
| 38 |
+
)
|
| 39 |
+
|
| 40 |
+
print("BaseProvider:", BaseProvider)
|
| 41 |
+
print("HuggingFaceProvider:", HuggingFaceProvider)
|
| 42 |
+
print("OpenRouterProvider:", OpenRouterProvider)
|
| 43 |
+
print("CerebrasProvider:", CerebrasProvider)
|
| 44 |
+
print("OpenAICompatibleProvider:", OpenAICompatibleProvider)
|
| 45 |
+
PY
|
| 46 |
+
|
| 47 |
+
echo
|
| 48 |
+
echo "========================================"
|
| 49 |
+
echo "Provider Package Rebuilt"
|
| 50 |
+
echo "========================================"
|
42_rebuild_fallback_layer.sh
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT=/root/projects/website-builder-backend-clean
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
echo "========================================"
|
| 8 |
+
echo "Rebuilding Dolor3V Fallback Layer"
|
| 9 |
+
echo "========================================"
|
| 10 |
+
|
| 11 |
+
cp backend/llm/providers/fallback.py \
|
| 12 |
+
backend/llm/providers/fallback.py.bak.$(date +%Y%m%d_%H%M%S) 2>/dev/null || true
|
| 13 |
+
|
| 14 |
+
cat > backend/llm/providers/fallback.py <<'PY'
|
| 15 |
+
"""
|
| 16 |
+
Dolor3V Production Fallback
|
| 17 |
+
|
| 18 |
+
Single-provider deployment.
|
| 19 |
+
Only Hugging Face is registered.
|
| 20 |
+
"""
|
| 21 |
+
|
| 22 |
+
from typing import Any
|
| 23 |
+
|
| 24 |
+
from .huggingface import HuggingFaceProvider
|
| 25 |
+
|
| 26 |
+
_PROVIDER = HuggingFaceProvider()
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
async def complete_with_fallback(
|
| 30 |
+
prompt: str,
|
| 31 |
+
**kwargs: Any,
|
| 32 |
+
):
|
| 33 |
+
"""
|
| 34 |
+
Unified completion entrypoint.
|
| 35 |
+
|
| 36 |
+
The runtime intentionally exposes only one provider.
|
| 37 |
+
"""
|
| 38 |
+
|
| 39 |
+
if hasattr(_PROVIDER, "complete"):
|
| 40 |
+
return await _PROVIDER.complete(prompt=prompt, **kwargs)
|
| 41 |
+
|
| 42 |
+
if hasattr(_PROVIDER, "generate"):
|
| 43 |
+
return await _PROVIDER.generate(prompt=prompt, **kwargs)
|
| 44 |
+
|
| 45 |
+
raise RuntimeError(
|
| 46 |
+
"HuggingFaceProvider exposes neither "
|
| 47 |
+
"'complete' nor 'generate'."
|
| 48 |
+
)
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
def get_provider():
|
| 52 |
+
return _PROVIDER
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
def providers():
|
| 56 |
+
return [_PROVIDER]
|
| 57 |
+
PY
|
| 58 |
+
|
| 59 |
+
echo
|
| 60 |
+
echo "[1/4] Compile"
|
| 61 |
+
|
| 62 |
+
python3 -m py_compile \
|
| 63 |
+
backend/llm/providers/fallback.py
|
| 64 |
+
|
| 65 |
+
echo
|
| 66 |
+
echo "[2/4] Import"
|
| 67 |
+
|
| 68 |
+
python3 <<'PY'
|
| 69 |
+
from backend.llm.providers.fallback import (
|
| 70 |
+
complete_with_fallback,
|
| 71 |
+
get_provider,
|
| 72 |
+
providers,
|
| 73 |
+
)
|
| 74 |
+
|
| 75 |
+
print("Fallback:", complete_with_fallback)
|
| 76 |
+
print("Provider:", type(get_provider()).__name__)
|
| 77 |
+
print("Providers:", len(providers()))
|
| 78 |
+
PY
|
| 79 |
+
|
| 80 |
+
echo
|
| 81 |
+
echo "[3/4] Search removed providers"
|
| 82 |
+
|
| 83 |
+
grep -RInE \
|
| 84 |
+
"GroqProvider|OpenRouterProvider|GeminiProvider|OllamaProvider|LocalProvider" \
|
| 85 |
+
backend/llm/providers/fallback.py || true
|
| 86 |
+
|
| 87 |
+
echo
|
| 88 |
+
echo "[4/4] Finished"
|
| 89 |
+
|
| 90 |
+
echo
|
| 91 |
+
echo "========================================"
|
| 92 |
+
echo "Dolor3V Fallback Ready"
|
| 93 |
+
echo "========================================"
|
43_inspect_huggingface_provider.sh
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT=/root/projects/website-builder-backend-clean
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
echo "========================================"
|
| 8 |
+
echo "Inspect HuggingFace Provider"
|
| 9 |
+
echo "========================================"
|
| 10 |
+
|
| 11 |
+
echo
|
| 12 |
+
echo "[1/5] Class definition"
|
| 13 |
+
grep -n "^class " backend/llm/providers/huggingface.py || true
|
| 14 |
+
|
| 15 |
+
echo
|
| 16 |
+
echo "[2/5] Methods"
|
| 17 |
+
grep -nE "^[[:space:]]*(async[[:space:]]+def|def)[[:space:]]+" \
|
| 18 |
+
backend/llm/providers/huggingface.py || true
|
| 19 |
+
|
| 20 |
+
echo
|
| 21 |
+
echo "[3/5] BaseProvider interface"
|
| 22 |
+
grep -nE "@abstractmethod|def generate|def complete" \
|
| 23 |
+
backend/models/providers.py || true
|
| 24 |
+
|
| 25 |
+
echo
|
| 26 |
+
echo "[4/5] OpenAI-compatible interface"
|
| 27 |
+
grep -nE "class |def generate|def complete|async def" \
|
| 28 |
+
backend/llm/providers/openai_compatible.py || true
|
| 29 |
+
|
| 30 |
+
echo
|
| 31 |
+
echo "[5/5] File sizes"
|
| 32 |
+
ls -lh \
|
| 33 |
+
backend/llm/providers/huggingface.py \
|
| 34 |
+
backend/llm/providers/openai_compatible.py \
|
| 35 |
+
backend/models/providers.py
|
| 36 |
+
|
| 37 |
+
echo
|
| 38 |
+
echo "========================================"
|
| 39 |
+
echo "Inspection Complete"
|
| 40 |
+
echo "========================================"
|
44_patch_openai_generate.sh
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT=/root/projects/website-builder-backend-clean
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
python3 <<'PY'
|
| 8 |
+
from pathlib import Path
|
| 9 |
+
|
| 10 |
+
p=Path("backend/llm/providers/openai_compatible.py")
|
| 11 |
+
src=p.read_text()
|
| 12 |
+
|
| 13 |
+
if "async def generate(" not in src:
|
| 14 |
+
|
| 15 |
+
marker=" async def complete("
|
| 16 |
+
|
| 17 |
+
wrapper='''
|
| 18 |
+
async def generate(
|
| 19 |
+
self,
|
| 20 |
+
model: str,
|
| 21 |
+
prompt: str,
|
| 22 |
+
**kwargs,
|
| 23 |
+
):
|
| 24 |
+
return await self.complete(
|
| 25 |
+
model=model,
|
| 26 |
+
prompt=prompt,
|
| 27 |
+
**kwargs,
|
| 28 |
+
)
|
| 29 |
+
|
| 30 |
+
'''
|
| 31 |
+
|
| 32 |
+
pos=src.find(marker)
|
| 33 |
+
|
| 34 |
+
if pos==-1:
|
| 35 |
+
raise RuntimeError("complete() not found")
|
| 36 |
+
|
| 37 |
+
src=src[:pos]+wrapper+src[pos:]
|
| 38 |
+
|
| 39 |
+
p.write_text(src)
|
| 40 |
+
|
| 41 |
+
print("patched")
|
| 42 |
+
PY
|
| 43 |
+
|
| 44 |
+
python3 -m py_compile \
|
| 45 |
+
backend/llm/providers/openai_compatible.py \
|
| 46 |
+
backend/llm/providers/huggingface.py
|
| 47 |
+
|
| 48 |
+
python3 <<'PY'
|
| 49 |
+
from backend.llm.providers.huggingface import HuggingFaceProvider
|
| 50 |
+
|
| 51 |
+
provider=HuggingFaceProvider()
|
| 52 |
+
|
| 53 |
+
print(type(provider).__name__)
|
| 54 |
+
print(hasattr(provider,"generate"))
|
| 55 |
+
print(hasattr(provider,"complete"))
|
| 56 |
+
PY
|
| 57 |
+
|
| 58 |
+
echo
|
| 59 |
+
echo "========================================"
|
| 60 |
+
echo "OpenAICompatibleProvider repaired"
|
| 61 |
+
echo "========================================"
|
45_verify_provider_stack.sh
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT=/root/projects/website-builder-backend-clean
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
echo "========================================"
|
| 8 |
+
echo "Dolor3V Provider Stack Verification"
|
| 9 |
+
echo "========================================"
|
| 10 |
+
|
| 11 |
+
echo
|
| 12 |
+
echo "[1/8] Compile"
|
| 13 |
+
|
| 14 |
+
python3 -m compileall backend
|
| 15 |
+
|
| 16 |
+
echo
|
| 17 |
+
echo "[2/8] Provider package"
|
| 18 |
+
|
| 19 |
+
python3 <<'PY'
|
| 20 |
+
from backend.llm.providers import (
|
| 21 |
+
BaseProvider,
|
| 22 |
+
HuggingFaceProvider,
|
| 23 |
+
OpenAICompatibleProvider,
|
| 24 |
+
OpenRouterProvider,
|
| 25 |
+
CerebrasProvider,
|
| 26 |
+
)
|
| 27 |
+
|
| 28 |
+
print("BaseProvider:", BaseProvider.__name__)
|
| 29 |
+
print("HuggingFaceProvider:", HuggingFaceProvider.__name__)
|
| 30 |
+
print("OpenAICompatibleProvider:", OpenAICompatibleProvider.__name__)
|
| 31 |
+
print("OpenRouterProvider:", OpenRouterProvider.__name__)
|
| 32 |
+
print("CerebrasProvider:", CerebrasProvider.__name__)
|
| 33 |
+
PY
|
| 34 |
+
|
| 35 |
+
echo
|
| 36 |
+
echo "[3/8] Provider registry"
|
| 37 |
+
|
| 38 |
+
python3 <<'PY'
|
| 39 |
+
import backend.llm.provider_registry as registry
|
| 40 |
+
|
| 41 |
+
print("Registry module:", registry)
|
| 42 |
+
|
| 43 |
+
if hasattr(registry,"list_providers"):
|
| 44 |
+
print(registry.list_providers())
|
| 45 |
+
|
| 46 |
+
if hasattr(registry,"get_provider"):
|
| 47 |
+
print(type(registry.get_provider()).__name__)
|
| 48 |
+
PY
|
| 49 |
+
|
| 50 |
+
echo
|
| 51 |
+
echo "[4/8] Gateway"
|
| 52 |
+
|
| 53 |
+
python3 <<'PY'
|
| 54 |
+
from backend.models.gateway import ModelGateway
|
| 55 |
+
|
| 56 |
+
gateway=ModelGateway()
|
| 57 |
+
|
| 58 |
+
print(type(gateway).__name__)
|
| 59 |
+
PY
|
| 60 |
+
|
| 61 |
+
echo
|
| 62 |
+
echo "[5/8] Main"
|
| 63 |
+
|
| 64 |
+
python3 <<'PY'
|
| 65 |
+
import backend.main
|
| 66 |
+
|
| 67 |
+
print(type(backend.main.llm_gateway).__name__)
|
| 68 |
+
print(type(backend.main.dolor3v).__name__)
|
| 69 |
+
PY
|
| 70 |
+
|
| 71 |
+
echo
|
| 72 |
+
echo "[6/8] Search removed providers"
|
| 73 |
+
|
| 74 |
+
grep -RInE \
|
| 75 |
+
"google\.generativeai|GeminiProvider|GroqProvider|OllamaProvider|LocalProvider" \
|
| 76 |
+
backend || true
|
| 77 |
+
|
| 78 |
+
echo
|
| 79 |
+
echo "[7/8] HuggingFace references"
|
| 80 |
+
|
| 81 |
+
grep -RIn "huggingface" backend || true
|
| 82 |
+
|
| 83 |
+
echo
|
| 84 |
+
echo "[8/8] Finished"
|
| 85 |
+
|
| 86 |
+
echo
|
| 87 |
+
echo "========================================"
|
| 88 |
+
echo "Provider Stack Verified"
|
| 89 |
+
echo "========================================"
|
| 90 |
+
|
46_move_runtime_imports.sh
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT=/root/projects/website-builder-backend-clean
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
python3 <<'PY'
|
| 8 |
+
from pathlib import Path
|
| 9 |
+
|
| 10 |
+
p=Path("backend/main.py")
|
| 11 |
+
lines=p.read_text().splitlines()
|
| 12 |
+
|
| 13 |
+
required=[
|
| 14 |
+
"from backend.models.gateway import ModelGateway",
|
| 15 |
+
"from backend.agents.memory import AgentMemoryStore",
|
| 16 |
+
"from backend.agents.messaging import MessageBus",
|
| 17 |
+
"from backend.agents.base import BaseAgent",
|
| 18 |
+
]
|
| 19 |
+
|
| 20 |
+
# remove every occurrence
|
| 21 |
+
filtered=[l for l in lines if l.strip() not in required]
|
| 22 |
+
|
| 23 |
+
# insert after orchestrator import
|
| 24 |
+
insert_at=0
|
| 25 |
+
for i,l in enumerate(filtered):
|
| 26 |
+
if l.strip()=="from backend.agents.orchestrator import Orchestrator":
|
| 27 |
+
insert_at=i+1
|
| 28 |
+
break
|
| 29 |
+
|
| 30 |
+
for item in reversed(required):
|
| 31 |
+
filtered.insert(insert_at,item)
|
| 32 |
+
|
| 33 |
+
p.write_text("\n".join(filtered)+"\n")
|
| 34 |
+
PY
|
| 35 |
+
|
| 36 |
+
echo
|
| 37 |
+
echo "===== Runtime imports ====="
|
| 38 |
+
nl -ba backend/main.py | sed -n '40,65p'
|
| 39 |
+
|
| 40 |
+
echo
|
| 41 |
+
echo "===== Duplicate check ====="
|
| 42 |
+
grep -nE \
|
| 43 |
+
"AgentMemoryStore|MessageBus|ModelGateway|BaseAgent" \
|
| 44 |
+
backend/main.py
|
| 45 |
+
|
| 46 |
+
echo
|
| 47 |
+
python3 -m py_compile backend/main.py
|
| 48 |
+
|
| 49 |
+
echo
|
| 50 |
+
python3 <<'PY'
|
| 51 |
+
import backend.main
|
| 52 |
+
|
| 53 |
+
print(type(backend.main.memory).__name__)
|
| 54 |
+
print(type(backend.main.bus).__name__)
|
| 55 |
+
print(type(backend.main.llm_gateway).__name__)
|
| 56 |
+
PY
|
| 57 |
+
|
| 58 |
+
echo
|
| 59 |
+
echo "========================================"
|
| 60 |
+
echo "Runtime imports repaired"
|
| 61 |
+
echo "========================================"
|
47_remove_duplicate_gateway_import.sh
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT=/root/projects/website-builder-backend-clean
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
python3 <<'PY'
|
| 8 |
+
from pathlib import Path
|
| 9 |
+
|
| 10 |
+
p = Path("backend/main.py")
|
| 11 |
+
lines = p.read_text().splitlines()
|
| 12 |
+
|
| 13 |
+
keep = "from backend.models.gateway import ModelGateway"
|
| 14 |
+
remove = "from backend.llm.gateway import ModelGateway"
|
| 15 |
+
|
| 16 |
+
new = []
|
| 17 |
+
kept = False
|
| 18 |
+
|
| 19 |
+
for line in lines:
|
| 20 |
+
if line.strip() == remove:
|
| 21 |
+
continue
|
| 22 |
+
if line.strip() == keep:
|
| 23 |
+
if kept:
|
| 24 |
+
continue
|
| 25 |
+
kept = True
|
| 26 |
+
new.append(line)
|
| 27 |
+
|
| 28 |
+
p.write_text("\n".join(new) + "\n")
|
| 29 |
+
PY
|
| 30 |
+
|
| 31 |
+
echo
|
| 32 |
+
echo "===== Gateway imports ====="
|
| 33 |
+
grep -n "ModelGateway" backend/main.py
|
| 34 |
+
|
| 35 |
+
echo
|
| 36 |
+
python3 -m py_compile backend/main.py
|
| 37 |
+
|
| 38 |
+
echo
|
| 39 |
+
python3 <<'PY'
|
| 40 |
+
import backend.main
|
| 41 |
+
|
| 42 |
+
print("Gateway class :", type(backend.main.llm_gateway).__module__)
|
| 43 |
+
print("Gateway type :", type(backend.main.llm_gateway).__name__)
|
| 44 |
+
print("Memory type :", type(backend.main.memory).__name__)
|
| 45 |
+
print("Bus type :", type(backend.main.bus).__name__)
|
| 46 |
+
print("Runtime type :", type(backend.main.dolor3v).__name__)
|
| 47 |
+
PY
|
| 48 |
+
|
| 49 |
+
echo
|
| 50 |
+
echo "========================================"
|
| 51 |
+
echo "Gateway import cleaned"
|
| 52 |
+
echo "========================================"
|
48_verify_fastapi_startup.sh
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT=/root/projects/website-builder-backend-clean
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
echo "========================================"
|
| 8 |
+
echo "Verify FastAPI Startup"
|
| 9 |
+
echo "========================================"
|
| 10 |
+
|
| 11 |
+
echo
|
| 12 |
+
echo "[1/6] Compile"
|
| 13 |
+
python3 -m py_compile backend/main.py
|
| 14 |
+
|
| 15 |
+
echo
|
| 16 |
+
echo "[2/6] Import"
|
| 17 |
+
python3 <<'PY'
|
| 18 |
+
import backend.main
|
| 19 |
+
|
| 20 |
+
print("App:", backend.main.app.title)
|
| 21 |
+
print("Runtime:", type(backend.main.dolor3v).__name__)
|
| 22 |
+
print("Gateway:", type(backend.main.llm_gateway).__name__)
|
| 23 |
+
PY
|
| 24 |
+
|
| 25 |
+
echo
|
| 26 |
+
echo "[3/6] Route count"
|
| 27 |
+
python3 <<'PY'
|
| 28 |
+
import backend.main
|
| 29 |
+
|
| 30 |
+
routes = backend.main.app.routes
|
| 31 |
+
print("Routes:", len(routes))
|
| 32 |
+
|
| 33 |
+
for r in routes[:20]:
|
| 34 |
+
print(getattr(r, "path", ""), getattr(r, "methods", ""))
|
| 35 |
+
PY
|
| 36 |
+
|
| 37 |
+
echo
|
| 38 |
+
echo "[4/6] ASGI validation"
|
| 39 |
+
python3 <<'PY'
|
| 40 |
+
import backend.main
|
| 41 |
+
assert callable(backend.main.app)
|
| 42 |
+
print("ASGI application OK")
|
| 43 |
+
PY
|
| 44 |
+
|
| 45 |
+
echo
|
| 46 |
+
echo "[5/6] Uvicorn configuration"
|
| 47 |
+
python3 -c "import uvicorn"
|
| 48 |
+
|
| 49 |
+
echo "uvicorn available"
|
| 50 |
+
|
| 51 |
+
echo
|
| 52 |
+
echo "[6/6] Finished"
|
| 53 |
+
|
| 54 |
+
echo
|
| 55 |
+
echo "========================================"
|
| 56 |
+
echo "FastAPI Startup Verified"
|
| 57 |
+
echo "========================================"
|
49_runtime_endpoint_validation.sh
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT=/root/projects/website-builder-backend-clean
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
HOST=127.0.0.1
|
| 8 |
+
PORT=8000
|
| 9 |
+
|
| 10 |
+
echo "========================================"
|
| 11 |
+
echo "Dolor3V Runtime Endpoint Validation"
|
| 12 |
+
echo "========================================"
|
| 13 |
+
|
| 14 |
+
cleanup() {
|
| 15 |
+
if [[ -n "${UVICORN_PID:-}" ]] && kill -0 "$UVICORN_PID" 2>/dev/null; then
|
| 16 |
+
echo
|
| 17 |
+
echo "[CLEANUP] Stopping Uvicorn..."
|
| 18 |
+
kill "$UVICORN_PID" || true
|
| 19 |
+
wait "$UVICORN_PID" 2>/dev/null || true
|
| 20 |
+
fi
|
| 21 |
+
}
|
| 22 |
+
trap cleanup EXIT
|
| 23 |
+
|
| 24 |
+
echo
|
| 25 |
+
echo "[1/10] Compile"
|
| 26 |
+
python3 -m py_compile backend/main.py
|
| 27 |
+
|
| 28 |
+
echo
|
| 29 |
+
echo "[2/10] Start FastAPI"
|
| 30 |
+
|
| 31 |
+
python3 -m uvicorn backend.main:app \
|
| 32 |
+
--host "$HOST" \
|
| 33 |
+
--port "$PORT" \
|
| 34 |
+
>/tmp/dolor3v_uvicorn.log 2>&1 &
|
| 35 |
+
|
| 36 |
+
UVICORN_PID=$!
|
| 37 |
+
|
| 38 |
+
echo
|
| 39 |
+
echo "[3/10] Wait for startup"
|
| 40 |
+
|
| 41 |
+
READY=0
|
| 42 |
+
|
| 43 |
+
for i in $(seq 1 30); do
|
| 44 |
+
if curl -fs "http://$HOST:$PORT/health" >/dev/null 2>&1; then
|
| 45 |
+
READY=1
|
| 46 |
+
break
|
| 47 |
+
fi
|
| 48 |
+
sleep 1
|
| 49 |
+
done
|
| 50 |
+
|
| 51 |
+
if [[ "$READY" -ne 1 ]]; then
|
| 52 |
+
echo
|
| 53 |
+
echo "========== UVICORN LOG =========="
|
| 54 |
+
cat /tmp/dolor3v_uvicorn.log
|
| 55 |
+
exit 1
|
| 56 |
+
fi
|
| 57 |
+
|
| 58 |
+
echo "[OK] Server started."
|
| 59 |
+
|
| 60 |
+
echo
|
| 61 |
+
echo "[4/10] /health"
|
| 62 |
+
curl -fs "http://$HOST:$PORT/health"
|
| 63 |
+
echo
|
| 64 |
+
|
| 65 |
+
echo
|
| 66 |
+
echo "[5/10] /openapi.json"
|
| 67 |
+
curl -fs "http://$HOST:$PORT/openapi.json" >/dev/null
|
| 68 |
+
echo "[OK] OpenAPI available."
|
| 69 |
+
|
| 70 |
+
echo
|
| 71 |
+
echo "[6/10] /mcp"
|
| 72 |
+
curl -s \
|
| 73 |
+
-X POST \
|
| 74 |
+
"http://$HOST:$PORT/mcp" \
|
| 75 |
+
-H "Content-Type: application/json" \
|
| 76 |
+
-d '{}' || true
|
| 77 |
+
echo
|
| 78 |
+
|
| 79 |
+
echo
|
| 80 |
+
echo "[7/10] Workspace session"
|
| 81 |
+
curl -s \
|
| 82 |
+
-X POST \
|
| 83 |
+
"http://$HOST:$PORT/api/workspace/session" \
|
| 84 |
+
-H "Content-Type: application/json" \
|
| 85 |
+
-d '{}' || true
|
| 86 |
+
echo
|
| 87 |
+
|
| 88 |
+
echo
|
| 89 |
+
echo "[8/10] Workspace sessions"
|
| 90 |
+
curl -s \
|
| 91 |
+
"http://$HOST:$PORT/api/workspace/sessions" || true
|
| 92 |
+
echo
|
| 93 |
+
|
| 94 |
+
echo
|
| 95 |
+
echo "[9/10] IDE search"
|
| 96 |
+
curl -s \
|
| 97 |
+
"http://$HOST:$PORT/api/ide/search?q=test" || true
|
| 98 |
+
echo
|
| 99 |
+
|
| 100 |
+
echo
|
| 101 |
+
echo "[10/10] Chat endpoint"
|
| 102 |
+
curl -s \
|
| 103 |
+
-X POST \
|
| 104 |
+
"http://$HOST:$PORT/api/workspace/chat/message" \
|
| 105 |
+
-H "Content-Type: application/json" \
|
| 106 |
+
-d '{"message":"hello"}' || true
|
| 107 |
+
echo
|
| 108 |
+
|
| 109 |
+
echo
|
| 110 |
+
echo "========================================"
|
| 111 |
+
echo "Dolor3V Runtime Validation Completed"
|
| 112 |
+
echo "========================================"
|
50_fix_runtime_validation.sh
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
ROOT=/root/projects/website-builder-backend-clean
|
| 5 |
+
cd "$ROOT"
|
| 6 |
+
|
| 7 |
+
echo "========================================"
|
| 8 |
+
echo "Dolor3V Runtime Validation Repair"
|
| 9 |
+
echo "========================================"
|
| 10 |
+
|
| 11 |
+
echo
|
| 12 |
+
echo "[1/8] Compile"
|
| 13 |
+
python3 -m compileall backend >/dev/null
|
| 14 |
+
|
| 15 |
+
echo
|
| 16 |
+
echo "[2/8] Start FastAPI"
|
| 17 |
+
|
| 18 |
+
uvicorn backend.main:app \
|
| 19 |
+
--host 127.0.0.1 \
|
| 20 |
+
--port 8000 \
|
| 21 |
+
>/tmp/dolor3v_runtime.log 2>&1 &
|
| 22 |
+
|
| 23 |
+
PID=$!
|
| 24 |
+
|
| 25 |
+
cleanup() {
|
| 26 |
+
kill $PID >/dev/null 2>&1 || true
|
| 27 |
+
}
|
| 28 |
+
trap cleanup EXIT
|
| 29 |
+
|
| 30 |
+
echo
|
| 31 |
+
echo "[3/8] Wait"
|
| 32 |
+
|
| 33 |
+
for i in $(seq 1 30); do
|
| 34 |
+
if curl -fs http://127.0.0.1:8000/health >/dev/null 2>&1; then
|
| 35 |
+
break
|
| 36 |
+
fi
|
| 37 |
+
sleep 1
|
| 38 |
+
done
|
| 39 |
+
|
| 40 |
+
curl -fs http://127.0.0.1:8000/health >/dev/null
|
| 41 |
+
|
| 42 |
+
echo "[OK] Runtime ready."
|
| 43 |
+
|
| 44 |
+
echo
|
| 45 |
+
echo "[4/8] Create workspace session"
|
| 46 |
+
|
| 47 |
+
SESSION_JSON=$(
|
| 48 |
+
curl -fs \
|
| 49 |
+
-X POST \
|
| 50 |
+
http://127.0.0.1:8000/api/workspace/session
|
| 51 |
+
)
|
| 52 |
+
|
| 53 |
+
echo "$SESSION_JSON"
|
| 54 |
+
|
| 55 |
+
SESSION_ID=$(
|
| 56 |
+
python3 - <<PY
|
| 57 |
+
import json
|
| 58 |
+
print(json.loads("""$SESSION_JSON""")["session_id"])
|
| 59 |
+
PY
|
| 60 |
+
)
|
| 61 |
+
|
| 62 |
+
echo
|
| 63 |
+
echo "[5/8] IDE search"
|
| 64 |
+
|
| 65 |
+
curl -fsG \
|
| 66 |
+
http://127.0.0.1:8000/api/ide/search \
|
| 67 |
+
--data-urlencode "query=backend"
|
| 68 |
+
|
| 69 |
+
echo
|
| 70 |
+
echo
|
| 71 |
+
echo "[6/8] Chat endpoint"
|
| 72 |
+
|
| 73 |
+
curl -fsG \
|
| 74 |
+
-X POST \
|
| 75 |
+
http://127.0.0.1:8000/api/workspace/chat/message \
|
| 76 |
+
--data-urlencode "session_id=${SESSION_ID}" \
|
| 77 |
+
--data-urlencode "role=user" \
|
| 78 |
+
--data-urlencode "content=Hello Dolor3V"
|
| 79 |
+
|
| 80 |
+
echo
|
| 81 |
+
echo
|
| 82 |
+
echo "[7/8] MCP"
|
| 83 |
+
|
| 84 |
+
curl -fs \
|
| 85 |
+
-H "Content-Type: application/json" \
|
| 86 |
+
-d '{"jsonrpc":"2.0","id":"1","method":"ping"}' \
|
| 87 |
+
http://127.0.0.1:8000/mcp
|
| 88 |
+
|
| 89 |
+
echo
|
| 90 |
+
echo
|
| 91 |
+
echo "[8/8] Health"
|
| 92 |
+
|
| 93 |
+
curl -fs http://127.0.0.1:8000/health
|
| 94 |
+
|
| 95 |
+
echo
|
| 96 |
+
echo
|
| 97 |
+
echo "========================================"
|
| 98 |
+
echo "Runtime Validation Passed"
|
| 99 |
+
echo "========================================"
|
| 100 |
+
|
| 101 |
+
echo
|
| 102 |
+
echo "[CLEANUP]"
|
| 103 |
+
kill $PID >/dev/null 2>&1 || true
|
| 104 |
+
wait $PID 2>/dev/null || true
|
| 105 |
+
|
agent_logic.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import asyncio
|
| 2 |
+
from google.antigravity import Agent, LocalAgentConfig
|
| 3 |
+
|
| 4 |
+
async def agentic_workflow(user_query):
|
| 5 |
+
# This matches the documentation for Antigravity you provided
|
| 6 |
+
config = LocalAgentConfig(
|
| 7 |
+
system_instructions="You are the lead architect of DOLOR3V Studio. Handle file generation and build triggers.",
|
| 8 |
+
vertex=True,
|
| 9 |
+
project="dolor3v-unified-backend"
|
| 10 |
+
)
|
| 11 |
+
|
| 12 |
+
async with Agent(config) as agent:
|
| 13 |
+
# The agent decides whether to call the builder or the design-tool
|
| 14 |
+
response = await agent.chat(user_query)
|
| 15 |
+
return await response.text()
|
android_project_generator.py
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from pathlib import Path
|
| 2 |
+
|
| 3 |
+
PACKAGE="com.dolor3v.app"
|
| 4 |
+
APP_NAME="Dolor3v"
|
| 5 |
+
|
| 6 |
+
ROOT=Path("generated_android")
|
| 7 |
+
|
| 8 |
+
def write(path,text):
|
| 9 |
+
path.parent.mkdir(parents=True,exist_ok=True)
|
| 10 |
+
path.write_text(text.strip()+"\n",encoding="utf-8")
|
| 11 |
+
|
| 12 |
+
def generate():
|
| 13 |
+
|
| 14 |
+
write(
|
| 15 |
+
ROOT/"AndroidManifest.xml",
|
| 16 |
+
f"""
|
| 17 |
+
<?xml version="1.0" encoding="utf-8"?>
|
| 18 |
+
<manifest
|
| 19 |
+
package="{PACKAGE}"
|
| 20 |
+
xmlns:android="http://schemas.android.com/apk/res/android">
|
| 21 |
+
|
| 22 |
+
<application
|
| 23 |
+
android:label="{APP_NAME}"
|
| 24 |
+
android:allowBackup="true"
|
| 25 |
+
android:supportsRtl="true"
|
| 26 |
+
android:theme="@style/Theme.App">
|
| 27 |
+
|
| 28 |
+
<activity
|
| 29 |
+
android:name=".MainActivity"
|
| 30 |
+
android:exported="true">
|
| 31 |
+
|
| 32 |
+
<intent-filter>
|
| 33 |
+
<action android:name="android.intent.action.MAIN"/>
|
| 34 |
+
<category android:name="android.intent.category.LAUNCHER"/>
|
| 35 |
+
</intent-filter>
|
| 36 |
+
|
| 37 |
+
</activity>
|
| 38 |
+
|
| 39 |
+
</application>
|
| 40 |
+
|
| 41 |
+
</manifest>
|
| 42 |
+
"""
|
| 43 |
+
)
|
| 44 |
+
|
| 45 |
+
write(
|
| 46 |
+
ROOT/"res/values/strings.xml",
|
| 47 |
+
"""
|
| 48 |
+
<?xml version="1.0" encoding="utf-8"?>
|
| 49 |
+
<resources>
|
| 50 |
+
<string name="app_name">Dolor3v</string>
|
| 51 |
+
</resources>
|
| 52 |
+
"""
|
| 53 |
+
)
|
| 54 |
+
|
| 55 |
+
write(
|
| 56 |
+
ROOT/"res/values/colors.xml",
|
| 57 |
+
"""
|
| 58 |
+
<?xml version="1.0" encoding="utf-8"?>
|
| 59 |
+
<resources>
|
| 60 |
+
<color name="black">#000000</color>
|
| 61 |
+
<color name="white">#FFFFFF</color>
|
| 62 |
+
</resources>
|
| 63 |
+
"""
|
| 64 |
+
)
|
| 65 |
+
|
| 66 |
+
write(
|
| 67 |
+
ROOT/"res/values/themes.xml",
|
| 68 |
+
"""
|
| 69 |
+
<?xml version="1.0" encoding="utf-8"?>
|
| 70 |
+
<resources>
|
| 71 |
+
|
| 72 |
+
<style
|
| 73 |
+
name="Theme.App"
|
| 74 |
+
parent="android:Theme.Material.Light.NoActionBar"/>
|
| 75 |
+
|
| 76 |
+
</resources>
|
| 77 |
+
"""
|
| 78 |
+
)
|
| 79 |
+
|
| 80 |
+
java_path=ROOT/"src/com/dolor3v/app/MainActivity.java"
|
| 81 |
+
|
| 82 |
+
write(
|
| 83 |
+
java_path,
|
| 84 |
+
f"""
|
| 85 |
+
package {PACKAGE};
|
| 86 |
+
|
| 87 |
+
import android.app.Activity;
|
| 88 |
+
import android.os.Bundle;
|
| 89 |
+
import android.widget.TextView;
|
| 90 |
+
|
| 91 |
+
public class MainActivity extends Activity {{
|
| 92 |
+
|
| 93 |
+
@Override
|
| 94 |
+
protected void onCreate(Bundle state) {{
|
| 95 |
+
super.onCreate(state);
|
| 96 |
+
|
| 97 |
+
TextView tv=new TextView(this);
|
| 98 |
+
tv.setText("Dolor3v APK Builder");
|
| 99 |
+
setContentView(tv);
|
| 100 |
+
}}
|
| 101 |
+
|
| 102 |
+
}}
|
| 103 |
+
"""
|
| 104 |
+
)
|
| 105 |
+
|
| 106 |
+
print(ROOT.resolve())
|
| 107 |
+
|
| 108 |
+
if __name__=="__main__":
|
| 109 |
+
generate()
|
apk_workflow.py
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
import os
|
| 4 |
+
import subprocess
|
| 5 |
+
from pathlib import Path
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
ANDROID_HOME = os.environ.get("ANDROID_HOME", "")
|
| 9 |
+
BUILD_TOOLS = os.environ.get("ANDROID_BUILD_TOOLS", "35.0.0")
|
| 10 |
+
JAVA_HOME = os.environ.get("JAVA_HOME", "")
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
class APKWorkflow:
|
| 14 |
+
|
| 15 |
+
def __init__(self, project: str):
|
| 16 |
+
self.project = Path(project).resolve()
|
| 17 |
+
|
| 18 |
+
def run(self):
|
| 19 |
+
return {
|
| 20 |
+
"validate": self.validate(),
|
| 21 |
+
"compile_resources": self.compile_resources(),
|
| 22 |
+
"compile_java": self.compile_java(),
|
| 23 |
+
"dex": self.dex(),
|
| 24 |
+
"package": self.package(),
|
| 25 |
+
"zipalign": self.zipalign(),
|
| 26 |
+
"sign": self.sign()
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
def validate(self):
|
| 30 |
+
manifest = self.project / "AndroidManifest.xml"
|
| 31 |
+
|
| 32 |
+
if not manifest.exists():
|
| 33 |
+
return {
|
| 34 |
+
"ok": False,
|
| 35 |
+
"error": "AndroidManifest.xml missing"
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
return {"ok": True}
|
| 39 |
+
|
| 40 |
+
def compile_resources(self):
|
| 41 |
+
|
| 42 |
+
aapt2 = Path(ANDROID_HOME) / "build-tools" / BUILD_TOOLS / "aapt2"
|
| 43 |
+
|
| 44 |
+
if not aapt2.exists():
|
| 45 |
+
return {
|
| 46 |
+
"ok": False,
|
| 47 |
+
"error": "aapt2 missing"
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
return {"ok": True}
|
| 51 |
+
|
| 52 |
+
def compile_java(self):
|
| 53 |
+
|
| 54 |
+
javac = "javac"
|
| 55 |
+
|
| 56 |
+
try:
|
| 57 |
+
subprocess.run(
|
| 58 |
+
[javac, "-version"],
|
| 59 |
+
check=True,
|
| 60 |
+
capture_output=True
|
| 61 |
+
)
|
| 62 |
+
return {"ok": True}
|
| 63 |
+
except Exception as e:
|
| 64 |
+
return {
|
| 65 |
+
"ok": False,
|
| 66 |
+
"error": str(e)
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
def dex(self):
|
| 70 |
+
|
| 71 |
+
d8 = Path(ANDROID_HOME) / "build-tools" / BUILD_TOOLS / "d8"
|
| 72 |
+
|
| 73 |
+
return {
|
| 74 |
+
"ok": d8.exists()
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
def package(self):
|
| 78 |
+
|
| 79 |
+
aapt2 = Path(ANDROID_HOME) / "build-tools" / BUILD_TOOLS / "aapt2"
|
| 80 |
+
|
| 81 |
+
return {
|
| 82 |
+
"ok": aapt2.exists()
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
def zipalign(self):
|
| 86 |
+
|
| 87 |
+
exe = Path(ANDROID_HOME) / "build-tools" / BUILD_TOOLS / "zipalign"
|
| 88 |
+
|
| 89 |
+
return {
|
| 90 |
+
"ok": exe.exists()
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
def sign(self):
|
| 94 |
+
|
| 95 |
+
exe = Path(ANDROID_HOME) / "build-tools" / BUILD_TOOLS / "apksigner"
|
| 96 |
+
|
| 97 |
+
return {
|
| 98 |
+
"ok": exe.exists()
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
if __name__ == "__main__":
|
| 103 |
+
|
| 104 |
+
import json
|
| 105 |
+
|
| 106 |
+
wf = APKWorkflow("android_project")
|
| 107 |
+
|
| 108 |
+
print(json.dumps(wf.run(), indent=2))
|
app_drive_upload.py
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import io
|
| 2 |
+
import json
|
| 3 |
+
import os
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
|
| 6 |
+
from google.oauth2 import service_account
|
| 7 |
+
from googleapiclient.discovery import build
|
| 8 |
+
from googleapiclient.http import MediaIoBaseUpload
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
SCOPES = [
|
| 12 |
+
"https://www.googleapis.com/auth/drive"
|
| 13 |
+
]
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
class DriveUploader:
|
| 17 |
+
|
| 18 |
+
def __init__(self):
|
| 19 |
+
|
| 20 |
+
service_json = os.environ["GDRIVE_SERVICE_ACCOUNT_JSON"]
|
| 21 |
+
folder_id = os.environ["GDRIVE_FOLDER_ID"]
|
| 22 |
+
|
| 23 |
+
self.folder_id = folder_id
|
| 24 |
+
|
| 25 |
+
credentials = service_account.Credentials.from_service_account_info(
|
| 26 |
+
json.loads(service_json),
|
| 27 |
+
scopes=SCOPES,
|
| 28 |
+
)
|
| 29 |
+
|
| 30 |
+
self.service = build(
|
| 31 |
+
"drive",
|
| 32 |
+
"v3",
|
| 33 |
+
credentials=credentials,
|
| 34 |
+
cache_discovery=False,
|
| 35 |
+
)
|
| 36 |
+
|
| 37 |
+
def upload(self, artifact: Path):
|
| 38 |
+
|
| 39 |
+
with artifact.open("rb") as fp:
|
| 40 |
+
|
| 41 |
+
media = MediaIoBaseUpload(
|
| 42 |
+
io.BytesIO(fp.read()),
|
| 43 |
+
mimetype="application/octet-stream",
|
| 44 |
+
resumable=False,
|
| 45 |
+
)
|
| 46 |
+
|
| 47 |
+
metadata = {
|
| 48 |
+
"name": artifact.name,
|
| 49 |
+
"parents": [
|
| 50 |
+
self.folder_id
|
| 51 |
+
],
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
created = (
|
| 55 |
+
self.service.files()
|
| 56 |
+
.create(
|
| 57 |
+
body=metadata,
|
| 58 |
+
media_body=media,
|
| 59 |
+
fields="id,name,webViewLink,webContentLink",
|
| 60 |
+
)
|
| 61 |
+
.execute()
|
| 62 |
+
)
|
| 63 |
+
|
| 64 |
+
self.service.permissions().create(
|
| 65 |
+
fileId=created["id"],
|
| 66 |
+
body={
|
| 67 |
+
"type": "anyone",
|
| 68 |
+
"role": "reader",
|
| 69 |
+
},
|
| 70 |
+
).execute()
|
| 71 |
+
|
| 72 |
+
return {
|
| 73 |
+
"id": created["id"],
|
| 74 |
+
"name": created["name"],
|
| 75 |
+
"download_url": (
|
| 76 |
+
f"https://drive.google.com/uc?export=download&id={created['id']}"
|
| 77 |
+
),
|
| 78 |
+
"view_url": created.get("webViewLink"),
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
drive_uploader = DriveUploader()
|
backend.log
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
INFO: Started server process [17813]
|
| 2 |
+
INFO: Waiting for application startup.
|
| 3 |
+
ERROR:dolor3v-unified-backend:Failed to initialize Postgres pool. Falling back to memory: [Errno 111] Connection refused
|
| 4 |
+
INFO: Application startup complete.
|
| 5 |
+
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
|
| 6 |
+
INFO: 127.0.0.1:55224 - "GET /health HTTP/1.1" 200 OK
|
| 7 |
+
INFO: 127.0.0.1:55228 - "GET /health HTTP/1.1" 200 OK
|
| 8 |
+
INFO: 127.0.0.1:55238 - "GET /health HTTP/1.1" 200 OK
|
| 9 |
+
INFO: 127.0.0.1:55252 - "GET /openapi.json HTTP/1.1" 200 OK
|
| 10 |
+
INFO: 127.0.0.1:55262 - "GET /api/mcp HTTP/1.1" 200 OK
|
| 11 |
+
INFO: 127.0.0.1:57966 - "GET /api/mcp/registry HTTP/1.1" 200 OK
|
| 12 |
+
INFO: 127.0.0.1:57974 - "GET /api/mcp/runtime HTTP/1.1" 200 OK
|
| 13 |
+
INFO: 127.0.0.1:57986 - "GET /api/discovery/servers HTTP/1.1" 200 OK
|
| 14 |
+
INFO: 127.0.0.1:57988 - "GET /api/health HTTP/1.1" 200 OK
|
| 15 |
+
INFO:httpx:HTTP Request: POST https://api.groq.com/openai/v1/chat/completions "HTTP/1.1 401 Unauthorized"
|
| 16 |
+
WARNING:dolor3v-unified-backend:Provider groq failed: Groq 401: {"error":{"message":"Invalid API Key","type":"invalid_request_error","code":"invalid_api_key"}}
|
| 17 |
+
|
| 18 |
+
INFO:httpx:HTTP Request: POST https://api.cerebras.ai/v1/chat/completions "HTTP/1.1 200 OK"
|
| 19 |
+
INFO: 127.0.0.1:57996 - "POST /v1/chat/completions HTTP/1.1" 200 OK
|
| 20 |
+
INFO:httpx:HTTP Request: POST https://api.cerebras.ai/v1/chat/completions "HTTP/1.1 200 OK"
|
| 21 |
+
INFO: 127.0.0.1:42324 - "POST /api/builder/generate/component?name=OrderCard&description=Order%20Card&framework=react HTTP/1.1" 200 OK
|
| 22 |
+
INFO:httpx:HTTP Request: POST https://api.cerebras.ai/v1/chat/completions "HTTP/1.1 200 OK"
|
| 23 |
+
INFO: 127.0.0.1:48874 - "POST /api/builder/generate/api?endpoint_path=/orders&method=POST&description=Create%20Orders HTTP/1.1" 200 OK
|
| 24 |
+
INFO: 127.0.0.1:48876 - "POST /api/builder/generate/project?prompt=Enterprise%20CRM&template=fastapi-react HTTP/1.1" 200 OK
|
backend.pid
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
30838
|
builder_routes.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Production Builder Routes
|
| 3 |
+
|
| 4 |
+
Wires the real AIBuilderService (backend/builder_api/service.py)
|
| 5 |
+
into a mountable APIRouter. Component/API/Schema generation now
|
| 6 |
+
call a real LLM via backend.models.gateway.model_gateway.
|
| 7 |
+
"""
|
| 8 |
+
|
| 9 |
+
from fastapi import APIRouter, Body
|
| 10 |
+
|
| 11 |
+
from backend.builder_api.service import AIBuilderService
|
| 12 |
+
|
| 13 |
+
router = APIRouter(prefix="/api/builder", tags=["Builder"])
|
| 14 |
+
|
| 15 |
+
builder_service = AIBuilderService()
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
@router.post("/generate/project")
|
| 19 |
+
def generate_project_endpoint(prompt: str, template: str = "fastapi-react"):
|
| 20 |
+
return builder_service.generate_project(prompt, template)
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
@router.post("/generate/component")
|
| 24 |
+
async def generate_component_endpoint(name: str, description: str, framework: str = "react"):
|
| 25 |
+
return await builder_service.generate_component(name, description, framework)
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
@router.post("/generate/api")
|
| 29 |
+
async def generate_api_endpoint(endpoint_path: str, method: str = "GET", description: str = ""):
|
| 30 |
+
return await builder_service.generate_api(endpoint_path, method, description)
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
@router.post("/generate/schema")
|
| 34 |
+
async def generate_schema_endpoint(table_name: str, fields: list = Body(...)):
|
| 35 |
+
return await builder_service.generate_schema(table_name, fields)
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
@router.post("/generate/pipeline")
|
| 39 |
+
def generate_pipeline_endpoint(target: str = "docker"):
|
| 40 |
+
return builder_service.generate_pipeline(target)
|
builds.db
ADDED
|
Binary file (32.8 kB). View file
|
|
|
builds_e2e.db
ADDED
|
Binary file (28.7 kB). View file
|
|
|
builds_test.db
ADDED
|
Binary file (28.7 kB). View file
|
|
|
bundle_parser.py
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
bundle_parser.py
|
| 3 |
+
|
| 4 |
+
Parses AI-generated multi-file bundles that use `// File: <path>` markers
|
| 5 |
+
to separate individual files within a single LLM completion.
|
| 6 |
+
Stdlib-only — no third-party dependencies.
|
| 7 |
+
"""
|
| 8 |
+
|
| 9 |
+
from __future__ import annotations
|
| 10 |
+
|
| 11 |
+
import re
|
| 12 |
+
import logging
|
| 13 |
+
from dataclasses import dataclass, field
|
| 14 |
+
from pathlib import PurePosixPath
|
| 15 |
+
from typing import List, Optional, Tuple, Dict
|
| 16 |
+
|
| 17 |
+
logger = logging.getLogger("bundle_parser")
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
class BundleParseError(Exception):
|
| 21 |
+
"""Raised when a bundle contains no recognizable file markers at all."""
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
@dataclass
|
| 25 |
+
class ParsedFile:
|
| 26 |
+
path: str
|
| 27 |
+
content: str
|
| 28 |
+
language: Optional[str] = None
|
| 29 |
+
warnings: List[str] = field(default_factory=list)
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
@dataclass
|
| 33 |
+
class ParseResult:
|
| 34 |
+
files: List[ParsedFile]
|
| 35 |
+
raw_marker_count: int
|
| 36 |
+
skipped: List[str] = field(default_factory=list)
|
| 37 |
+
|
| 38 |
+
@property
|
| 39 |
+
def ok(self) -> bool:
|
| 40 |
+
return len(self.files) > 0
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
_FILE_MARKER_RE = re.compile(
|
| 44 |
+
r'''^[ \t]*(?://|\#|<!--)\s*File:\s*(?P<path>[^\n*]+?)\s*(?:-->)?\s*$''',
|
| 45 |
+
re.IGNORECASE | re.MULTILINE,
|
| 46 |
+
)
|
| 47 |
+
|
| 48 |
+
_FENCE_OPEN_RE = re.compile(r'^[ \t]*```[ \t]*([A-Za-z0-9_+-]*)[ \t]*$', re.MULTILINE)
|
| 49 |
+
_FENCE_CLOSE_RE = re.compile(r'^[ \t]*```[ \t]*$')
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
def _sanitize_path(raw_path: str) -> Optional[str]:
|
| 53 |
+
if not raw_path:
|
| 54 |
+
return None
|
| 55 |
+
path = raw_path.strip().strip('`').strip('"').strip("'")
|
| 56 |
+
path = path.replace('\\', '/')
|
| 57 |
+
while path.startswith('./'):
|
| 58 |
+
path = path[2:]
|
| 59 |
+
if not path or path.isspace():
|
| 60 |
+
return None
|
| 61 |
+
p = PurePosixPath(path)
|
| 62 |
+
if p.is_absolute():
|
| 63 |
+
return None
|
| 64 |
+
if '..' in p.parts:
|
| 65 |
+
return None
|
| 66 |
+
cleaned_parts = [part for part in p.parts if part not in ('', '.')]
|
| 67 |
+
if not cleaned_parts:
|
| 68 |
+
return None
|
| 69 |
+
return '/'.join(cleaned_parts)
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
def _strip_fence(block: str) -> Tuple[str, Optional[str]]:
|
| 73 |
+
lines = block.split('\n')
|
| 74 |
+
start_idx = None
|
| 75 |
+
lang = None
|
| 76 |
+
for i, line in enumerate(lines):
|
| 77 |
+
m = _FENCE_OPEN_RE.match(line)
|
| 78 |
+
if m:
|
| 79 |
+
start_idx = i
|
| 80 |
+
lang = m.group(1) or None
|
| 81 |
+
break
|
| 82 |
+
if line.strip():
|
| 83 |
+
break
|
| 84 |
+
if start_idx is None:
|
| 85 |
+
return block.strip('\n'), None
|
| 86 |
+
end_idx = None
|
| 87 |
+
for j in range(start_idx + 1, len(lines)):
|
| 88 |
+
if _FENCE_CLOSE_RE.match(lines[j]):
|
| 89 |
+
end_idx = j
|
| 90 |
+
break
|
| 91 |
+
if end_idx is None:
|
| 92 |
+
content = '\n'.join(lines[start_idx + 1:])
|
| 93 |
+
return content.strip('\n'), lang
|
| 94 |
+
content = '\n'.join(lines[start_idx + 1:end_idx])
|
| 95 |
+
return content.strip('\n'), lang
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
def parse_bundle(raw_text: str) -> ParseResult:
|
| 99 |
+
if not raw_text or not raw_text.strip():
|
| 100 |
+
raise BundleParseError("empty bundle: no text to parse")
|
| 101 |
+
markers = list(_FILE_MARKER_RE.finditer(raw_text))
|
| 102 |
+
if not markers:
|
| 103 |
+
raise BundleParseError("no '// File: <path>' markers found in bundle")
|
| 104 |
+
|
| 105 |
+
files: List[ParsedFile] = []
|
| 106 |
+
skipped: List[str] = []
|
| 107 |
+
seen_paths: Dict[str, int] = {}
|
| 108 |
+
|
| 109 |
+
for idx, match in enumerate(markers):
|
| 110 |
+
raw_path = match.group('path')
|
| 111 |
+
block_start = match.end()
|
| 112 |
+
block_end = markers[idx + 1].start() if idx + 1 < len(markers) else len(raw_text)
|
| 113 |
+
raw_block = raw_text[block_start:block_end]
|
| 114 |
+
|
| 115 |
+
safe_path = _sanitize_path(raw_path)
|
| 116 |
+
if safe_path is None:
|
| 117 |
+
skipped.append(raw_path.strip() if raw_path else '(empty path)')
|
| 118 |
+
logger.warning("bundle_parser: skipping unsafe/empty path %r", raw_path)
|
| 119 |
+
continue
|
| 120 |
+
|
| 121 |
+
content, lang = _strip_fence(raw_block)
|
| 122 |
+
warnings: List[str] = []
|
| 123 |
+
if not content.strip():
|
| 124 |
+
warnings.append("file body is empty after stripping markers/fences")
|
| 125 |
+
if content and not content.endswith('\n'):
|
| 126 |
+
content += '\n'
|
| 127 |
+
if safe_path in seen_paths:
|
| 128 |
+
warnings.append(f"duplicate path, overwriting earlier block #{seen_paths[safe_path]}")
|
| 129 |
+
files = [f for f in files if f.path != safe_path]
|
| 130 |
+
seen_paths[safe_path] = idx
|
| 131 |
+
files.append(ParsedFile(path=safe_path, content=content, language=lang, warnings=warnings))
|
| 132 |
+
|
| 133 |
+
return ParseResult(files=files, raw_marker_count=len(markers), skipped=skipped)
|
| 134 |
+
|
| 135 |
+
|
| 136 |
+
def summarize(result: ParseResult) -> str:
|
| 137 |
+
lines = [f"Parsed {len(result.files)} file(s) from {result.raw_marker_count} marker(s)."]
|
| 138 |
+
for f in result.files:
|
| 139 |
+
tag = f" [{', '.join(f.warnings)}]" if f.warnings else ""
|
| 140 |
+
lines.append(f" - {f.path} ({len(f.content)} bytes){tag}")
|
| 141 |
+
if result.skipped:
|
| 142 |
+
lines.append(f"Skipped {len(result.skipped)} unsafe/empty path(s): {result.skipped}")
|
| 143 |
+
return '\n'.join(lines)
|
capability_scanner.py
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import asyncio
|
| 2 |
+
import json
|
| 3 |
+
import httpx
|
| 4 |
+
|
| 5 |
+
from remote_mcp_registry import list_servers
|
| 6 |
+
|
| 7 |
+
INIT_REQUEST = {
|
| 8 |
+
"jsonrpc": "2.0",
|
| 9 |
+
"id": 1,
|
| 10 |
+
"method": "initialize",
|
| 11 |
+
"params": {
|
| 12 |
+
"protocolVersion": "2025-03-26",
|
| 13 |
+
"capabilities": {},
|
| 14 |
+
"clientInfo": {
|
| 15 |
+
"name": "dolor3v-mcp-core",
|
| 16 |
+
"version": "1.0.0"
|
| 17 |
+
}
|
| 18 |
+
}
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
async def scan():
|
| 22 |
+
results=[]
|
| 23 |
+
|
| 24 |
+
async with httpx.AsyncClient(timeout=20, follow_redirects=True) as client:
|
| 25 |
+
for server in list_servers():
|
| 26 |
+
item={
|
| 27 |
+
"id":server["id"],
|
| 28 |
+
"endpoint":server["endpoint"]
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
try:
|
| 32 |
+
r=await client.post(
|
| 33 |
+
server["endpoint"],
|
| 34 |
+
json=INIT_REQUEST,
|
| 35 |
+
headers={"Content-Type":"application/json"}
|
| 36 |
+
)
|
| 37 |
+
|
| 38 |
+
item["http_status"]=r.status_code
|
| 39 |
+
|
| 40 |
+
try:
|
| 41 |
+
item["response"]=r.json()
|
| 42 |
+
except Exception:
|
| 43 |
+
item["response"]=r.text[:1000]
|
| 44 |
+
|
| 45 |
+
except Exception as e:
|
| 46 |
+
item["error"]=type(e).__name__
|
| 47 |
+
item["message"]=str(e)
|
| 48 |
+
|
| 49 |
+
results.append(item)
|
| 50 |
+
|
| 51 |
+
print(json.dumps(results,indent=2))
|
| 52 |
+
|
| 53 |
+
if __name__=="__main__":
|
| 54 |
+
asyncio.run(scan())
|
check_env.py
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
|
| 3 |
+
print("DATABASE_URL =", os.getenv("DATABASE_URL"))
|
| 4 |
+
print("POSTGRES_SERVER =", os.getenv("POSTGRES_SERVER"))
|
| 5 |
+
print("POSTGRES_PORT =", os.getenv("POSTGRES_PORT"))
|
| 6 |
+
print("POSTGRES_USER =", os.getenv("POSTGRES_USER"))
|
| 7 |
+
print("POSTGRES_DB =", os.getenv("POSTGRES_DB"))
|
compiler.py
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import asyncio
|
| 2 |
+
import shutil
|
| 3 |
+
import subprocess
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
|
| 6 |
+
ANDROID_HOME = Path("/opt/android-sdk")
|
| 7 |
+
GRADLE = shutil.which("gradle") or shutil.which("./gradlew")
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
async def run(cmd, cwd=None):
|
| 11 |
+
process = await asyncio.create_subprocess_exec(
|
| 12 |
+
*cmd,
|
| 13 |
+
cwd=cwd,
|
| 14 |
+
stdout=asyncio.subprocess.PIPE,
|
| 15 |
+
stderr=asyncio.subprocess.STDOUT,
|
| 16 |
+
)
|
| 17 |
+
|
| 18 |
+
output = []
|
| 19 |
+
|
| 20 |
+
while True:
|
| 21 |
+
line = await process.stdout.readline()
|
| 22 |
+
if not line:
|
| 23 |
+
break
|
| 24 |
+
output.append(line.decode())
|
| 25 |
+
|
| 26 |
+
code = await process.wait()
|
| 27 |
+
|
| 28 |
+
return code, "".join(output)
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
async def compile_android(project_dir: str):
|
| 32 |
+
|
| 33 |
+
project = Path(project_dir)
|
| 34 |
+
|
| 35 |
+
gradlew = project / "gradlew"
|
| 36 |
+
|
| 37 |
+
if gradlew.exists():
|
| 38 |
+
gradle = "./gradlew"
|
| 39 |
+
else:
|
| 40 |
+
gradle = GRADLE
|
| 41 |
+
|
| 42 |
+
if gradle is None:
|
| 43 |
+
raise RuntimeError("Gradle not installed")
|
| 44 |
+
|
| 45 |
+
code, log = await run(
|
| 46 |
+
[gradle, "assembleRelease"],
|
| 47 |
+
cwd=str(project)
|
| 48 |
+
)
|
| 49 |
+
|
| 50 |
+
if code != 0:
|
| 51 |
+
raise RuntimeError(log)
|
| 52 |
+
|
| 53 |
+
apk = next(
|
| 54 |
+
project.glob("**/outputs/apk/release/*.apk"),
|
| 55 |
+
None
|
| 56 |
+
)
|
| 57 |
+
|
| 58 |
+
aab = next(
|
| 59 |
+
project.glob("**/outputs/bundle/release/*.aab"),
|
| 60 |
+
None
|
| 61 |
+
)
|
| 62 |
+
|
| 63 |
+
if apk:
|
| 64 |
+
return str(apk)
|
| 65 |
+
|
| 66 |
+
if aab:
|
| 67 |
+
return str(aab)
|
| 68 |
+
|
| 69 |
+
raise RuntimeError("No APK or AAB generated")
|
data/agent_memory.db
ADDED
|
Binary file (28.7 kB). View file
|
|
|
db_patch.py
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import ssl
|
| 3 |
+
import asyncpg
|
| 4 |
+
from typing import Optional
|
| 5 |
+
|
| 6 |
+
DATABASE_URL = os.environ.get("DATABASE_URL", "").strip()
|
| 7 |
+
|
| 8 |
+
POSTGRES_SERVER = os.environ.get("POSTGRES_SERVER", "").strip()
|
| 9 |
+
POSTGRES_PORT = int(os.environ.get("POSTGRES_PORT", "5432"))
|
| 10 |
+
POSTGRES_USER = os.environ.get("POSTGRES_USER", "").strip()
|
| 11 |
+
POSTGRES_PASSWORD = os.environ.get("POSTGRES_PASSWORD", "").strip()
|
| 12 |
+
POSTGRES_DB = os.environ.get("POSTGRES_DB", "").strip()
|
| 13 |
+
|
| 14 |
+
db_pool: Optional[asyncpg.Pool] = None
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
async def init_db_pool() -> asyncpg.Pool:
|
| 18 |
+
"""
|
| 19 |
+
Production database initialization.
|
| 20 |
+
|
| 21 |
+
Priority:
|
| 22 |
+
1. DATABASE_URL
|
| 23 |
+
2. POSTGRES_* variables
|
| 24 |
+
"""
|
| 25 |
+
|
| 26 |
+
ssl_ctx = ssl.create_default_context()
|
| 27 |
+
ssl_ctx.check_hostname = False
|
| 28 |
+
ssl_ctx.verify_mode = ssl.CERT_NONE
|
| 29 |
+
|
| 30 |
+
if DATABASE_URL:
|
| 31 |
+
logger.info("Initializing PostgreSQL using DATABASE_URL")
|
| 32 |
+
|
| 33 |
+
pool = await asyncpg.create_pool(
|
| 34 |
+
dsn=DATABASE_URL,
|
| 35 |
+
ssl=ssl_ctx,
|
| 36 |
+
min_size=1,
|
| 37 |
+
max_size=5,
|
| 38 |
+
timeout=30,
|
| 39 |
+
command_timeout=60,
|
| 40 |
+
statement_cache_size=0,
|
| 41 |
+
)
|
| 42 |
+
|
| 43 |
+
else:
|
| 44 |
+
logger.info("Initializing PostgreSQL using POSTGRES_* variables")
|
| 45 |
+
|
| 46 |
+
pool = await asyncpg.create_pool(
|
| 47 |
+
host=POSTGRES_SERVER,
|
| 48 |
+
port=POSTGRES_PORT,
|
| 49 |
+
user=POSTGRES_USER,
|
| 50 |
+
password=POSTGRES_PASSWORD,
|
| 51 |
+
database=POSTGRES_DB,
|
| 52 |
+
ssl=ssl_ctx,
|
| 53 |
+
min_size=1,
|
| 54 |
+
max_size=5,
|
| 55 |
+
timeout=30,
|
| 56 |
+
command_timeout=60,
|
| 57 |
+
statement_cache_size=0,
|
| 58 |
+
)
|
| 59 |
+
|
| 60 |
+
async with pool.acquire() as conn:
|
| 61 |
+
|
| 62 |
+
await conn.execute("""
|
| 63 |
+
CREATE TABLE IF NOT EXISTS dolor3v_projects (
|
| 64 |
+
page_id TEXT PRIMARY KEY,
|
| 65 |
+
data JSONB NOT NULL,
|
| 66 |
+
created_at TIMESTAMPTZ DEFAULT now(),
|
| 67 |
+
updated_at TIMESTAMPTZ DEFAULT now()
|
| 68 |
+
)
|
| 69 |
+
""")
|
| 70 |
+
|
| 71 |
+
await conn.execute("""
|
| 72 |
+
CREATE TABLE IF NOT EXISTS dolor3v_assets (
|
| 73 |
+
id SERIAL PRIMARY KEY,
|
| 74 |
+
name TEXT NOT NULL,
|
| 75 |
+
url TEXT NOT NULL,
|
| 76 |
+
type TEXT NOT NULL,
|
| 77 |
+
created_at TIMESTAMPTZ DEFAULT now()
|
| 78 |
+
)
|
| 79 |
+
""")
|
| 80 |
+
|
| 81 |
+
await conn.execute("""
|
| 82 |
+
CREATE TABLE IF NOT EXISTS dolor3v_versions (
|
| 83 |
+
id SERIAL PRIMARY KEY,
|
| 84 |
+
project_id TEXT NOT NULL,
|
| 85 |
+
name TEXT NOT NULL,
|
| 86 |
+
data JSONB NOT NULL,
|
| 87 |
+
created_at TIMESTAMPTZ DEFAULT now()
|
| 88 |
+
)
|
| 89 |
+
""")
|
| 90 |
+
|
| 91 |
+
await conn.execute("""
|
| 92 |
+
CREATE TABLE IF NOT EXISTS dolor3v_builds (
|
| 93 |
+
id TEXT PRIMARY KEY,
|
| 94 |
+
project_id TEXT NOT NULL,
|
| 95 |
+
platform TEXT NOT NULL,
|
| 96 |
+
status TEXT NOT NULL,
|
| 97 |
+
logs TEXT NOT NULL,
|
| 98 |
+
download_url TEXT,
|
| 99 |
+
created_at TIMESTAMPTZ DEFAULT now()
|
| 100 |
+
)
|
| 101 |
+
""")
|
| 102 |
+
|
| 103 |
+
logger.info("Database pool initialized successfully.")
|
| 104 |
+
|
| 105 |
+
return pool
|
deployments.db
ADDED
|
Binary file (24.6 kB). View file
|
|
|
deployments_e2e.db
ADDED
|
Binary file (20.5 kB). View file
|
|
|
deployments_test.db
ADDED
|
Binary file (20.5 kB). View file
|
|
|