Agora você pode testar os recursos do STUDIO AI AU

This commit is contained in:
Flatlogic Bot 2026-02-16 01:42:51 +00:00
parent 91243baf92
commit e17e54022a
6 changed files with 19 additions and 40 deletions

View File

@ -1,35 +1,5 @@
"""
LocalAIApi lightweight Python client for the Flatlogic AI proxy.
Usage (inside the Django workspace):
from ai.local_ai_api import LocalAIApi
response = LocalAIApi.create_response({
"input": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Summarise this text in two sentences."},
],
"text": {"format": {"type": "json_object"}},
})
if response.get("success"):
data = LocalAIApi.decode_json_from_response(response)
# ...
# Typical successful payload (truncated):
# {
# "id": "resp_xxx",
# "status": "completed",
# "output": [
# {"type": "reasoning", "summary": []},
# {"type": "message", "content": [{"type": "output_text", "text": "Your final answer here."}]}
# ],
# "usage": { "input_tokens": 123, "output_tokens": 456 }
# }
The helper automatically injects the project UUID header and falls back to
reading executor/.env if environment variables are missing.
"""
from __future__ import annotations
@ -145,6 +115,7 @@ def request(path: Optional[str], payload: Dict[str, Any], options: Optional[Dict
"Content-Type": "application/json",
"Accept": "application/json",
cfg["project_header"]: project_uuid,
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
}
extra_headers = options.get("headers")
if isinstance(extra_headers, Iterable):
@ -180,6 +151,7 @@ def fetch_status(ai_request_id: Any, options: Optional[Dict[str, Any]] = None) -
headers: Dict[str, str] = {
"Accept": "application/json",
cfg["project_header"]: project_uuid,
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
}
extra_headers = options.get("headers")
if isinstance(extra_headers, Iterable):
@ -294,7 +266,6 @@ def _extract_text(response: Dict[str, Any]) -> str:
return payload
return ""
def _config() -> Dict[str, Any]:
global _CONFIG_CACHE # noqa: PLW0603
if _CONFIG_CACHE is not None:
@ -314,13 +285,12 @@ def _config() -> Dict[str, Any]:
"project_id": project_id,
"project_uuid": os.getenv("PROJECT_UUID"),
"project_header": os.getenv("AI_PROJECT_HEADER", "project-uuid"),
"default_model": os.getenv("AI_DEFAULT_MODEL", "gpt-5-mini"),
"default_model": os.getenv("AI_DEFAULT_MODEL", "gpt-4o-mini"),
"timeout": int(os.getenv("AI_TIMEOUT", "30")),
"verify_tls": os.getenv("AI_VERIFY_TLS", "true").lower() not in {"0", "false", "no"},
}
return _CONFIG_CACHE
def _build_url(path: str, base_url: str) -> str:
trimmed = path.strip()
if trimmed.startswith("http://") or trimmed.startswith("https://"):
@ -329,7 +299,6 @@ def _build_url(path: str, base_url: str) -> str:
return f"{base_url}{trimmed}"
return f"{base_url}/{trimmed}"
def _resolve_status_path(ai_request_id: Any, cfg: Dict[str, Any]) -> str:
base_path = (cfg.get("responses_path") or "").rstrip("/")
if not base_path:
@ -338,7 +307,6 @@ def _resolve_status_path(ai_request_id: Any, cfg: Dict[str, Any]) -> str:
base_path = f"{base_path}/ai-request"
return f"{base_path}/{ai_request_id}/status"
def _http_request(url: str, method: str, body: Optional[bytes], headers: Dict[str, str],
timeout: int, verify_tls: bool) -> Dict[str, Any]:
"""
@ -413,7 +381,7 @@ def _ensure_env_loaded() -> None:
continue
key, value = stripped.split("=", 1)
key = key.strip()
value = value.strip().strip('\'"')
value = value.strip().strip('"')
if key and not os.getenv(key):
os.environ[key] = value
except OSError:

View File

@ -1,6 +1,8 @@
from django.db import models
from django.utils.text import slugify
import uuid
import random
import string
class StudioConfig(models.Model):
"""Singleton model to store studio-wide settings and the unique admin key."""
@ -43,7 +45,16 @@ class Project(models.Model):
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
base_slug = slugify(self.title)
if not base_slug:
base_slug = "project"
unique_slug = base_slug
while Project.objects.filter(slug=unique_slug).exists():
random_string = ''.join(random.choices(string.ascii_lowercase + string.digits, k=4))
unique_slug = f"{base_slug}-{random_string}"
self.slug = unique_slug
super().save(*args, **kwargs)
def __str__(self):
@ -109,4 +120,4 @@ class CgiAsset(models.Model):
assigned_artist = models.CharField(max_length=100, blank=True)
def __str__(self):
return f"{self.name} ({self.get_asset_type_display()})"
return f"{self.name} ({self.get_asset_type_display()})"

View File

@ -80,7 +80,7 @@ def generate_production(request):
{"role": "system", "content": "You are an expert Hollywood Producer and AI Cinema Director."},
{"role": "user", "content": prompt},
],
"response_format": {"type": "json_object"},
"text": {"format": {"type": "json_object"}},
})
if response.get("success"):
@ -178,4 +178,4 @@ def project_detail(request, slug):
"assets": project.assets.all(),
"scenes": project.scenes.all(),
}
return render(request, "core/project_detail.html", context)
return render(request, "core/project_detail.html", context)