Install and update artemis-use with task diagnostics and plugin guidance. Preserve cross-device file receipts, review canonical reports, guard stage transitions and reduce small history summaries. Improve exploration lifecycle, request recovery and browser live connections.
181 lines
5.6 KiB
Python
181 lines
5.6 KiB
Python
"""Shared exploration operations; no separate Web execution path."""
|
|
|
|
from contextlib import contextmanager
|
|
|
|
from fastapi import APIRouter, HTTPException, Query
|
|
|
|
from artemis.config.exploration import ExplorationConfig
|
|
from artemis.exploration.models import (
|
|
CreateExploration,
|
|
ExplorationMessage,
|
|
ExplorationRequest,
|
|
SaveCaseRequest,
|
|
ValidateCaseRequest,
|
|
DemonstrationRequest,
|
|
ExtendDemonstration,
|
|
GenerateCaseRequest,
|
|
CaseBatchRequest,
|
|
)
|
|
from artemis.exploration.store import ExplorationConflict
|
|
from apps.admin_console.services.exploration_service import exploration_service as service
|
|
|
|
|
|
router = APIRouter(prefix="/api/explorations", tags=["exploration"])
|
|
|
|
|
|
@router.get("/{exploration_id}/deletion-preview")
|
|
def preview_deletion(exploration_id: str):
|
|
from apps.admin_console.services.task_deletion import exploration_deletion_preview
|
|
|
|
with domain_errors():
|
|
return exploration_deletion_preview(exploration_id)
|
|
|
|
|
|
@router.delete("/{exploration_id}")
|
|
def delete_conversation(exploration_id: str):
|
|
from apps.admin_console.services.exploration_deletion import delete_exploration
|
|
|
|
with domain_errors():
|
|
deleted = delete_exploration(service.repository, exploration_id)
|
|
return {"status": "success", "deleted_session_ids": deleted}
|
|
|
|
|
|
@contextmanager
|
|
def domain_errors():
|
|
try:
|
|
yield
|
|
except KeyError as exc:
|
|
raise HTTPException(404, str(exc).strip("'")) from exc
|
|
except ExplorationConflict as exc:
|
|
raise HTTPException(409, str(exc)) from exc
|
|
except ValueError as exc:
|
|
# Pydantic may echo sensitive input. Invalid nested fields get a plain error.
|
|
from pydantic import ValidationError
|
|
|
|
raise HTTPException(
|
|
400, "探索参数不合法" if isinstance(exc, ValidationError) else str(exc)
|
|
) from exc
|
|
|
|
|
|
@router.get("/settings")
|
|
def settings():
|
|
return service.settings()
|
|
|
|
|
|
@router.put("/settings")
|
|
def save_settings(value: ExplorationConfig):
|
|
return service.save_settings(value)
|
|
|
|
|
|
@router.get("")
|
|
def list_explorations(limit: int = Query(100, ge=1, le=500)):
|
|
return service.repository.list(limit)
|
|
|
|
|
|
@router.post("")
|
|
def create(value: CreateExploration, source: str = Query("web", pattern="^(web|mcp)$")):
|
|
with domain_errors():
|
|
return service.create(value, source=source)
|
|
|
|
|
|
@router.get("/{session_id}")
|
|
def detail(session_id: str, after: int = Query(0, ge=0)):
|
|
with domain_errors():
|
|
return service.detail(session_id, after=after)
|
|
|
|
|
|
@router.post("/{session_id}/start")
|
|
async def start(
|
|
session_id: str, value: ExplorationRequest, source: str = Query("web", pattern="^(web|mcp)$")
|
|
):
|
|
with domain_errors():
|
|
return await service.start(session_id, value.request_id, source=source)
|
|
|
|
|
|
@router.post("/{session_id}/messages")
|
|
async def message(
|
|
session_id: str, value: ExplorationMessage, source: str = Query("web", pattern="^(web|mcp)$")
|
|
):
|
|
with domain_errors():
|
|
result = service.message(session_id, value.text, value.request_id, source=source)
|
|
if not result.get("run_id"):
|
|
from apps.admin_console.services.automation_service import spawn
|
|
from artemis.exploration.editorial import discuss
|
|
|
|
spawn(discuss(service.repository, session_id, result))
|
|
return result
|
|
|
|
|
|
@router.post("/{session_id}/pause")
|
|
def pause(session_id: str):
|
|
with domain_errors():
|
|
return service.pause(session_id)
|
|
|
|
|
|
@router.post("/{session_id}/stop")
|
|
async def stop(session_id: str):
|
|
with domain_errors():
|
|
return service.stop(session_id)
|
|
|
|
|
|
@router.post("/{session_id}/continue")
|
|
async def resume(
|
|
session_id: str, value: ExplorationRequest, source: str = Query("web", pattern="^(web|mcp)$")
|
|
):
|
|
with domain_errors():
|
|
return await service.resume(session_id, value.request_id, source=source)
|
|
|
|
|
|
@router.get("/{session_id}/case")
|
|
def case(session_id: str, version: int | None = Query(None, ge=1)):
|
|
with domain_errors():
|
|
return service.repository.case(session_id, version)
|
|
|
|
|
|
@router.post("/{session_id}/case")
|
|
def save_case(session_id: str, value: SaveCaseRequest):
|
|
with domain_errors():
|
|
return service.save_case(session_id, value)
|
|
|
|
|
|
@router.post("/{session_id}/validate")
|
|
async def validate(
|
|
session_id: str, value: ValidateCaseRequest, source: str = Query("web", pattern="^(web|mcp)$")
|
|
):
|
|
with domain_errors():
|
|
return await service.validate(session_id, value, source=source)
|
|
|
|
|
|
@router.post("/{session_id}/demonstrations")
|
|
def demonstrate(session_id: str, value: DemonstrationRequest):
|
|
with domain_errors():
|
|
return service.demonstrate(session_id, value.request_id, value.source)
|
|
|
|
|
|
@router.post("/{session_id}/demonstrations/{demo_id}/extend")
|
|
def extend_demonstration(session_id: str, demo_id: str, value: ExtendDemonstration):
|
|
with domain_errors():
|
|
return service.demonstration_command(
|
|
session_id, demo_id, "extend", value.request_id, seconds=value.seconds
|
|
)
|
|
|
|
|
|
@router.post("/{session_id}/demonstrations/{demo_id}/{command}")
|
|
def demonstration_command(session_id: str, demo_id: str, command: str, value: ExplorationRequest):
|
|
if command not in {"finish", "cancel"}:
|
|
raise HTTPException(404, "示范操作不存在")
|
|
with domain_errors():
|
|
return service.demonstration_command(session_id, demo_id, command, value.request_id)
|
|
|
|
|
|
@router.post("/{session_id}/generate")
|
|
async def generate_case(session_id: str, value: GenerateCaseRequest):
|
|
with domain_errors():
|
|
return await service.generate_case(session_id, value)
|
|
|
|
|
|
@router.post("/{session_id}/batch")
|
|
def case_batch(session_id: str, value: CaseBatchRequest):
|
|
with domain_errors():
|
|
return service.create_case_batch(session_id, value)
|