feat: add ISSLOP AI usage analysis CLI commands, game router, and politics topic
- Add `cmd_isslop_prune`, `cmd_isslop_clear`, `cmd_isslop_analyze` CLI commands for AI usage analysis job management - Register `/game` router with `index` and `farm` endpoints for Code Farm idle game - Add `politics` to allowed TOPICS constant replacing `signals` - Introduce `ISSLOP_DIR`, `ISSLOP_WORKSPACES_DIR`, `ISSLOP_RUNS_DIR`, `ISSLOP_MEDIA_DIR` config paths - Add `clear_user_stars` and `clear_user_projects_cache` calls on vote and project create/delete - Update `make prod` to use `nproc` workers via `DEVPLACE_WEB_WORKERS` env var - Convert `database.py` and `utils.py` to packages for modular structure - Add `devplace apikey` and `devplace token` CLI subcommands for API key and access token management
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
" retoor <retoor@molodetz.nl>
|
||||
" Self-contained config for the ppy container. No external plugins or managers:
|
||||
" it works out of the box with the stock vim, and the AI edit feature uses only
|
||||
" curl and the PRAVDA_* gateway env that every instance is launched with.
|
||||
" curl and the DEVPLACE_* gateway env that every instance is launched with.
|
||||
|
||||
set nocompatible
|
||||
filetype plugin indent on
|
||||
@@ -70,7 +70,7 @@ function! s:GetVisualSelection() abort
|
||||
endfunction
|
||||
|
||||
function! s:GatewayUrl() abort
|
||||
let l:base = substitute($PRAVDA_OPENAI_URL, '/\+$', '', '')
|
||||
let l:base = substitute($DEVPLACE_OPENAI_URL, '/\+$', '', '')
|
||||
if empty(l:base)
|
||||
return 'https://openai.app.molodetz.nl/v1/chat/completions'
|
||||
elseif l:base =~# '/chat/completions$'
|
||||
@@ -92,7 +92,7 @@ function! AiEditSelection() abort
|
||||
endif
|
||||
let l:prompt = l:instruction . "\n\nHere is the text:\n" . l:orig
|
||||
\ . "\n\nOutput only the transformed text. No explanations, markdown, or code blocks."
|
||||
let l:api_key = !empty($PRAVDA_API_KEY) ? $PRAVDA_API_KEY : $DEEPSEEK_API_KEY
|
||||
let l:api_key = !empty($DEVPLACE_API_KEY) ? $DEVPLACE_API_KEY : $DEEPSEEK_API_KEY
|
||||
let l:json = '{"model":"deepseek-chat","messages":[{"role":"user","content":' . json_encode(l:prompt) . '}]}'
|
||||
let l:cmd = 'curl -sS -X POST ' . shellescape(s:GatewayUrl())
|
||||
\ . ' -H ' . shellescape('Authorization: Bearer ' . l:api_key)
|
||||
|
||||
@@ -49,14 +49,14 @@ from urllib.parse import quote, unquote, urlencode, urlparse, urlsplit, urlunspl
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
def _resolve_devplace_url() -> str:
|
||||
base = os.environ.get("PRAVDA_BASE_URL", "").strip().rstrip("/")
|
||||
base = os.environ.get("DEVPLACE_BASE_URL", "").strip().rstrip("/")
|
||||
if base:
|
||||
return base
|
||||
return os.environ.get("DEVPLACE_URL", "https://devplace.net").strip().rstrip("/")
|
||||
|
||||
|
||||
def _resolve_llm_endpoint() -> str:
|
||||
base = os.environ.get("PRAVDA_OPENAI_URL", "").strip().rstrip("/")
|
||||
base = os.environ.get("DEVPLACE_OPENAI_URL", "").strip().rstrip("/")
|
||||
if not base:
|
||||
base = "https://openai.app.molodetz.nl/v1"
|
||||
return base if base.endswith("/chat/completions") else base + "/chat/completions"
|
||||
@@ -64,7 +64,7 @@ def _resolve_llm_endpoint() -> str:
|
||||
|
||||
DEVPLACE_URL = _resolve_devplace_url()
|
||||
DEVPLACE_API_KEY = (
|
||||
os.environ.get("PRAVDA_API_KEY")
|
||||
os.environ.get("DEVPLACE_API_KEY")
|
||||
or os.environ.get("DEVPLACE_API_KEY")
|
||||
or "019ea58c-fae0-7112-8025-e629a54104a4"
|
||||
)
|
||||
@@ -81,7 +81,7 @@ LLM_ENDPOINT = _resolve_llm_endpoint()
|
||||
LLM_BASE_URL = LLM_ENDPOINT.rsplit("/chat/completions", 1)[0]
|
||||
MODEL = "molodetz"
|
||||
LLM_API_KEY = str(
|
||||
os.environ.get("PRAVDA_API_KEY")
|
||||
os.environ.get("DEVPLACE_API_KEY")
|
||||
or os.environ.get("LLM_API_KEY")
|
||||
or ""
|
||||
)
|
||||
|
||||
@@ -659,7 +659,7 @@ from typing import Any, Callable, Optional
|
||||
from urllib.parse import urlencode, urlparse
|
||||
|
||||
def _resolve_llm_endpoint() -> str:
|
||||
base = os.environ.get("PRAVDA_OPENAI_URL", "").strip().rstrip("/")
|
||||
base = os.environ.get("DEVPLACE_OPENAI_URL", "").strip().rstrip("/")
|
||||
if not base:
|
||||
base = "https://openai.app.molodetz.nl/v1"
|
||||
return base if base.endswith("/chat/completions") else base + "/chat/completions"
|
||||
@@ -669,7 +669,7 @@ LLM_ENDPOINT = _resolve_llm_endpoint()
|
||||
LLM_BASE_URL = LLM_ENDPOINT.rsplit("/chat/completions", 1)[0]
|
||||
MODEL = "molodetz"
|
||||
API_KEY = (
|
||||
os.environ.get("PRAVDA_API_KEY")
|
||||
os.environ.get("DEVPLACE_API_KEY")
|
||||
or os.environ.get("LLM_API_KEY")
|
||||
or str(uuid.uuid4())
|
||||
)
|
||||
|
||||
Binary file not shown.
@@ -41,14 +41,14 @@ from urllib.error import HTTPError, URLError
|
||||
from urllib.parse import urlencode, urljoin, urlparse
|
||||
|
||||
def _resolve_api_url() -> str:
|
||||
base = os.environ.get("PRAVDA_OPENAI_URL", "").strip().rstrip("/")
|
||||
base = os.environ.get("DEVPLACE_OPENAI_URL", "").strip().rstrip("/")
|
||||
if not base:
|
||||
return "https://openai.app.molodetz.nl/v1/chat/completions"
|
||||
return base if base.endswith("/chat/completions") else base + "/chat/completions"
|
||||
|
||||
|
||||
API_URL = _resolve_api_url()
|
||||
API_KEY = os.environ.get("PRAVDA_API_KEY") or os.environ.get("DEEPSEEK_API_KEY") or ""
|
||||
API_KEY = os.environ.get("DEVPLACE_API_KEY") or os.environ.get("DEEPSEEK_API_KEY") or ""
|
||||
RSEARCH_BASE_URL = "https://rsearch.app.molodetz.nl"
|
||||
RSEARCH_MODES = ("search", "chat", "describe", "health")
|
||||
RSEARCH_MAX_BYTES = 8 * 1024 * 1024
|
||||
@@ -1644,7 +1644,7 @@ async def describe_image(prompt: str, image_path: str):
|
||||
|
||||
api_key = API_KEY
|
||||
if not api_key:
|
||||
return json.dumps({"status": "error", "error": "PRAVDA_API_KEY or DEEPSEEK_API_KEY missing"})
|
||||
return json.dumps({"status": "error", "error": "DEVPLACE_API_KEY or DEEPSEEK_API_KEY missing"})
|
||||
|
||||
payload = {
|
||||
"model": DEFAULT_MODEL,
|
||||
@@ -1811,7 +1811,7 @@ async def delegate(task: str, allowed_tools: Optional[list] = None):
|
||||
"""
|
||||
api_key = API_KEY
|
||||
if not api_key:
|
||||
return json.dumps({"status": "error", "error": "PRAVDA_API_KEY or DEEPSEEK_API_KEY missing"})
|
||||
return json.dumps({"status": "error", "error": "DEVPLACE_API_KEY or DEEPSEEK_API_KEY missing"})
|
||||
if allowed_tools:
|
||||
sub_payloads = [
|
||||
t for t in get_tool_payloads()
|
||||
@@ -2567,7 +2567,7 @@ async def amain(headed: bool = False, prompt: str = "", timeout: float = 0) -> N
|
||||
|
||||
api_key = API_KEY
|
||||
if not api_key:
|
||||
md.print("**Error:** `PRAVDA_API_KEY` or `DEEPSEEK_API_KEY` missing.")
|
||||
md.print("**Error:** `DEVPLACE_API_KEY` or `DEEPSEEK_API_KEY` missing.")
|
||||
sys.exit(1)
|
||||
|
||||
clone_mode = os.environ.get("MAK_CLONE_MODE") == "1"
|
||||
|
||||
Reference in New Issue
Block a user