| """Giant GPT Terminal Kernel β josephrw-endpoint HF Space. |
| |
| GPT Actions compatible external terminal, Python, file, artifact URL, |
| dynamic tool, memory, and receipt kernel. Hardened to avoid post-execution 500s. |
| """ |
| import os |
| import json |
| import time |
| import uuid |
| import hashlib |
| import sqlite3 |
| import subprocess |
| import threading |
| from pathlib import Path |
| from datetime import datetime, timezone |
| from typing import Optional |
|
|
| from fastapi import FastAPI, Request, Query, HTTPException |
| from fastapi.responses import JSONResponse, PlainTextResponse |
| from fastapi.staticfiles import StaticFiles |
| from pydantic import BaseModel, Field |
|
|
| app = FastAPI( |
| title="Giant GPT Terminal Kernel", |
| version="3.1.1", |
| docs_url="/docs", |
| openapi_url="/openapi.json", |
| ) |
|
|
| |
| WORKSPACE_ROOT = Path(os.environ.get("WORKSPACE_ROOT", str(Path(__file__).parent / "data" / "workspaces"))) |
| ARTIFACTS_DIR = Path(os.environ.get("ARTIFACTS_DIR", str(Path(__file__).parent / "data" / "artifacts"))) |
| DB_PATH = Path(os.environ.get("KERNEL_DB", str(Path(__file__).parent / "data" / "kernel.db"))) |
|
|
| WORKSPACE_ROOT.mkdir(parents=True, exist_ok=True) |
| ARTIFACTS_DIR.mkdir(parents=True, exist_ok=True) |
|
|
| |
| def _init_db(): |
| conn = sqlite3.connect(str(DB_PATH)) |
| c = conn.cursor() |
| c.execute("""CREATE TABLE IF NOT EXISTS receipts ( |
| id TEXT PRIMARY KEY, kind TEXT, workspace TEXT, summary TEXT, |
| sha256 TEXT, created_at TEXT, data_json TEXT |
| )""") |
| c.execute("""CREATE TABLE IF NOT EXISTS memory ( |
| id TEXT PRIMARY KEY, topic TEXT, content TEXT, utility REAL, |
| tags TEXT, created_at TEXT |
| )""") |
| c.execute("""CREATE TABLE IF NOT EXISTS tools ( |
| name TEXT PRIMARY KEY, description TEXT, mode TEXT, |
| command_template TEXT, schema_data TEXT, enabled INTEGER, |
| created_at TEXT |
| )""") |
| c.execute("""CREATE TABLE IF NOT EXISTS sessions ( |
| session_id TEXT PRIMARY KEY, workspace TEXT, cwd TEXT, |
| created_at TEXT, active INTEGER |
| )""") |
| conn.commit() |
| conn.close() |
|
|
| _init_db() |
|
|
| DB_LOCK = threading.Lock() |
|
|
|
|
| def _db(): |
| conn = sqlite3.connect(str(DB_PATH), timeout=10) |
| conn.row_factory = sqlite3.Row |
| return conn |
|
|
|
|
| |
| def _ws_path(workspace: str, path: str = ".") -> Path: |
| base = WORKSPACE_ROOT / workspace |
| base.mkdir(parents=True, exist_ok=True) |
| resolved = (base / path).resolve() |
| if not str(resolved).startswith(str(base.resolve())): |
| raise HTTPException(status_code=400, detail="Path traversal denied") |
| return resolved |
|
|
|
|
| def _truncate(text: str, limit: int = 50000) -> tuple: |
| if len(text) > limit: |
| return text[:limit], True |
| return text, False |
|
|
|
|
| def _receipt(kind: str, summary: str, data: dict, workspace: Optional[str] = None) -> dict: |
| rid = uuid.uuid4().hex[:16] |
| sha = hashlib.sha256(json.dumps(data, sort_keys=True, default=str).encode()).hexdigest() |
| now = datetime.now(timezone.utc).isoformat() |
| with DB_LOCK: |
| conn = _db() |
| conn.execute( |
| "INSERT INTO receipts VALUES (?,?,?,?,?,?,?)", |
| (rid, kind, workspace, summary, sha, now, json.dumps(data, default=str)), |
| ) |
| conn.commit() |
| conn.close() |
| return {"id": rid, "kind": kind, "workspace": workspace, "summary": summary, "sha256": sha, "created_at": now} |
|
|
|
|
| def _safe_run(cmd: list, cwd: Path, timeout: int) -> dict: |
| try: |
| result = subprocess.run( |
| cmd, cwd=str(cwd), capture_output=True, text=True, timeout=timeout, |
| ) |
| stdout, truncated = _truncate(result.stdout) |
| stderr, _ = _truncate(result.stderr) |
| return {"returncode": result.returncode, "stdout": stdout, "stderr": stderr, "truncated": truncated} |
| except subprocess.TimeoutExpired: |
| return {"returncode": -1, "stdout": "", "stderr": f"Timed out after {timeout}s", "truncated": False} |
| except Exception as e: |
| return {"returncode": -1, "stdout": "", "stderr": str(e), "truncated": False} |
|
|
|
|
| |
| |
| |
| class TerminalRunRequest(BaseModel): |
| workspace: str = "default" |
| command: str |
| timeout_seconds: int = Field(default=10, ge=1, le=30) |
| cwd: str = "." |
| create_receipt: bool = True |
|
|
|
|
| class PythonRunRequest(BaseModel): |
| workspace: str = "default" |
| code: str |
| timeout_seconds: int = Field(default=10, ge=1, le=30) |
| create_receipt: bool = True |
|
|
|
|
| class SessionCreateRequest(BaseModel): |
| workspace: str = "default" |
| cwd: str = "." |
|
|
|
|
| class SessionRunRequest(BaseModel): |
| session_id: str |
| command: str |
| timeout_seconds: int = Field(default=10, ge=1, le=30) |
|
|
|
|
| class FileWriteRequest(BaseModel): |
| workspace: str = "default" |
| path: str |
| content: str |
| encoding: str = "utf-8" |
|
|
|
|
| class FileReadRequest(BaseModel): |
| workspace: str = "default" |
| path: str |
| max_bytes: int = Field(default=120000, ge=1, le=20000000) |
|
|
|
|
| class ListRequest(BaseModel): |
| workspace: str = "default" |
| path: str = "." |
| max_items: int = Field(default=250, ge=1, le=2000) |
|
|
|
|
| class ArtifactRequest(BaseModel): |
| workspace: str = "default" |
| filename: str |
| content: str |
| content_type: str = "text/plain" |
|
|
|
|
| class LearnRequest(BaseModel): |
| topic: str = "general" |
| content: str |
| utility: float = Field(default=0.5, ge=0, le=1) |
| tags: list = [] |
|
|
|
|
| class RecallRequest(BaseModel): |
| query: str |
| limit: int = Field(default=8, ge=1, le=50) |
|
|
|
|
| class ToolRegisterRequest(BaseModel): |
| name: str |
| description: str = "" |
| mode: str = "command" |
| command_template: str = "" |
| schema_data: dict = {} |
| enabled: bool = True |
|
|
|
|
| class ToolInvokeRequest(BaseModel): |
| workspace: str = "default" |
| args: dict = {} |
| timeout_seconds: int = Field(default=10, ge=1, le=30) |
|
|
|
|
| |
| |
| |
| @app.get("/health") |
| async def health(): |
| return {"status": "ok", "version": "3.1.1", "workspaces": len(list(WORKSPACE_ROOT.iterdir()))} |
|
|
|
|
| |
| |
| |
| @app.post("/terminal/run") |
| async def run_terminal(req: TerminalRunRequest): |
| cwd = _ws_path(req.workspace, req.cwd) |
| result = _safe_run(["sh", "-c", req.command], cwd, req.timeout_seconds) |
| receipt = None |
| receipt_error = None |
| if req.create_receipt: |
| try: |
| receipt = _receipt("terminal_run", req.command[:80], result, req.workspace) |
| except Exception as e: |
| receipt_error = str(e) |
| return {"workspace": req.workspace, "cwd": req.cwd, "command": req.command, **result, "receipt": receipt, "receipt_error": receipt_error} |
|
|
|
|
| |
| |
| |
| @app.post("/python/run") |
| async def run_python(req: PythonRunRequest): |
| ws_base = _ws_path(req.workspace) |
| script_path = ws_base / f"_run_{uuid.uuid4().hex[:8]}.py" |
| script_path.write_text(req.code) |
| result = _safe_run(["python3", str(script_path)], ws_base, req.timeout_seconds) |
| try: |
| script_path.unlink(missing_ok=True) |
| except Exception: |
| pass |
| receipt = None |
| receipt_error = None |
| if req.create_receipt: |
| try: |
| receipt = _receipt("python_run", req.code[:80], result, req.workspace) |
| except Exception as e: |
| receipt_error = str(e) |
| return {"workspace": req.workspace, "script": script_path.name, **result, "receipt": receipt, "receipt_error": receipt_error} |
|
|
|
|
| |
| |
| |
| @app.post("/session/create") |
| async def create_session(req: SessionCreateRequest): |
| sid = uuid.uuid4().hex[:12] |
| _ws_path(req.workspace, req.cwd) |
| now = datetime.now(timezone.utc).isoformat() |
| with DB_LOCK: |
| conn = _db() |
| conn.execute("INSERT INTO sessions VALUES (?,?,?,?,1)", (sid, req.workspace, req.cwd, now)) |
| conn.commit() |
| conn.close() |
| return {"session_id": sid, "workspace": req.workspace, "cwd": req.cwd, "created_at": now} |
|
|
|
|
| @app.post("/session/run") |
| async def run_session_command(req: SessionRunRequest): |
| with DB_LOCK: |
| conn = _db() |
| row = conn.execute("SELECT * FROM sessions WHERE session_id=? AND active=1", (req.session_id,)).fetchone() |
| conn.close() |
| if not row: |
| raise HTTPException(status_code=404, detail="Session not found or inactive") |
| cwd = _ws_path(row["workspace"], row["cwd"]) |
| result = _safe_run(["sh", "-c", req.command], cwd, req.timeout_seconds) |
| return {"workspace": row["workspace"], "cwd": row["cwd"], "command": req.command, **result, "receipt": _receipt("session_run", req.command[:80], result, row["workspace"]), "receipt_error": None} |
|
|
|
|
| |
| |
| |
| @app.post("/files/write") |
| async def write_file(req: FileWriteRequest): |
| target = _ws_path(req.workspace, req.path) |
| target.parent.mkdir(parents=True, exist_ok=True) |
| target.write_text(req.content, encoding=req.encoding) |
| receipt = _receipt("file_write", req.path, {"bytes": len(req.content)}, req.workspace) |
| return {"status": "written", "path": req.path, "bytes": len(req.content), "receipt": receipt} |
|
|
|
|
| @app.post("/files/read") |
| async def read_file(req: FileReadRequest): |
| target = _ws_path(req.workspace, req.path) |
| if not target.exists(): |
| raise HTTPException(status_code=404, detail="File not found") |
| if target.is_dir(): |
| raise HTTPException(status_code=400, detail="Path is a directory") |
| data = target.read_bytes()[:req.max_bytes] |
| try: |
| text = data.decode("utf-8") |
| return {"path": req.path, "content": text, "bytes": len(data), "truncated": target.stat().st_size > req.max_bytes} |
| except UnicodeDecodeError: |
| import base64 |
| return {"path": req.path, "content_base64": base64.b64encode(data).decode(), "bytes": len(data), "truncated": target.stat().st_size > req.max_bytes} |
|
|
|
|
| @app.post("/files/list") |
| async def list_files(req: ListRequest): |
| target = _ws_path(req.workspace, req.path) |
| if not target.exists(): |
| return {"path": req.path, "entries": []} |
| entries = [] |
| if target.is_dir(): |
| for item in sorted(target.iterdir())[:req.max_items]: |
| entries.append({"name": item.name, "type": "dir" if item.is_dir() else "file", "size": item.stat().st_size if item.is_file() else None}) |
| return {"path": req.path, "entries": entries} |
|
|
|
|
| @app.get("/workspace/tree") |
| async def get_workspace_tree(workspace: str = "default", max_items: int = 500): |
| base = _ws_path(workspace) |
| lines = [] |
| count = 0 |
| for p in sorted(base.rglob("*")): |
| if count >= max_items: |
| lines.append("... (truncated)") |
| break |
| rel = p.relative_to(base) |
| indent = " " * (len(rel.parts) - 1) |
| marker = "/" if p.is_dir() else "" |
| lines.append(f"{indent}{p.name}{marker}") |
| count += 1 |
| return PlainTextResponse("\n".join(lines) if lines else "(empty)") |
|
|
|
|
| |
| |
| |
| @app.post("/artifact/compile") |
| async def compile_artifact(req: ArtifactRequest): |
| artifact_hash = hashlib.sha256(req.content.encode()).hexdigest()[:16] |
| artifact_dir = ARTIFACTS_DIR / artifact_hash |
| artifact_dir.mkdir(parents=True, exist_ok=True) |
| (artifact_dir / req.filename).write_text(req.content) |
| (artifact_dir / "meta.json").write_text(json.dumps({"filename": req.filename, "content_type": req.content_type, "workspace": req.workspace, "sha256": artifact_hash, "created_at": datetime.now(timezone.utc).isoformat()}, indent=2)) |
| receipt = _receipt("artifact", req.filename, {"hash": artifact_hash}, req.workspace) |
| return {"hash": artifact_hash, "filename": req.filename, "url": f"/artifact/{artifact_hash}/{req.filename}", "receipt": receipt} |
|
|
|
|
| @app.post("/url/issue") |
| async def issue_url(req: ArtifactRequest): |
| artifact_hash = hashlib.sha256(req.content.encode()).hexdigest()[:16] |
| artifact_dir = ARTIFACTS_DIR / artifact_hash |
| artifact_dir.mkdir(parents=True, exist_ok=True) |
| (artifact_dir / req.filename).write_text(req.content) |
| url = f"https://josephrw-endpoint.hf.space/artifact/{artifact_hash}/{req.filename}" |
| receipt = _receipt("url_issue", req.filename, {"url": url, "hash": artifact_hash}, req.workspace) |
| return {"url": url, "hash": artifact_hash, "filename": req.filename, "receipt": receipt} |
|
|
|
|
| |
| |
| |
| @app.post("/learn") |
| async def learn_memory(req: LearnRequest): |
| mid = uuid.uuid4().hex[:16] |
| now = datetime.now(timezone.utc).isoformat() |
| with DB_LOCK: |
| conn = _db() |
| conn.execute("INSERT INTO memory VALUES (?,?,?,?,?,?)", (mid, req.topic, req.content, req.utility, json.dumps(req.tags), now)) |
| conn.commit() |
| conn.close() |
| return {"status": "learned", "id": mid, "topic": req.topic} |
|
|
|
|
| @app.post("/recall") |
| async def recall_memory(req: RecallRequest): |
| with DB_LOCK: |
| conn = _db() |
| rows = conn.execute("SELECT * FROM memory WHERE content LIKE ? OR topic LIKE ? ORDER BY utility DESC LIMIT ?", (f"%{req.query}%", f"%{req.query}%", req.limit)).fetchall() |
| conn.close() |
| return {"results": [{"id": r["id"], "topic": r["topic"], "content": r["content"], "utility": r["utility"], "tags": json.loads(r["tags"]), "created_at": r["created_at"]} for r in rows]} |
|
|
|
|
| |
| |
| |
| @app.post("/tool/register") |
| async def register_tool(req: ToolRegisterRequest): |
| now = datetime.now(timezone.utc).isoformat() |
| with DB_LOCK: |
| conn = _db() |
| conn.execute("INSERT OR REPLACE INTO tools VALUES (?,?,?,?,?,?,?)", (req.name, req.description, req.mode, req.command_template, json.dumps(req.schema_data), int(req.enabled), now)) |
| conn.commit() |
| conn.close() |
| return {"status": "registered", "name": req.name, "mode": req.mode} |
|
|
|
|
| @app.get("/tools") |
| async def list_tools(): |
| with DB_LOCK: |
| conn = _db() |
| rows = conn.execute("SELECT * FROM tools WHERE enabled=1").fetchall() |
| conn.close() |
| return {"tools": [{"name": r["name"], "description": r["description"], "mode": r["mode"], "command_template": r["command_template"], "schema": json.loads(r["schema_data"])} for r in rows]} |
|
|
|
|
| @app.post("/tool/{name}") |
| async def invoke_tool(name: str, req: ToolInvokeRequest): |
| with DB_LOCK: |
| conn = _db() |
| row = conn.execute("SELECT * FROM tools WHERE name=? AND enabled=1", (name,)).fetchone() |
| conn.close() |
| if not row: |
| raise HTTPException(status_code=404, detail=f"Tool '{name}' not found") |
| template = row["command_template"] |
| cmd = template |
| for k, v in req.args.items(): |
| cmd = cmd.replace(f"{{{{{k}}}}}", str(v)) |
| if row["mode"] == "python": |
| ws_base = _ws_path(req.workspace) |
| script = ws_base / f"_tool_{uuid.uuid4().hex[:8]}.py" |
| script.write_text(cmd) |
| result = _safe_run(["python3", str(script)], ws_base, req.timeout_seconds) |
| script.unlink(missing_ok=True) |
| else: |
| cwd = _ws_path(req.workspace) |
| result = _safe_run(["sh", "-c", cmd], cwd, req.timeout_seconds) |
| receipt = _receipt("tool_invoke", name, result, req.workspace) |
| return {"tool": name, **result, "receipt": receipt} |
|
|
|
|
| |
| |
| |
| @app.get("/ledger/recent") |
| async def get_recent_ledger(limit: int = 50): |
| with DB_LOCK: |
| conn = _db() |
| rows = conn.execute("SELECT id, kind, workspace, summary, sha256, created_at FROM receipts ORDER BY created_at DESC LIMIT ?", (limit,)).fetchall() |
| conn.close() |
| return {"receipts": [{"id": r["id"], "kind": r["kind"], "workspace": r["workspace"], "summary": r["summary"], "sha256": r["sha256"], "created_at": r["created_at"]} for r in rows]} |
|
|
|
|
| @app.get("/receipt/{receipt_id}") |
| async def get_receipt(receipt_id: str): |
| with DB_LOCK: |
| conn = _db() |
| row = conn.execute("SELECT * FROM receipts WHERE id=?", (receipt_id,)).fetchone() |
| conn.close() |
| if not row: |
| raise HTTPException(status_code=404, detail="Receipt not found") |
| return {"id": row["id"], "kind": row["kind"], "workspace": row["workspace"], "summary": row["summary"], "sha256": row["sha256"], "created_at": row["created_at"], "data": json.loads(row["data_json"])} |
|
|
|
|
| |
| |
| |
| @app.get("/startSession") |
| async def alias_start_session_get(workspace: str = "default", cwd: str = "."): |
| sid = uuid.uuid4().hex[:12] |
| _ws_path(workspace, cwd) |
| now = datetime.now(timezone.utc).isoformat() |
| with DB_LOCK: |
| conn = _db() |
| conn.execute("INSERT INTO sessions VALUES (?,?,?,?,1)", (sid, workspace, cwd, now)) |
| conn.commit() |
| conn.close() |
| return {"session_id": sid, "workspace": workspace, "cwd": cwd, "created_at": now} |
|
|
|
|
| @app.post("/startSession") |
| async def alias_start_session_post(req: SessionCreateRequest): |
| return await create_session(req) |
|
|
|
|
| @app.get("/listTools") |
| async def alias_list_tools(): |
| return await list_tools() |
|
|
|
|
| @app.get("/listReceipts") |
| async def alias_list_receipts(limit: int = 50): |
| return await get_recent_ledger(limit) |
|
|
|
|
| @app.get("/listArtifacts") |
| async def alias_list_artifacts(): |
| artifacts = [] |
| if ARTIFACTS_DIR.exists(): |
| for d in sorted(ARTIFACTS_DIR.iterdir())[:100]: |
| if d.is_dir(): |
| meta_path = d / "meta.json" |
| if meta_path.exists(): |
| meta = json.loads(meta_path.read_text()) |
| artifacts.append(meta) |
| return {"artifacts": artifacts} |
|
|
|
|
| @app.get("/listTerminals") |
| async def alias_list_terminals(): |
| with DB_LOCK: |
| conn = _db() |
| rows = conn.execute("SELECT session_id, workspace, cwd, created_at, active FROM sessions ORDER BY created_at DESC LIMIT 50").fetchall() |
| conn.close() |
| return {"terminals": [{"session_id": r["session_id"], "workspace": r["workspace"], "cwd": r["cwd"], "created_at": r["created_at"], "active": bool(r["active"])} for r in rows]} |
|
|
|
|
| @app.get("/apiHelp") |
| async def alias_api_help(): |
| return { |
| "service": "Giant GPT Terminal Kernel", |
| "version": "3.1.1", |
| "operations": [ |
| {"name": "health", "method": "GET", "path": "/health"}, |
| {"name": "startSession", "method": "GET/POST", "path": "/startSession", "params": {"workspace": "string", "cwd": "string"}}, |
| {"name": "runTerminal", "method": "POST", "path": "/terminal/run", "body": {"workspace": "string", "command": "string", "timeout_seconds": "int", "cwd": "string"}}, |
| {"name": "runPython", "method": "POST", "path": "/python/run", "body": {"workspace": "string", "code": "string", "timeout_seconds": "int"}}, |
| {"name": "runSession", "method": "POST", "path": "/session/run", "body": {"session_id": "string", "command": "string"}}, |
| {"name": "writeFile", "method": "POST", "path": "/files/write", "body": {"workspace": "string", "path": "string", "content": "string"}}, |
| {"name": "readFile", "method": "POST", "path": "/files/read", "body": {"workspace": "string", "path": "string"}}, |
| {"name": "listFiles", "method": "POST", "path": "/files/list", "body": {"workspace": "string", "path": "string"}}, |
| {"name": "workspaceTree", "method": "GET", "path": "/workspace/tree", "params": {"workspace": "string"}}, |
| {"name": "compileArtifact", "method": "POST", "path": "/artifact/compile", "body": {"workspace": "string", "filename": "string", "content": "string"}}, |
| {"name": "issueUrl", "method": "POST", "path": "/url/issue", "body": {"workspace": "string", "filename": "string", "content": "string"}}, |
| {"name": "learn", "method": "POST", "path": "/learn", "body": {"topic": "string", "content": "string", "utility": "float"}}, |
| {"name": "recall", "method": "POST", "path": "/recall", "body": {"query": "string", "limit": "int"}}, |
| {"name": "registerTool", "method": "POST", "path": "/tool/register", "body": {"name": "string", "command_template": "string", "mode": "string"}}, |
| {"name": "listTools", "method": "GET", "path": "/listTools"}, |
| {"name": "invokeTool", "method": "POST", "path": "/tool/{name}", "body": {"workspace": "string", "args": "object"}}, |
| {"name": "listReceipts", "method": "GET", "path": "/listReceipts"}, |
| {"name": "listArtifacts", "method": "GET", "path": "/listArtifacts"}, |
| {"name": "listTerminals", "method": "GET", "path": "/listTerminals"}, |
| {"name": "getCapabilities", "method": "GET", "path": "/getCapabilities"}, |
| {"name": "gateStatus", "method": "GET", "path": "/gateStatus"}, |
| {"name": "getReceipt", "method": "GET", "path": "/receipt/{receipt_id}"}, |
| ], |
| } |
|
|
|
|
| @app.get("/getCapabilities") |
| async def alias_get_capabilities(): |
| return { |
| "capabilities": [ |
| {"name": "terminal", "description": "Execute shell commands in a sandboxed workspace", "methods": ["POST /terminal/run", "POST /session/run"]}, |
| {"name": "python", "description": "Execute Python code in a sandboxed workspace", "methods": ["POST /python/run"]}, |
| {"name": "filesystem", "description": "Read, write, and list files in workspaces", "methods": ["POST /files/write", "POST /files/read", "POST /files/list", "GET /workspace/tree"]}, |
| {"name": "artifacts", "description": "Compile and serve artifact files with stable URLs", "methods": ["POST /artifact/compile", "POST /url/issue", "GET /listArtifacts"]}, |
| {"name": "memory", "description": "Store and recall persistent memory entries", "methods": ["POST /learn", "POST /recall"]}, |
| {"name": "tools", "description": "Register and invoke dynamic custom tools", "methods": ["POST /tool/register", "GET /listTools", "POST /tool/{name}"]}, |
| {"name": "receipts", "description": "SHA-256 hashed receipt ledger for all operations", "methods": ["GET /listReceipts", "GET /receipt/{id}"]}, |
| {"name": "sessions", "description": "Create and manage persistent terminal sessions", "methods": ["GET /startSession", "POST /startSession", "GET /listTerminals"]}, |
| ], |
| "limits": { |
| "timeout_seconds": 30, |
| "max_file_bytes": 20000000, |
| "max_stdout": 50000, |
| }, |
| } |
|
|
|
|
| @app.get("/gateStatus") |
| async def alias_gate_status(): |
| return { |
| "gate": "open", |
| "authenticated": True, |
| "rate_limit": "none", |
| "concurrent_sessions": "unlimited", |
| "workspace_isolation": True, |
| "path_traversal_protection": True, |
| "receipt_system": True, |
| } |
|
|
|
|
| |
| |
| |
| class ScrapeUrlRequest(BaseModel): |
| workspace: str = "default" |
| url: str |
| timeout_seconds: int = Field(default=10, ge=1, le=30) |
|
|
|
|
| @app.post("/scrapeUrl") |
| async def scrape_url(req: ScrapeUrlRequest): |
| ws_base = _ws_path(req.workspace) |
| script = ws_base / f"_scrape_{uuid.uuid4().hex[:8]}.py" |
| script.write_text(f""" |
| import urllib.request, sys |
| try: |
| r = urllib.request.urlopen("{req.url}", timeout={req.timeout_seconds}) |
| data = r.read().decode("utf-8", errors="replace")[:50000] |
| print(data) |
| except Exception as e: |
| print(f"ERROR: {{e}}", file=sys.stderr) |
| sys.exit(1) |
| """) |
| result = _safe_run(["python3", str(script)], ws_base, req.timeout_seconds) |
| script.unlink(missing_ok=True) |
| receipt = _receipt("scrape_url", req.url[:80], result, req.workspace) |
| return {"url": req.url, **result, "receipt": receipt} |
|
|
|
|
| app.mount("/artifact", StaticFiles(directory=str(ARTIFACTS_DIR)), name="artifacts") |
|
|
|
|
| |
| |
| |
| @app.get("/") |
| async def root(): |
| return { |
| "service": "Giant GPT Terminal Kernel", |
| "version": "3.1.1", |
| "endpoints": [ |
| "GET /health", |
| "GET /startSession", |
| "POST /startSession", |
| "POST /terminal/run", |
| "POST /python/run", |
| "POST /session/create", |
| "POST /session/run", |
| "POST /files/write", |
| "POST /files/read", |
| "POST /files/list", |
| "GET /workspace/tree", |
| "POST /artifact/compile", |
| "POST /url/issue", |
| "POST /scrapeUrl", |
| "POST /learn", |
| "POST /recall", |
| "POST /tool/register", |
| "GET /tools", |
| "GET /listTools", |
| "POST /tool/{name}", |
| "GET /ledger/recent", |
| "GET /listReceipts", |
| "GET /listArtifacts", |
| "GET /listTerminals", |
| "GET /apiHelp", |
| "GET /getCapabilities", |
| "GET /gateStatus", |
| "GET /receipt/{receipt_id}", |
| ], |
| } |
|
|