Terminal / architecture.py
GitHub Action
sync: backend da GitHub 2026-05-18T11:59:53Z
e6fbc88
Raw
History Blame Contribute Delete
5.5 kB
"""
architecture.py — Free distributed no-PC architecture profile
The selected zero-cost architecture is deliberately split into control,
execution, tools and memory layers:
- iPhone/mobile browser: control surface only.
- GitHub Actions: event-triggered Agent Kernel and lightweight execution.
- Hugging Face Spaces: backend tools/API runtime, not a heavy persistent VM.
- LiteLLM/OpenAI-compatible provider routing: free remote model pool.
- GitHub repository: primary memory, code, task history and run reports.
This keeps the system usable without Replit, without a local PC and without
paid infrastructure while making the real limits explicit.
"""
from __future__ import annotations
import os
from dataclasses import dataclass, asdict
from typing import Any
@dataclass(frozen=True)
class Capability:
name: str
status: str
reason: str
FREE_REMOTE_PLAN = {
"name": "github_actions_hf_spaces_free_agent",
"label": "GitHub Actions + HF Spaces Free Agent Kernel",
"mode": "total_free_no_local_pc",
"control_surface": "iPhone via GitHub Actions workflow_dispatch or web frontend",
"primary_runtime": "GitHub Actions for agent runs; Hugging Face Spaces for backend tools/API",
"tool_runtime": "Hugging Face Spaces Docker free tier",
"memory_primary": "GitHub repository under .agent/ plus code/history",
"memory_secondary": "SQLite/local backend memory when the Space is available",
"principle": "Distributed backend-first agent kernel with safe-by-default GitHub memory, provider fallback and mobile review.",
"model_priority": ["openrouter", "gemini", "groq", "huggingface", "openai_compatible"],
"execution": "GitHub Actions for bounded jobs; backend allowlisted tools only; browser sandbox disabled by default",
}
def _env_enabled(name: str, default: bool = False) -> bool:
raw = os.getenv(name)
if raw is None:
return default
return raw.strip().lower() in {"1", "true", "yes", "on"}
def get_architecture_profile() -> dict[str, Any]:
"""Return runtime capabilities for the free no-PC deployment plan."""
providers = {
"openrouter": bool(os.getenv("OPENROUTER_API_KEY")),
"gemini": bool(os.getenv("GEMINI_API_KEY") or os.getenv("GOOGLE_API_KEY")),
"groq": bool(os.getenv("GROQ_API_KEY")),
"huggingface": bool(os.getenv("HF_TOKEN") or os.getenv("HUGGINGFACE_API_KEY") or os.getenv("HUGGINGFACE_TOKEN")),
"openai_compatible": bool(os.getenv("OPENAI_API_KEY")),
}
github_actions_configured = bool(os.getenv("GITHUB_ACTIONS") or os.getenv("GITHUB_REPOSITORY"))
github_token_configured = bool(os.getenv("GITHUB_TOKEN") or os.getenv("GH_TOKEN"))
capabilities = [
Capability("mobile_control", "enabled", "GitHub Actions workflow_dispatch and the frontend can be used from iPhone."),
Capability("github_actions_agent_kernel", "enabled", "Bounded agent runs execute in GitHub Actions and persist reports under .agent/."),
Capability("github_memory", "enabled", "State, task history and run reports are committed to the repository for durable zero-cost memory."),
Capability("hf_spaces_tools", "enabled", "The FastAPI backend remains the lightweight tools/API runtime for the free Space."),
Capability("litellm_routing", "enabled", "OpenAI-compatible provider order supports OpenRouter, Gemini, Groq, Hugging Face and optional OpenAI-compatible endpoints."),
Capability("sqlite_memory", "secondary", "Backend SQLite/local memory remains useful but is not the primary no-PC source of truth."),
Capability("qdrant", "optional", "Use only if an external free Qdrant endpoint is configured; not required for the baseline."),
Capability("openhands", "external_optional", "Full OpenHands remains too heavy for the free baseline and should not run inside the free Space."),
Capability("docker_sandbox", "disabled_on_free_space", "Nested Docker is intentionally disabled on the free plan."),
Capability("browser_sandbox", "disabled_by_default", "Client-side code execution is not a real isolated workspace and is not part of the main path."),
]
return {
"plan": FREE_REMOTE_PLAN,
"providers": providers,
"capabilities": [asdict(c) for c in capabilities],
"limits": {
"requires_local_pc": False,
"requires_paid_vm": False,
"runs_heavy_local_models": False,
"supports_nested_docker": False,
"long_running_24_7_agent": False,
"bounded_actions_runtime": True,
},
"github_actions": {
"workflow": ".github/workflows/agent-kernel.yml",
"workflow_template": "docs/workflows/agent-kernel.yml",
"activation_note": "Copy the template to .github/workflows/agent-kernel.yml with GitHub UI or a token that has workflow permission.",
"script": "scripts/agent_kernel.py",
"memory_dir": ".agent/",
"configured_in_current_runtime": github_actions_configured,
"token_available_in_current_runtime": github_token_configured,
"trigger_modes": ["workflow_dispatch", "issue_label_agent-run"],
},
"feature_flags": {
"browser_sandbox_enabled": _env_enabled("VITE_ENABLE_BROWSER_SANDBOX", False),
"browser_llm_enabled": _env_enabled("VITE_ENABLE_BROWSER_LLM", False),
"qdrant_enabled": bool(os.getenv("QDRANT_URL")),
},
}