283 lines
10 KiB
Python
283 lines
10 KiB
Python
from __future__ import annotations
|
|
|
|
from fastapi import Depends, HTTPException, Query
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from ...core.response import success_response
|
|
from ...dependencies.permissions import require_manager_user
|
|
from ...dependencies.tenant import get_tenant_id
|
|
from ...models import User
|
|
from ...schemas.reply_iteration import (
|
|
FeedbackAssetPromoteRequest,
|
|
PromptReleaseCreateRequest,
|
|
PromptTrialCreateRequest,
|
|
PromptTrialDecisionRequest,
|
|
ReplyIterationCandidateCreateRequest,
|
|
ReplyIterationJudgeRunCreateRequest,
|
|
)
|
|
from ...services.prompt_release import PromptReleaseService
|
|
from ...services.reply_iteration import ReplyIterationService
|
|
from .shared import *
|
|
|
|
|
|
@router.post("/feedback-center/items/{record_id}/promote")
|
|
async def promote_feedback_center_item_to_asset(
|
|
record_id: int,
|
|
request: FeedbackAssetPromoteRequest,
|
|
current_user: User = Depends(require_manager_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
tenant_id: int = Depends(get_tenant_id),
|
|
):
|
|
effective_tenant_id = int(getattr(current_user, "tenant_id", tenant_id) or tenant_id)
|
|
try:
|
|
data = await ReplyIterationService(db).promote_feedback_record(
|
|
tenant_id=effective_tenant_id,
|
|
record_id=record_id,
|
|
actor_id=int(current_user.id),
|
|
asset_type=request.asset_type,
|
|
prompt_key=request.prompt_key,
|
|
workflow_type=request.workflow_type,
|
|
notes=request.notes,
|
|
pair_with_asset_id=request.pair_with_asset_id,
|
|
pair_role=request.pair_role,
|
|
pair_reason=request.pair_reason,
|
|
)
|
|
except ValueError as exc:
|
|
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
|
return success_response(data)
|
|
|
|
|
|
@router.post("/reply-iteration/backfill-mounted-assets")
|
|
async def backfill_reply_iteration_assets_from_real_feedback(
|
|
limit: int = Query(default=200, ge=1, le=2000),
|
|
current_user: User = Depends(require_manager_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
tenant_id: int = Depends(get_tenant_id),
|
|
):
|
|
effective_tenant_id = int(getattr(current_user, "tenant_id", tenant_id) or tenant_id)
|
|
try:
|
|
data = await ReplyIterationService(db).backfill_mounted_training_assets_from_feedback(
|
|
tenant_id=effective_tenant_id,
|
|
actor_id=int(current_user.id),
|
|
limit=limit,
|
|
)
|
|
except ValueError as exc:
|
|
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
|
return success_response(data)
|
|
|
|
|
|
@router.get("/reply-iteration/assets")
|
|
async def list_reply_iteration_assets(
|
|
asset_type: str | None = Query(default=None),
|
|
prompt_key: str | None = Query(default=None),
|
|
limit: int = Query(default=20, ge=1, le=100),
|
|
offset: int = Query(default=0, ge=0),
|
|
current_user: User = Depends(require_manager_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
tenant_id: int = Depends(get_tenant_id),
|
|
):
|
|
effective_tenant_id = int(getattr(current_user, "tenant_id", tenant_id) or tenant_id)
|
|
data = await ReplyIterationService(db).list_assets(
|
|
tenant_id=effective_tenant_id,
|
|
asset_type=asset_type,
|
|
prompt_key=prompt_key,
|
|
limit=limit,
|
|
offset=offset,
|
|
)
|
|
return success_response(data)
|
|
|
|
|
|
@router.post("/reply-iteration/judge-runs")
|
|
async def create_reply_iteration_judge_run(
|
|
request: ReplyIterationJudgeRunCreateRequest,
|
|
current_user: User = Depends(require_manager_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
tenant_id: int = Depends(get_tenant_id),
|
|
):
|
|
effective_tenant_id = int(getattr(current_user, "tenant_id", tenant_id) or tenant_id)
|
|
try:
|
|
data = await ReplyIterationService(db).create_judge_run(
|
|
tenant_id=effective_tenant_id,
|
|
asset_id=request.asset_id,
|
|
actor_id=int(current_user.id),
|
|
)
|
|
except ValueError as exc:
|
|
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
|
return success_response(data)
|
|
|
|
|
|
@router.get("/reply-iteration/judge-runs")
|
|
async def list_reply_iteration_judge_runs(
|
|
limit: int = Query(default=20, ge=1, le=100),
|
|
offset: int = Query(default=0, ge=0),
|
|
current_user: User = Depends(require_manager_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
tenant_id: int = Depends(get_tenant_id),
|
|
):
|
|
effective_tenant_id = int(getattr(current_user, "tenant_id", tenant_id) or tenant_id)
|
|
return success_response(
|
|
await ReplyIterationService(db).list_judge_runs(
|
|
tenant_id=effective_tenant_id,
|
|
limit=limit,
|
|
offset=offset,
|
|
)
|
|
)
|
|
|
|
|
|
@router.post("/reply-iteration/candidates")
|
|
async def create_reply_iteration_candidate(
|
|
request: ReplyIterationCandidateCreateRequest,
|
|
current_user: User = Depends(require_manager_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
tenant_id: int = Depends(get_tenant_id),
|
|
):
|
|
effective_tenant_id = int(getattr(current_user, "tenant_id", tenant_id) or tenant_id)
|
|
try:
|
|
data = await ReplyIterationService(db).create_optimizer_candidate(
|
|
tenant_id=effective_tenant_id,
|
|
judge_run_id=request.judge_run_id,
|
|
actor_id=int(current_user.id),
|
|
)
|
|
except ValueError as exc:
|
|
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
|
return success_response(data)
|
|
|
|
|
|
@router.get("/reply-iteration/candidates")
|
|
async def list_reply_iteration_candidates(
|
|
limit: int = Query(default=20, ge=1, le=100),
|
|
offset: int = Query(default=0, ge=0),
|
|
current_user: User = Depends(require_manager_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
tenant_id: int = Depends(get_tenant_id),
|
|
):
|
|
effective_tenant_id = int(getattr(current_user, "tenant_id", tenant_id) or tenant_id)
|
|
return success_response(
|
|
await ReplyIterationService(db).list_candidates(
|
|
tenant_id=effective_tenant_id,
|
|
limit=limit,
|
|
offset=offset,
|
|
)
|
|
)
|
|
|
|
|
|
@router.post("/reply-iteration/prompt-releases")
|
|
async def create_prompt_release(
|
|
request: PromptReleaseCreateRequest,
|
|
current_user: User = Depends(require_manager_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
tenant_id: int = Depends(get_tenant_id),
|
|
):
|
|
effective_tenant_id = int(getattr(current_user, "tenant_id", tenant_id) or tenant_id)
|
|
try:
|
|
data = await PromptReleaseService(db).create_release(
|
|
tenant_id=effective_tenant_id,
|
|
prompt_key=request.prompt_key,
|
|
body_snapshot=request.body_snapshot,
|
|
created_by=int(current_user.id),
|
|
notes=request.notes,
|
|
)
|
|
except ValueError as exc:
|
|
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
|
return success_response(data)
|
|
|
|
|
|
@router.get("/reply-iteration/prompt-releases")
|
|
async def list_prompt_releases(
|
|
prompt_key: str | None = Query(default=None),
|
|
current_user: User = Depends(require_manager_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
tenant_id: int = Depends(get_tenant_id),
|
|
):
|
|
effective_tenant_id = int(getattr(current_user, "tenant_id", tenant_id) or tenant_id)
|
|
return success_response(
|
|
await PromptReleaseService(db).list_releases(
|
|
tenant_id=effective_tenant_id,
|
|
prompt_key=prompt_key,
|
|
)
|
|
)
|
|
|
|
|
|
@router.post("/reply-iteration/prompt-releases/{release_id}/activate")
|
|
async def activate_prompt_release(
|
|
release_id: int,
|
|
current_user: User = Depends(require_manager_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
tenant_id: int = Depends(get_tenant_id),
|
|
):
|
|
effective_tenant_id = int(getattr(current_user, "tenant_id", tenant_id) or tenant_id)
|
|
try:
|
|
data = await PromptReleaseService(db).activate_release(
|
|
tenant_id=effective_tenant_id,
|
|
release_id=release_id,
|
|
actor_id=int(current_user.id),
|
|
)
|
|
except ValueError as exc:
|
|
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
|
return success_response(data)
|
|
|
|
|
|
@router.get("/reply-iteration/trials")
|
|
async def list_prompt_release_trials(
|
|
limit: int = Query(default=20, ge=1, le=100),
|
|
offset: int = Query(default=0, ge=0),
|
|
current_user: User = Depends(require_manager_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
tenant_id: int = Depends(get_tenant_id),
|
|
):
|
|
effective_tenant_id = int(getattr(current_user, "tenant_id", tenant_id) or tenant_id)
|
|
return success_response(
|
|
await ReplyIterationService(db).list_trials(
|
|
tenant_id=effective_tenant_id,
|
|
limit=limit,
|
|
offset=offset,
|
|
)
|
|
)
|
|
|
|
|
|
@router.post("/reply-iteration/trials")
|
|
async def create_prompt_release_trial(
|
|
request: PromptTrialCreateRequest,
|
|
current_user: User = Depends(require_manager_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
tenant_id: int = Depends(get_tenant_id),
|
|
):
|
|
effective_tenant_id = int(getattr(current_user, "tenant_id", tenant_id) or tenant_id)
|
|
try:
|
|
data = await ReplyIterationService(db).create_trial(
|
|
tenant_id=effective_tenant_id,
|
|
actor_id=int(current_user.id),
|
|
title=request.title,
|
|
hypothesis=request.hypothesis,
|
|
target_metric=request.target_metric,
|
|
prompt_key=request.prompt_key,
|
|
baseline_release_id=request.baseline_release_id,
|
|
candidate_release_id=request.candidate_release_id,
|
|
scope_json=request.scope_json,
|
|
)
|
|
except ValueError as exc:
|
|
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
|
return success_response(data)
|
|
|
|
|
|
@router.post("/reply-iteration/trials/{trial_id}/decision")
|
|
async def decide_prompt_release_trial(
|
|
trial_id: int,
|
|
request: PromptTrialDecisionRequest,
|
|
current_user: User = Depends(require_manager_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
tenant_id: int = Depends(get_tenant_id),
|
|
):
|
|
effective_tenant_id = int(getattr(current_user, "tenant_id", tenant_id) or tenant_id)
|
|
try:
|
|
data = await ReplyIterationService(db).decide_trial(
|
|
tenant_id=effective_tenant_id,
|
|
trial_id=trial_id,
|
|
actor_id=int(current_user.id),
|
|
decision=request.decision,
|
|
result_summary=request.result_summary,
|
|
)
|
|
except ValueError as exc:
|
|
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
|
return success_response(data)
|