Commit 0d12d87f authored by Administrator's avatar Administrator

Update 7 files via Son of Anton

parent 015b7902
......@@ -42,13 +42,14 @@ def _run_migrations():
conn.execute(text("ALTER TABLE chats ADD COLUMN reasoning_budget INTEGER DEFAULT 0"))
if "linked_repo_id" not in columns:
conn.execute(text("ALTER TABLE chats ADD COLUMN linked_repo_id VARCHAR(36)"))
if "linked_repo_branch" not in columns:
conn.execute(text("ALTER TABLE chats ADD COLUMN linked_repo_branch VARCHAR(100)"))
conn.commit()
if "chat_attachments" not in existing_tables:
from backend.models import ChatAttachment
ChatAttachment.__table__.create(bind=engine, checkfirst=True)
# Create user_permissions table if missing
if "user_permissions" not in existing_tables:
from backend.models import UserPermissions
UserPermissions.__table__.create(bind=engine, checkfirst=True)
......
......@@ -54,7 +54,6 @@ class UserPermissions(Base):
unique=True, nullable=False, index=True,
)
# Feature access
can_use_web_search = Column(Boolean, default=False)
can_use_ui_design = Column(Boolean, default=False)
can_use_knowledge_base = Column(Boolean, default=True)
......@@ -63,10 +62,8 @@ class UserPermissions(Base):
can_export_pptx = Column(Boolean, default=True)
can_export_docx = Column(Boolean, default=True)
# Model access — "all" or comma-separated model IDs
allowed_models = Column(Text, default="eu.anthropic.claude-haiku-4-5-20251001-v1:0")
# Limits (0 = unlimited for count-based limits)
max_tokens_cap = Column(Integer, default=4096)
max_reasoning_budget = Column(Integer, default=0)
max_chats = Column(Integer, default=50)
......@@ -90,6 +87,7 @@ class Chat(Base):
model = Column(String(100), default="eu.anthropic.claude-opus-4-6-v1")
knowledge_base_id = Column(String(36), nullable=True)
linked_repo_id = Column(String(36), nullable=True)
linked_repo_branch = Column(String(100), nullable=True)
max_tokens = Column(Integer, default=4096)
reasoning_budget = Column(Integer, default=0)
created_at = Column(DateTime, default=datetime.utcnow)
......
......@@ -28,6 +28,7 @@ class CreateChatBody(BaseModel):
model: str = "eu.anthropic.claude-opus-4-6-v1"
knowledge_base_id: Optional[str] = None
linked_repo_id: Optional[str] = None
linked_repo_branch: Optional[str] = None
max_tokens: int = 4096
reasoning_budget: int = 0
......@@ -39,6 +40,7 @@ class UpdateChatBody(BaseModel):
reasoning_budget: Optional[int] = None
knowledge_base_id: Optional[str] = None
linked_repo_id: Optional[str] = None
linked_repo_branch: Optional[str] = None
class SendMessageBody(BaseModel):
......@@ -85,6 +87,7 @@ def create_chat(body: CreateChatBody, user: User = Depends(get_current_user), db
model=check_model_allowed(user.id, body.model, db),
knowledge_base_id=body.knowledge_base_id or None,
linked_repo_id=body.linked_repo_id or None,
linked_repo_branch=body.linked_repo_branch or None,
max_tokens=min(body.max_tokens, perms.get("max_tokens_cap", 4096)),
reasoning_budget=min(body.reasoning_budget, perms.get("max_reasoning_budget", 0)),
)
......@@ -116,6 +119,8 @@ def update_chat(chat_id: str, body: UpdateChatBody, user: User = Depends(get_cur
if body.linked_repo_id and not perms.get("can_use_gitlab"):
raise HTTPException(403, "GitLab not enabled.")
chat.linked_repo_id = body.linked_repo_id or None
if body.linked_repo_branch is not None:
chat.linked_repo_branch = body.linked_repo_branch or None
db.commit()
return _chat_dict(chat, db)
......@@ -205,11 +210,6 @@ async def commit_from_chat(
user: User = Depends(get_current_user),
db: Session = Depends(get_db),
):
"""
Commit files from chat to linked GitLab repo.
Auto-detects whether each file should be 'create' or 'update'
by checking the repo tree, so it never fails on wrong action type.
"""
check_feature(user.id, "use_gitlab", db)
chat = db.query(Chat).filter(Chat.id == chat_id, Chat.user_id == user.id).first()
......@@ -226,73 +226,44 @@ async def commit_from_chat(
if not settings or not settings.is_active:
raise HTTPException(400, "GitLab not configured")
# ── Fetch repo tree to know which files already exist ──
existing_paths = set()
try:
tree = await gitlab_service.get_tree(
settings.gitlab_url,
settings.gitlab_token,
repo.gitlab_project_id,
ref=body.branch,
recursive=True,
settings.gitlab_url, settings.gitlab_token,
repo.gitlab_project_id, ref=body.branch, recursive=True,
)
existing_paths = {
item["path"] for item in tree if item["type"] == "blob"
}
existing_paths = {item["path"] for item in tree if item["type"] == "blob"}
except Exception:
# If tree fetch fails (empty repo, network issue, etc.),
# we'll try all as "create" since we can't know what exists
pass
# ── Build actions with auto-detected create/update ──
actions = []
for f in body.files:
file_path = f.get("file_path", "")
content = f.get("content", "")
requested_action = f.get("action", "auto")
if not file_path or not content:
continue
file_exists = file_path in existing_paths
# Smart action resolution
if requested_action in ("auto", "upsert"):
# Auto-detect: update if exists, create if not
actual_action = "update" if file_exists else "create"
elif requested_action == "update" and not file_exists:
# User said update but file doesn't exist → create instead
actual_action = "create"
elif requested_action == "create" and file_exists:
# User said create but file already exists → update instead
actual_action = "update"
else:
actual_action = requested_action
actions.append({
"action": actual_action,
"file_path": file_path,
"content": content,
})
actions.append({"action": actual_action, "file_path": file_path, "content": content})
if not actions:
raise HTTPException(400, "No valid files to commit")
try:
result = await gitlab_service.commit_files(
settings.gitlab_url,
settings.gitlab_token,
repo.gitlab_project_id,
body.branch,
body.commit_message,
actions,
settings.gitlab_url, settings.gitlab_token,
repo.gitlab_project_id, body.branch, body.commit_message, actions,
)
gen_manager.invalidate_repo_cache(repo.id)
return {
"ok": True,
"commit": result,
"files_committed": len(actions),
}
return {"ok": True, "commit": result, "files_committed": len(actions)}
except gitlab_service.GitLabError as e:
raise HTTPException(e.status_code, f"Commit failed: {e.detail}")
......@@ -314,6 +285,7 @@ def _chat_dict(c, db=None):
"id": c.id, "title": c.title, "model": c.model,
"knowledge_base_id": c.knowledge_base_id,
"linked_repo_id": c.linked_repo_id,
"linked_repo_branch": getattr(c, "linked_repo_branch", None) or None,
"max_tokens": c.max_tokens or 4096,
"reasoning_budget": c.reasoning_budget or 0,
"created_at": str(c.created_at),
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment