mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-15 19:10:47 +02:00
Add SaaS AI engine (#5907)
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
from . import tool_models
|
||||
from .api.requests import (
|
||||
CreateSessionRequest,
|
||||
DetectTypeRequest,
|
||||
FillFieldsRequest,
|
||||
GenerateAllSectionsRequest,
|
||||
GenerateSectionRequest,
|
||||
IntentCheckRequest,
|
||||
PdfAnswerRequest,
|
||||
RepromptRequest,
|
||||
UpdateDraftRequest,
|
||||
UpdateOutlineRequest,
|
||||
UpdateTemplateRequest,
|
||||
)
|
||||
from .api.responses import (
|
||||
CreateSessionResponse,
|
||||
DetectTypeResponse,
|
||||
DocTypeClassification,
|
||||
ErrorDetailResponse,
|
||||
FillFieldsResponse,
|
||||
GenerateAllSectionsResponse,
|
||||
GenerateErrorResponse,
|
||||
GenerateSectionResponse,
|
||||
GenerateSuccessResponse,
|
||||
HealthResponse,
|
||||
HtmlResponse,
|
||||
IntentCheckResponse,
|
||||
LLMDraftSectionsResponse,
|
||||
LLMFieldValuesResponse,
|
||||
MissingQuestionsResponse,
|
||||
NeedsInfoResponse,
|
||||
OutlineResponse,
|
||||
OutlineSection,
|
||||
PdfAnswer,
|
||||
PdfAnswerResponse,
|
||||
PdfEditorUploadResponse,
|
||||
SectionContent,
|
||||
SuccessResponse,
|
||||
UploadAssetResponse,
|
||||
VersionEntry,
|
||||
VersionsResponse,
|
||||
)
|
||||
from .base import ApiModel
|
||||
from .briefs import Action, BriefModel, DocumentType, IntentClassification
|
||||
from .chat import (
|
||||
ChatInfoRequest,
|
||||
ChatInfoResponse,
|
||||
ChatMessage,
|
||||
ChatRouteRequest,
|
||||
ChatRouteResponse,
|
||||
ChatTitleContext,
|
||||
ChatTitleExample,
|
||||
CreateIntentHint,
|
||||
EditIntentHint,
|
||||
InferredTool,
|
||||
InferToolsRequest,
|
||||
InferToolsResponse,
|
||||
InterpretParameterRequest,
|
||||
InterpretParameterResponse,
|
||||
SmartFolderIntentHint,
|
||||
)
|
||||
from .common import Constraint, DraftSection, ErrorCode, FieldValue, PdfPreflight, UploadedFileInfo
|
||||
from .editing.api import (
|
||||
EditMessageRequest,
|
||||
EditMessageResponse,
|
||||
EditResultFile,
|
||||
EditSessionResponse,
|
||||
EditToolCall,
|
||||
FrontendExecutionPlan,
|
||||
FrontendExecutionStep,
|
||||
)
|
||||
from .editing.confirmation import ConfirmationAction, ConfirmationAnswer, ConfirmationIntent
|
||||
from .editing.decisions import AskUserMessage, DefaultsDecision, IntentDecision
|
||||
from .editing.operations import IncompatibleChainError, OperationRef
|
||||
from .file_processing import (
|
||||
ClarificationDecision,
|
||||
EditToolSelection,
|
||||
FollowupIntent,
|
||||
JsonValue,
|
||||
PendingRequirement,
|
||||
ToolParameter,
|
||||
)
|
||||
from .java import AISession, JavaCreateSessionResponse, JavaUpdateSessionRequest
|
||||
from .llm import LLMGenerateAllSectionsResponse, LLMGeneratedSection
|
||||
from .pdf_editor import (
|
||||
Color,
|
||||
Document,
|
||||
DocumentElt,
|
||||
FontElt,
|
||||
ImageElt,
|
||||
InfoElt,
|
||||
Metadata,
|
||||
PageElt,
|
||||
TextElt,
|
||||
)
|
||||
from .pdf_generator import (
|
||||
CreateStreamPhase,
|
||||
CreateStreamRequest,
|
||||
PreviewTemplateHtmlRequest,
|
||||
RenderPreviewRequest,
|
||||
ThemePayload,
|
||||
)
|
||||
from .smart_folders import (
|
||||
AvailableTool,
|
||||
SmartFolderAutomation,
|
||||
SmartFolderConfig,
|
||||
SmartFolderCreateRequest,
|
||||
SmartFolderCreateResponse,
|
||||
SmartFolderOperation,
|
||||
)
|
||||
from .tool_models import OperationId
|
||||
|
||||
__all__ = [
|
||||
"AISession",
|
||||
"Action",
|
||||
"ApiModel",
|
||||
"AskUserMessage",
|
||||
"AvailableTool",
|
||||
"BriefModel",
|
||||
"ChatInfoRequest",
|
||||
"ChatInfoResponse",
|
||||
"ChatMessage",
|
||||
"ChatRouteRequest",
|
||||
"ChatRouteResponse",
|
||||
"ChatTitleContext",
|
||||
"ChatTitleExample",
|
||||
"ClarificationDecision",
|
||||
"Color",
|
||||
"ConfirmationAction",
|
||||
"ConfirmationAnswer",
|
||||
"ConfirmationIntent",
|
||||
"Constraint",
|
||||
"CreateIntentHint",
|
||||
"CreateSessionRequest",
|
||||
"CreateSessionResponse",
|
||||
"CreateStreamPhase",
|
||||
"CreateStreamRequest",
|
||||
"PreviewTemplateHtmlRequest",
|
||||
"RenderPreviewRequest",
|
||||
"ThemePayload",
|
||||
"DefaultsDecision",
|
||||
"DetectTypeRequest",
|
||||
"DetectTypeResponse",
|
||||
"DocTypeClassification",
|
||||
"Document",
|
||||
"DocumentElt",
|
||||
"DocumentType",
|
||||
"DraftSection",
|
||||
"EditIntentHint",
|
||||
"EditMessageRequest",
|
||||
"EditMessageResponse",
|
||||
"EditResultFile",
|
||||
"EditSessionResponse",
|
||||
"EditToolCall",
|
||||
"EditToolSelection",
|
||||
"ErrorCode",
|
||||
"ErrorDetailResponse",
|
||||
"FieldValue",
|
||||
"FrontendExecutionPlan",
|
||||
"FrontendExecutionStep",
|
||||
"FillFieldsRequest",
|
||||
"FillFieldsResponse",
|
||||
"FollowupIntent",
|
||||
"FontElt",
|
||||
"GenerateAllSectionsRequest",
|
||||
"GenerateAllSectionsResponse",
|
||||
"GenerateErrorResponse",
|
||||
"GenerateSectionRequest",
|
||||
"GenerateSectionResponse",
|
||||
"GenerateSuccessResponse",
|
||||
"HealthResponse",
|
||||
"HtmlResponse",
|
||||
"ImageElt",
|
||||
"IncompatibleChainError",
|
||||
"InfoElt",
|
||||
"IntentCheckRequest",
|
||||
"IntentCheckResponse",
|
||||
"IntentClassification",
|
||||
"IntentDecision",
|
||||
"InferredTool",
|
||||
"InferToolsRequest",
|
||||
"InferToolsResponse",
|
||||
"InterpretParameterRequest",
|
||||
"InterpretParameterResponse",
|
||||
"JavaCreateSessionResponse",
|
||||
"JavaUpdateSessionRequest",
|
||||
"JsonValue",
|
||||
"LLMFieldValuesResponse",
|
||||
"LLMGenerateAllSectionsResponse",
|
||||
"LLMGeneratedSection",
|
||||
"LLMDraftSectionsResponse",
|
||||
"Metadata",
|
||||
"MissingQuestionsResponse",
|
||||
"NeedsInfoResponse",
|
||||
"OperationId",
|
||||
"OperationRef",
|
||||
"OutlineResponse",
|
||||
"OutlineSection",
|
||||
"PdfPreflight",
|
||||
"PageElt",
|
||||
"PdfAnswer",
|
||||
"PdfAnswerRequest",
|
||||
"PdfAnswerResponse",
|
||||
"PdfEditorUploadResponse",
|
||||
"PendingRequirement",
|
||||
"RepromptRequest",
|
||||
"SectionContent",
|
||||
"SmartFolderAutomation",
|
||||
"SmartFolderConfig",
|
||||
"SmartFolderCreateRequest",
|
||||
"SmartFolderCreateResponse",
|
||||
"SmartFolderIntentHint",
|
||||
"SmartFolderOperation",
|
||||
"SuccessResponse",
|
||||
"TextElt",
|
||||
"ToolParameter",
|
||||
"UpdateDraftRequest",
|
||||
"UpdateOutlineRequest",
|
||||
"UpdateTemplateRequest",
|
||||
"UploadedFileInfo",
|
||||
"UploadAssetResponse",
|
||||
"VersionEntry",
|
||||
"VersionsResponse",
|
||||
"tool_models",
|
||||
]
|
||||
@@ -0,0 +1,77 @@
|
||||
from .requests import (
|
||||
CreateSessionRequest,
|
||||
DetectTypeRequest,
|
||||
FillFieldsRequest,
|
||||
GenerateAllSectionsRequest,
|
||||
GenerateSectionRequest,
|
||||
IntentCheckRequest,
|
||||
PdfAnswerRequest,
|
||||
RepromptRequest,
|
||||
UpdateDraftRequest,
|
||||
UpdateOutlineRequest,
|
||||
UpdateTemplateRequest,
|
||||
)
|
||||
from .responses import (
|
||||
CreateSessionResponse,
|
||||
DetectTypeResponse,
|
||||
DocTypeClassification,
|
||||
ErrorDetailResponse,
|
||||
FillFieldsResponse,
|
||||
GenerateAllSectionsResponse,
|
||||
GenerateErrorResponse,
|
||||
GenerateSectionResponse,
|
||||
GenerateSuccessResponse,
|
||||
HealthResponse,
|
||||
IntentCheckResponse,
|
||||
LLMDraftSectionsResponse,
|
||||
LLMFieldValuesResponse,
|
||||
MissingQuestionsResponse,
|
||||
NeedsInfoResponse,
|
||||
OutlineResponse,
|
||||
PdfAnswer,
|
||||
PdfAnswerResponse,
|
||||
PdfEditorUploadResponse,
|
||||
SectionContent,
|
||||
SuccessResponse,
|
||||
UploadAssetResponse,
|
||||
VersionEntry,
|
||||
VersionsResponse,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"CreateSessionRequest",
|
||||
"DetectTypeRequest",
|
||||
"FillFieldsRequest",
|
||||
"GenerateAllSectionsRequest",
|
||||
"GenerateSectionRequest",
|
||||
"IntentCheckRequest",
|
||||
"PdfAnswerRequest",
|
||||
"RepromptRequest",
|
||||
"UpdateDraftRequest",
|
||||
"UpdateOutlineRequest",
|
||||
"UpdateTemplateRequest",
|
||||
"CreateSessionResponse",
|
||||
"DetectTypeResponse",
|
||||
"DocTypeClassification",
|
||||
"ErrorDetailResponse",
|
||||
"FillFieldsResponse",
|
||||
"GenerateAllSectionsResponse",
|
||||
"GenerateErrorResponse",
|
||||
"GenerateSectionResponse",
|
||||
"GenerateSuccessResponse",
|
||||
"HealthResponse",
|
||||
"IntentCheckResponse",
|
||||
"LLMFieldValuesResponse",
|
||||
"LLMDraftSectionsResponse",
|
||||
"MissingQuestionsResponse",
|
||||
"NeedsInfoResponse",
|
||||
"OutlineResponse",
|
||||
"PdfAnswer",
|
||||
"PdfAnswerResponse",
|
||||
"PdfEditorUploadResponse",
|
||||
"SectionContent",
|
||||
"SuccessResponse",
|
||||
"UploadAssetResponse",
|
||||
"VersionEntry",
|
||||
"VersionsResponse",
|
||||
]
|
||||
@@ -0,0 +1,72 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from ..base import ApiModel
|
||||
from ..chat import ChatMessage
|
||||
from ..common import Constraint, DraftSection
|
||||
|
||||
|
||||
class IntentCheckRequest(ApiModel):
|
||||
prompt: str = ""
|
||||
conversation_history: list[ChatMessage] = Field(default_factory=list)
|
||||
current_pdf_url: str | None = None
|
||||
|
||||
|
||||
class DetectTypeRequest(ApiModel):
|
||||
prompt: str = ""
|
||||
explicit_type: str | None = None
|
||||
|
||||
|
||||
class PdfAnswerRequest(ApiModel):
|
||||
pdf_url: str | None = None
|
||||
question: str | None = None
|
||||
|
||||
|
||||
class CreateSessionRequest(ApiModel):
|
||||
prompt: str = ""
|
||||
doc_type: str = ""
|
||||
template_id: str = ""
|
||||
|
||||
|
||||
class UpdateOutlineRequest(ApiModel):
|
||||
outline_text: str = ""
|
||||
constraints: Constraint | None = None
|
||||
outline_filename: str | None = None
|
||||
|
||||
|
||||
class UpdateDraftRequest(ApiModel):
|
||||
draft_sections: list[DraftSection] = Field(default_factory=list)
|
||||
|
||||
|
||||
class UpdateTemplateRequest(ApiModel):
|
||||
doc_type: str | None = None
|
||||
template_id: str | None = None
|
||||
|
||||
|
||||
class RepromptRequest(ApiModel):
|
||||
prompt: str = ""
|
||||
|
||||
|
||||
class FillFieldsRequest(ApiModel):
|
||||
fields: list[dict[str, str]] = Field(default_factory=list)
|
||||
extra_prompt: str = ""
|
||||
|
||||
|
||||
class GenerateSectionRequest(ApiModel):
|
||||
session_id: str | None = None
|
||||
section_label: str = ""
|
||||
section_index: int = 0
|
||||
custom_prompt: str = ""
|
||||
document_prompt: str = ""
|
||||
doc_type: str = "document"
|
||||
existing_sections: list[DraftSection] = Field(default_factory=list)
|
||||
|
||||
|
||||
class GenerateAllSectionsRequest(ApiModel):
|
||||
session_id: str | None = None
|
||||
document_prompt: str = ""
|
||||
doc_type: str = "document"
|
||||
sections: list[DraftSection] = Field(default_factory=list)
|
||||
only_indices: list[int] | None = None
|
||||
additional_prompt: str = ""
|
||||
@@ -0,0 +1,155 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from ..base import ApiModel
|
||||
from ..common import DraftSection, FieldValue
|
||||
|
||||
|
||||
class OutlineSection(ApiModel):
|
||||
"""A single section in the document outline with pre-filled content."""
|
||||
|
||||
label: str = Field(description="Section title/header")
|
||||
value: str = Field(description="Pre-filled content extracted from user's prompt")
|
||||
|
||||
|
||||
class OutlineResponse(ApiModel):
|
||||
"""Structured outline with detected document type and sections."""
|
||||
|
||||
doc_type: str = Field(description="Detected document type")
|
||||
sections: list[OutlineSection]
|
||||
outline_filename: str | None = None
|
||||
|
||||
|
||||
class DocTypeClassification(ApiModel):
|
||||
doc_type: str
|
||||
|
||||
|
||||
class SectionContent(ApiModel):
|
||||
content: str
|
||||
|
||||
|
||||
class HtmlResponse(ApiModel):
|
||||
html: str
|
||||
|
||||
|
||||
class PdfAnswer(ApiModel):
|
||||
answer: str
|
||||
evidence: list[str] = Field(default_factory=list)
|
||||
|
||||
|
||||
class MissingQuestionsResponse(ApiModel):
|
||||
message: str
|
||||
|
||||
|
||||
class LLMFieldValuesResponse(ApiModel):
|
||||
fields: list[FieldValue]
|
||||
|
||||
|
||||
class LLMDraftSectionsResponse(ApiModel):
|
||||
sections: list[DraftSection]
|
||||
|
||||
|
||||
class IntentCheckResponse(ApiModel):
|
||||
wants_pdf: bool | None = None
|
||||
has_enough_info: bool | None = None
|
||||
document_type: str | None = None
|
||||
missing_fields: list[str] | None = None
|
||||
doc_type: str | None = None
|
||||
has_pdf: bool | None = None
|
||||
reason: str | None = None
|
||||
|
||||
|
||||
class DetectTypeResponse(ApiModel):
|
||||
doc_type: str | None = None
|
||||
confidence: str | None = None
|
||||
method: str | None = None
|
||||
error: str | None = None
|
||||
|
||||
|
||||
class PdfAnswerResponse(ApiModel):
|
||||
answer: str | None = None
|
||||
mode: str | None = None
|
||||
error: str | None = None
|
||||
|
||||
|
||||
class NeedsInfoResponse(ApiModel):
|
||||
needs_info: bool | None = None
|
||||
message: str | None = None
|
||||
missing: list[str] | None = None
|
||||
collected: dict[str, str] | None = None
|
||||
doc_type: str | None = None
|
||||
|
||||
|
||||
class VersionEntry(ApiModel):
|
||||
id: str
|
||||
prompt: str
|
||||
doc_type: str
|
||||
pdf_url: str
|
||||
created_at: str
|
||||
template_used: bool
|
||||
edit_mode: bool
|
||||
|
||||
|
||||
class GenerateSuccessResponse(ApiModel):
|
||||
pdf_url: str
|
||||
doc_type: str
|
||||
message: str
|
||||
version: VersionEntry
|
||||
template_used: bool
|
||||
editing_existing: bool
|
||||
|
||||
|
||||
class GenerateErrorResponse(ApiModel):
|
||||
error: str
|
||||
editing_existing: bool
|
||||
|
||||
|
||||
class ErrorDetailResponse(ApiModel):
|
||||
error: str
|
||||
detail: str
|
||||
|
||||
|
||||
class CreateSessionResponse(ApiModel):
|
||||
session_id: str
|
||||
doc_type: str
|
||||
detection_method: str
|
||||
template_html: str | None = None # Selected .html template, or None
|
||||
|
||||
|
||||
class SuccessResponse(ApiModel):
|
||||
success: bool
|
||||
|
||||
|
||||
class FillFieldsResponse(ApiModel):
|
||||
fields: list[dict[str, str]]
|
||||
|
||||
|
||||
class GenerateSectionResponse(ApiModel):
|
||||
content: str | None = None
|
||||
section_index: int | None = None
|
||||
error: str | None = None
|
||||
|
||||
|
||||
class GenerateAllSectionsResponse(ApiModel):
|
||||
sections: list[DraftSection] | None = None
|
||||
incomplete_section_indices: list[int] | None = None
|
||||
error: str | None = None
|
||||
|
||||
|
||||
class VersionsResponse(ApiModel):
|
||||
versions: list[VersionEntry]
|
||||
|
||||
|
||||
class UploadAssetResponse(ApiModel):
|
||||
asset_id: str
|
||||
asset_url: str
|
||||
|
||||
|
||||
class PdfEditorUploadResponse(ApiModel):
|
||||
pdf_url: str
|
||||
|
||||
|
||||
class HealthResponse(ApiModel):
|
||||
status: str
|
||||
engine: str
|
||||
@@ -0,0 +1,13 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
from pydantic.alias_generators import to_camel
|
||||
|
||||
|
||||
class ApiModel(BaseModel):
|
||||
model_config = ConfigDict(
|
||||
alias_generator=to_camel,
|
||||
extra="forbid",
|
||||
validate_by_name=True,
|
||||
validate_by_alias=True,
|
||||
)
|
||||
@@ -0,0 +1,54 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from enum import StrEnum
|
||||
|
||||
from .base import ApiModel
|
||||
|
||||
|
||||
class DocumentType(StrEnum):
|
||||
academic = "academic"
|
||||
agenda = "agenda"
|
||||
brochure = "brochure"
|
||||
business_card = "business_card"
|
||||
case_study = "case_study"
|
||||
checklist = "checklist"
|
||||
contract = "contract"
|
||||
creative = "creative"
|
||||
datasheet = "datasheet"
|
||||
document = "document"
|
||||
flyer = "flyer"
|
||||
invoice = "invoice"
|
||||
letter = "letter"
|
||||
manual = "manual"
|
||||
menu = "menu"
|
||||
minutes = "minutes"
|
||||
newsletter = "newsletter"
|
||||
one_pager = "one_pager"
|
||||
poster = "poster"
|
||||
presentation = "presentation"
|
||||
press_release = "press_release"
|
||||
proposal = "proposal"
|
||||
recipe = "recipe"
|
||||
report = "report"
|
||||
resume = "resume"
|
||||
timeline = "timeline"
|
||||
whitepaper = "whitepaper"
|
||||
|
||||
|
||||
class Action(StrEnum):
|
||||
new = "new"
|
||||
edit = "edit"
|
||||
question = "question"
|
||||
|
||||
|
||||
class BriefModel(ApiModel):
|
||||
pass
|
||||
|
||||
|
||||
class IntentClassification(BriefModel):
|
||||
doc_type: DocumentType
|
||||
action: Action
|
||||
wants_pdf: bool
|
||||
has_enough_info: bool
|
||||
missing_fields: list[str]
|
||||
notes: str
|
||||
@@ -0,0 +1,107 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Literal
|
||||
|
||||
from pydantic import Field, model_validator
|
||||
|
||||
from .base import ApiModel
|
||||
|
||||
|
||||
class ChatInfoRequest(ApiModel):
|
||||
message: str = ""
|
||||
history: list[ChatMessage] = Field(default_factory=list)
|
||||
|
||||
|
||||
class ChatInfoResponse(ApiModel):
|
||||
assistant_message: str = ""
|
||||
|
||||
|
||||
class InterpretParameterRequest(ApiModel):
|
||||
tool_id: str
|
||||
tool_name: str
|
||||
question: str
|
||||
user_response: str
|
||||
|
||||
|
||||
class InterpretParameterResponse(ApiModel):
|
||||
type: Literal["value", "confused", "cancel", "default"]
|
||||
extracted_value: str | None = None
|
||||
help_message: str
|
||||
|
||||
|
||||
class ChatMessage(ApiModel):
|
||||
role: Literal["system", "assistant", "user"]
|
||||
content: str | list[str | dict]
|
||||
|
||||
|
||||
class ChatTitleExample(ApiModel):
|
||||
user: str
|
||||
title: str
|
||||
|
||||
|
||||
class ChatTitleContext(ApiModel):
|
||||
current_title: str | None = None
|
||||
max_length: int | None = None
|
||||
style_hint: str | None = None
|
||||
examples: list[ChatTitleExample] = Field(default_factory=list)
|
||||
|
||||
|
||||
class EditIntentHint(ApiModel):
|
||||
mode: Literal["command", "info", "document_question", "html_edit", "ambiguous"]
|
||||
requires_file_context: bool = False
|
||||
|
||||
|
||||
class CreateIntentHint(ApiModel):
|
||||
action: Literal["start", "generate_pdf", "regenerate_outline"] = "start"
|
||||
doc_type: str | None = None # Detected document type when action="start"
|
||||
template_tex: str | None = None # Selected .tex from default_templates, or None if unknown
|
||||
|
||||
|
||||
class SmartFolderIntentHint(ApiModel):
|
||||
action: Literal["configure", "create"]
|
||||
|
||||
|
||||
class ChatRouteRequest(ApiModel):
|
||||
message: str = ""
|
||||
history: list[ChatMessage] = Field(default_factory=list)
|
||||
has_files: bool = False
|
||||
has_editable_html: bool = False
|
||||
has_create_session: bool = False
|
||||
has_edit_session: bool = False
|
||||
last_route: Literal["edit", "create", "none"] = "none"
|
||||
request_title: bool = False
|
||||
title_context: ChatTitleContext | None = None
|
||||
|
||||
|
||||
class InferToolsRequest(ApiModel):
|
||||
message: str
|
||||
available_tools: list[str]
|
||||
|
||||
|
||||
class InferredTool(ApiModel):
|
||||
tool_id: str
|
||||
confidence: Literal["high", "medium", "low"]
|
||||
|
||||
|
||||
class InferToolsResponse(ApiModel):
|
||||
tools: list[InferredTool]
|
||||
reason: str
|
||||
|
||||
|
||||
class ChatRouteResponse(ApiModel):
|
||||
intent: Literal["create", "edit", "smart_folder"]
|
||||
create_intent: CreateIntentHint | None = None
|
||||
edit_intent: EditIntentHint | None = None
|
||||
smart_folder_intent: SmartFolderIntentHint | None = None
|
||||
reason: str = ""
|
||||
suggested_title: str | None = None
|
||||
|
||||
@model_validator(mode="after")
|
||||
def _require_matching_intent(self) -> ChatRouteResponse:
|
||||
if self.intent == "create" and self.create_intent is None:
|
||||
raise ValueError("create_intent is required when intent='create'")
|
||||
elif self.intent == "edit" and self.edit_intent is None:
|
||||
raise ValueError("edit_intent is required when intent='edit'")
|
||||
elif self.intent == "smart_folder" and self.smart_folder_intent is None:
|
||||
raise ValueError("smart_folder_intent is required when intent='smart_folder'")
|
||||
return self
|
||||
@@ -0,0 +1,39 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from enum import StrEnum
|
||||
|
||||
from .base import ApiModel
|
||||
|
||||
|
||||
class ErrorCode(StrEnum):
|
||||
"""Error codes for special handling."""
|
||||
|
||||
INSUFFICIENT_CREDITS = "INSUFFICIENT_CREDITS"
|
||||
|
||||
|
||||
class Constraint(ApiModel):
|
||||
tone: str | None = None
|
||||
audience: str | None = None
|
||||
page_count: int | None = None
|
||||
|
||||
|
||||
class UploadedFileInfo(ApiModel):
|
||||
name: str | None = None
|
||||
type: str | None = None
|
||||
|
||||
|
||||
class PdfPreflight(ApiModel):
|
||||
file_size_mb: float | None = None
|
||||
is_encrypted: bool | None = None
|
||||
page_count: int | None = None
|
||||
has_text_layer: bool | None = None
|
||||
|
||||
|
||||
class DraftSection(ApiModel):
|
||||
label: str
|
||||
value: str
|
||||
|
||||
|
||||
class FieldValue(ApiModel):
|
||||
label: str
|
||||
value: str
|
||||
@@ -0,0 +1,30 @@
|
||||
from .api import (
|
||||
EditMessageRequest,
|
||||
EditMessageResponse,
|
||||
EditResultFile,
|
||||
EditSessionResponse,
|
||||
EditToolCall,
|
||||
FrontendExecutionPlan,
|
||||
FrontendExecutionStep,
|
||||
)
|
||||
from .confirmation import ConfirmationAction, ConfirmationAnswer, ConfirmationIntent
|
||||
from .decisions import AskUserMessage, DefaultsDecision, IntentDecision
|
||||
from .operations import IncompatibleChainError, OperationRef
|
||||
|
||||
__all__ = [
|
||||
"AskUserMessage",
|
||||
"ConfirmationAction",
|
||||
"ConfirmationAnswer",
|
||||
"ConfirmationIntent",
|
||||
"DefaultsDecision",
|
||||
"EditMessageRequest",
|
||||
"EditMessageResponse",
|
||||
"EditResultFile",
|
||||
"EditSessionResponse",
|
||||
"EditToolCall",
|
||||
"FrontendExecutionPlan",
|
||||
"FrontendExecutionStep",
|
||||
"IncompatibleChainError",
|
||||
"IntentDecision",
|
||||
"OperationRef",
|
||||
]
|
||||
@@ -0,0 +1,61 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Literal
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from ..base import ApiModel
|
||||
from ..chat import EditIntentHint
|
||||
from ..common import ErrorCode
|
||||
from ..tool_models import OperationId, ParamToolModel
|
||||
|
||||
|
||||
class EditSessionResponse(ApiModel):
|
||||
session_id: str
|
||||
file_name: str
|
||||
file_type: str | None = None
|
||||
|
||||
|
||||
class EditMessageRequest(ApiModel):
|
||||
message: str = ""
|
||||
action: str | None = None
|
||||
edit_intent: EditIntentHint | None = None
|
||||
|
||||
|
||||
class EditToolCall(ApiModel):
|
||||
operation_id: OperationId
|
||||
parameters: ParamToolModel
|
||||
|
||||
|
||||
class EditResultFile(ApiModel):
|
||||
url: str
|
||||
name: str | None = None
|
||||
|
||||
|
||||
class FrontendExecutionStep(ApiModel):
|
||||
operation_id: OperationId
|
||||
parameters: ParamToolModel
|
||||
|
||||
|
||||
class FrontendExecutionPlan(ApiModel):
|
||||
mode: Literal["single", "pipeline"]
|
||||
steps: list[FrontendExecutionStep] = Field(default_factory=list)
|
||||
pipeline_name: str | None = None
|
||||
|
||||
|
||||
class EditMessageResponse(ApiModel):
|
||||
assistant_message: str
|
||||
tool_calls: list[EditToolCall] = Field(default_factory=list)
|
||||
execute_on_frontend: bool = False
|
||||
frontend_plan: FrontendExecutionPlan | None = None
|
||||
result_file_url: str | None = None
|
||||
result_file_name: str | None = None
|
||||
result_files: list[EditResultFile] | None = None
|
||||
result_json: dict[str, Any] | None = None
|
||||
result_text: str | None = None
|
||||
result_bool: bool | None = None
|
||||
needs_more_info: bool = False
|
||||
missing_parameters: list[str] = Field(default_factory=list)
|
||||
confirmation_required: bool = False
|
||||
warning: str | None = None
|
||||
error: ErrorCode | None = None
|
||||
@@ -0,0 +1,23 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Literal
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from ..base import ApiModel
|
||||
|
||||
ConfirmationAction = Literal["confirm", "cancel", "modify", "new_request", "question"]
|
||||
|
||||
|
||||
class ConfirmationAnswer(ApiModel):
|
||||
message: str
|
||||
|
||||
|
||||
class ConfirmationIntent(ApiModel):
|
||||
"""
|
||||
Intent classification during confirmation phase (AWAITING_CONFIRM state).
|
||||
CRITICAL: Never ignore user messages during confirmation.
|
||||
"""
|
||||
|
||||
action: ConfirmationAction = Field(..., description="confirm, cancel, modify, new_request, or question")
|
||||
modification_description: str | None = Field(None, description="If action=modify, what change the user wants")
|
||||
@@ -0,0 +1,18 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Literal
|
||||
|
||||
from ..base import ApiModel
|
||||
|
||||
|
||||
class DefaultsDecision(ApiModel):
|
||||
use_defaults: bool
|
||||
|
||||
|
||||
class AskUserMessage(ApiModel):
|
||||
message: str
|
||||
|
||||
|
||||
class IntentDecision(ApiModel):
|
||||
mode: Literal["command", "info", "document_question", "ambiguous"]
|
||||
requires_file_context: bool = False
|
||||
@@ -0,0 +1,18 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from ..base import ApiModel
|
||||
from ..tool_models import OperationId
|
||||
|
||||
|
||||
class OperationRef(ApiModel):
|
||||
"""Reference to an operation with enough info for frontend tool lookup."""
|
||||
|
||||
operation_id: OperationId
|
||||
|
||||
|
||||
class IncompatibleChainError(ApiModel):
|
||||
"""Validation error data for incompatible operation chains."""
|
||||
|
||||
type: str # Always "incompatible_chain"
|
||||
current_operation: OperationRef
|
||||
next_operation: OperationRef
|
||||
@@ -0,0 +1,40 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Literal
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from .base import ApiModel
|
||||
from .tool_models import OperationId, ParamToolModel
|
||||
|
||||
type JsonValue = dict[str, Any] | list[Any] | str | int | float | bool | None
|
||||
|
||||
|
||||
class ToolParameter(ApiModel):
|
||||
name: str
|
||||
value: JsonValue
|
||||
|
||||
|
||||
class EditToolSelection(ApiModel):
|
||||
action: Literal["call_tool", "ask_user", "no_tool"]
|
||||
operation_ids: list[OperationId] = Field(
|
||||
default_factory=list,
|
||||
description="Operation IDs to run in order. Use multiple items for compound requests.",
|
||||
)
|
||||
response_message: str | None = None
|
||||
|
||||
|
||||
class ClarificationDecision(ApiModel):
|
||||
action: str = Field(..., description="proceed or ask_user")
|
||||
question: str | None = None
|
||||
missing_parameters: list[str] = Field(default_factory=list)
|
||||
|
||||
|
||||
class FollowupIntent(ApiModel):
|
||||
mode: str = Field(..., description="fill_missing, new_request, or info")
|
||||
|
||||
|
||||
class PendingRequirement(ApiModel):
|
||||
operation_id: OperationId
|
||||
parameters: ParamToolModel | None = None
|
||||
missing: list[str] = Field(default_factory=list)
|
||||
@@ -0,0 +1,40 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from .base import ApiModel
|
||||
from .common import Constraint, DraftSection
|
||||
|
||||
|
||||
class JavaCreateSessionResponse(ApiModel):
|
||||
session_id: str
|
||||
|
||||
|
||||
class JavaUpdateSessionRequest(ApiModel):
|
||||
outline_text: str | None = None
|
||||
outline_filename: str | None = None
|
||||
outline_approved: bool | None = None
|
||||
outline_constraints: Constraint | None = None
|
||||
draft_sections: list[DraftSection] | None = None
|
||||
polished_html: str | None = None
|
||||
pdf_url: str | None = None
|
||||
doc_type: str | None = None
|
||||
template_id: str | None = None
|
||||
status: str | None = None
|
||||
|
||||
|
||||
class AISession(ApiModel):
|
||||
session_id: str | None = None
|
||||
user_id: str | None = None
|
||||
prompt_latest: str | None = None
|
||||
prompt_initial: str | None = None
|
||||
doc_type: str | None = None
|
||||
template_id: str | None = None
|
||||
outline_text: str | None = None
|
||||
outline_filename: str | None = None
|
||||
outline_approved: bool | None = None
|
||||
outline_constraints: Constraint | None = None
|
||||
draft_sections: list[DraftSection] | None = None
|
||||
polished_html: str | None = None
|
||||
pdf_url: str | None = None
|
||||
created_at: str | None = None
|
||||
updated_at: str | None = None
|
||||
status: str | None = None
|
||||
@@ -0,0 +1,12 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from .base import ApiModel
|
||||
|
||||
|
||||
class LLMGeneratedSection(ApiModel):
|
||||
index: int
|
||||
value: str
|
||||
|
||||
|
||||
class LLMGenerateAllSectionsResponse(ApiModel):
|
||||
sections: list[LLMGeneratedSection]
|
||||
@@ -0,0 +1,89 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from .base import ApiModel
|
||||
|
||||
|
||||
class Color(ApiModel):
|
||||
color_space: str
|
||||
components: list[float]
|
||||
|
||||
|
||||
class TextElt(ApiModel):
|
||||
id: str
|
||||
text: str
|
||||
font_id: str | None = None
|
||||
font_size: float | None = None
|
||||
x: float
|
||||
y: float
|
||||
width: float
|
||||
height: float
|
||||
text_matrix: list[float]
|
||||
fill_color: Color | None = None
|
||||
|
||||
|
||||
class ImageElt(ApiModel):
|
||||
id: str
|
||||
object_name: str | None = None
|
||||
x: float
|
||||
y: float
|
||||
width: float
|
||||
height: float
|
||||
left: float
|
||||
top: float
|
||||
bottom: float
|
||||
right: float
|
||||
image_data: str | None = None
|
||||
image_format: str | None = None
|
||||
|
||||
|
||||
class InfoElt(ApiModel):
|
||||
anchors: list[float]
|
||||
boundaries: list[float]
|
||||
observed_left: float
|
||||
observed_right: float
|
||||
y_min: float
|
||||
y_max: float
|
||||
offset: float = 0.0
|
||||
page_width: float | None = None
|
||||
|
||||
|
||||
class PageElt(ApiModel):
|
||||
width: float
|
||||
height: float
|
||||
page_number: float
|
||||
text_elements: list[TextElt]
|
||||
image_elements: list[ImageElt]
|
||||
|
||||
|
||||
class Metadata(ApiModel):
|
||||
number_of_pages: int
|
||||
|
||||
|
||||
class FontElt(ApiModel):
|
||||
id: str | None
|
||||
uid: str | None
|
||||
base_name: str | None = None
|
||||
embedded: bool
|
||||
program: None
|
||||
program_format: None = None
|
||||
web_program: None = None
|
||||
web_program_format: None = None
|
||||
pdf_program: None = None
|
||||
pdf_program_format: None = None
|
||||
ascent: float
|
||||
descent: float
|
||||
units_per_em: float
|
||||
standard14_name: None = None
|
||||
color: str | None
|
||||
font_descriptor_flags: int | None = None
|
||||
|
||||
|
||||
class DocumentElt(ApiModel):
|
||||
metadata: Metadata
|
||||
fonts: list[FontElt]
|
||||
pages: list[PageElt]
|
||||
lazy_images: bool
|
||||
|
||||
|
||||
class Document(ApiModel):
|
||||
document: DocumentElt
|
||||
@@ -0,0 +1,47 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from enum import StrEnum
|
||||
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
from pydantic.alias_generators import to_camel
|
||||
|
||||
from .base import ApiModel
|
||||
|
||||
|
||||
class ThemePayload(BaseModel):
|
||||
model_config = ConfigDict(
|
||||
alias_generator=to_camel,
|
||||
extra="allow", # CSS var overrides (--theme-primary etc.) are dynamic
|
||||
validate_by_name=True,
|
||||
validate_by_alias=True,
|
||||
)
|
||||
logo_base64: str | None = None
|
||||
|
||||
def css_overrides(self) -> dict[str, str] | None:
|
||||
extras = self.model_extra or {}
|
||||
return {k: str(v) for k, v in extras.items()} if extras else None
|
||||
|
||||
|
||||
class CreateStreamPhase(StrEnum):
|
||||
OUTLINE = "outline"
|
||||
DRAFT = "draft"
|
||||
POLISH = "polish"
|
||||
REVISE = "revise"
|
||||
|
||||
|
||||
class CreateStreamRequest(ApiModel):
|
||||
phase: CreateStreamPhase = CreateStreamPhase.OUTLINE
|
||||
theme: ThemePayload | None = None # theme dict sent in POST body
|
||||
additional_instructions: str = ""
|
||||
|
||||
# Optional HTML revision inputs (used when phase=REVISE).
|
||||
base_html: str | None = None
|
||||
|
||||
|
||||
class PreviewTemplateHtmlRequest(ApiModel):
|
||||
template: str = ""
|
||||
|
||||
|
||||
class RenderPreviewRequest(ApiModel):
|
||||
template: str = ""
|
||||
theme: ThemePayload | None = None
|
||||
@@ -0,0 +1,41 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from .base import ApiModel
|
||||
from .chat import ChatMessage
|
||||
|
||||
|
||||
class AvailableTool(ApiModel):
|
||||
id: str
|
||||
name: str
|
||||
|
||||
|
||||
class SmartFolderOperation(ApiModel):
|
||||
operation: str
|
||||
parameters: str = Field(default="{}")
|
||||
|
||||
|
||||
class SmartFolderAutomation(ApiModel):
|
||||
name: str
|
||||
description: str | None = None
|
||||
operations: list[SmartFolderOperation] = Field(default_factory=list)
|
||||
|
||||
|
||||
class SmartFolderConfig(ApiModel):
|
||||
name: str
|
||||
description: str
|
||||
automation: SmartFolderAutomation
|
||||
icon: str
|
||||
accent_color: str
|
||||
|
||||
|
||||
class SmartFolderCreateRequest(ApiModel):
|
||||
message: str = ""
|
||||
history: list[ChatMessage] = Field(default_factory=list)
|
||||
available_tools: list[AvailableTool] = Field(default_factory=list)
|
||||
|
||||
|
||||
class SmartFolderCreateResponse(ApiModel):
|
||||
assistant_message: str
|
||||
smart_folder_config: SmartFolderConfig | None = None
|
||||
@@ -0,0 +1,439 @@
|
||||
# AUTO-GENERATED FILE. DO NOT EDIT.
|
||||
# Generated by scripts/generate_tool_models.py from frontend TypeScript sources.
|
||||
from __future__ import annotations
|
||||
|
||||
from enum import StrEnum
|
||||
from typing import Any, Literal
|
||||
|
||||
from models.base import ApiModel
|
||||
|
||||
|
||||
class AddAttachmentsParams(ApiModel):
|
||||
attachments: list[dict[str, Any]] = []
|
||||
|
||||
|
||||
class AdjustContrastParams(ApiModel):
|
||||
blue: float = 100
|
||||
brightness: float = 100
|
||||
contrast: float = 100
|
||||
green: float = 100
|
||||
red: float = 100
|
||||
saturation: float = 100
|
||||
|
||||
|
||||
class AutoRenameParams(ApiModel):
|
||||
use_first_text_as_fallback: bool = False
|
||||
|
||||
|
||||
class AutomateParams(ApiModel):
|
||||
pass
|
||||
|
||||
|
||||
class BookletImpositionParams(ApiModel):
|
||||
add_border: bool = False
|
||||
add_gutter: bool = False
|
||||
double_sided: bool = True
|
||||
duplex_pass: Literal["BOTH", "FIRST", "SECOND"] = "BOTH"
|
||||
flip_on_short_edge: bool = False
|
||||
gutter_size: float = 12
|
||||
pages_per_sheet: float = 2
|
||||
spine_location: Literal["LEFT", "RIGHT"] = "LEFT"
|
||||
|
||||
|
||||
class CertSignParams(ApiModel):
|
||||
cert_file: dict[str, Any] | None = None
|
||||
cert_type: Literal["", "PEM", "PKCS12", "PFX", "JKS"] = ""
|
||||
jks_file: dict[str, Any] | None = None
|
||||
location: str = ""
|
||||
name: str = ""
|
||||
p12_file: dict[str, Any] | None = None
|
||||
page_number: float = 1
|
||||
password: str = ""
|
||||
private_key_file: dict[str, Any] | None = None
|
||||
reason: str = ""
|
||||
show_logo: bool = True
|
||||
show_signature: bool = False
|
||||
sign_mode: Literal["MANUAL", "AUTO"] = "MANUAL"
|
||||
|
||||
|
||||
class ChangeMetadataParams(ApiModel):
|
||||
author: str = ""
|
||||
creation_date: str | None = None
|
||||
creator: str = ""
|
||||
custom_metadata: list[dict[str, str]] = []
|
||||
delete_all: bool = False
|
||||
keywords: str = ""
|
||||
modification_date: str | None = None
|
||||
producer: str = ""
|
||||
subject: str = ""
|
||||
title: str = ""
|
||||
trapped: Literal["True", "False", "Unknown"] | None = None
|
||||
|
||||
|
||||
class ChangePermissionsParams(ApiModel):
|
||||
prevent_assembly: bool = False
|
||||
prevent_extract_content: bool = False
|
||||
prevent_extract_for_accessibility: bool = False
|
||||
prevent_fill_in_form: bool = False
|
||||
prevent_modify: bool = False
|
||||
prevent_modify_annotations: bool = False
|
||||
prevent_printing: bool = False
|
||||
prevent_printing_faithful: bool = False
|
||||
|
||||
|
||||
class AddPasswordParams(ApiModel):
|
||||
key_length: float = 128
|
||||
owner_password: str = ""
|
||||
password: str = ""
|
||||
permissions: ChangePermissionsParams = ChangePermissionsParams.model_validate(
|
||||
{
|
||||
"preventAssembly": False,
|
||||
"preventExtractContent": False,
|
||||
"preventExtractForAccessibility": False,
|
||||
"preventFillInForm": False,
|
||||
"preventModify": False,
|
||||
"preventModifyAnnotations": False,
|
||||
"preventPrinting": False,
|
||||
"preventPrintingFaithful": False,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class CompressParams(ApiModel):
|
||||
compression_level: float = 5
|
||||
compression_method: Literal["quality", "filesize"] = "quality"
|
||||
expected_size: str = ""
|
||||
file_size_unit: Literal["KB", "MB"] = "MB"
|
||||
file_size_value: str = ""
|
||||
grayscale: bool = False
|
||||
|
||||
|
||||
class ConvertParams(ApiModel):
|
||||
cbz_options: dict[str, bool] = {"optimizeForEbook": False}
|
||||
cbz_output_options: dict[str, float] = {"dpi": 150}
|
||||
email_options: dict[str, Any] = {
|
||||
"includeAttachments": True,
|
||||
"maxAttachmentSizeMB": 10,
|
||||
"downloadHtml": False,
|
||||
"includeAllRecipients": False,
|
||||
}
|
||||
from_extension: str = ""
|
||||
html_options: dict[str, float] = {"zoomLevel": 1}
|
||||
image_options: dict[str, Any] = {
|
||||
"colorType": "color",
|
||||
"dpi": 300,
|
||||
"singleOrMultiple": "multiple",
|
||||
"fitOption": "maintainAspectRatio",
|
||||
"autoRotate": True,
|
||||
"combineImages": True,
|
||||
}
|
||||
is_smart_detection: bool = False
|
||||
pdfa_options: dict[str, str] = {"outputFormat": "pdfa-1"}
|
||||
smart_detection_type: Literal["mixed", "images", "web", "none"] = "none"
|
||||
to_extension: str = ""
|
||||
|
||||
|
||||
class CropParams(ApiModel):
|
||||
crop_area: dict[str, float] = {"x": 0, "y": 0, "width": 595, "height": 842}
|
||||
|
||||
|
||||
class EditTableOfContentsParams(ApiModel):
|
||||
bookmarks: list[dict[str, Any]] = []
|
||||
replace_existing: bool = True
|
||||
|
||||
|
||||
class ExtractImagesParams(ApiModel):
|
||||
allow_duplicates: bool = False
|
||||
format: Literal["png", "jpg", "gif"] = "png"
|
||||
|
||||
|
||||
class ExtractPagesParams(ApiModel):
|
||||
page_numbers: str = ""
|
||||
|
||||
|
||||
class FlattenParams(ApiModel):
|
||||
flatten_only_forms: bool = False
|
||||
|
||||
|
||||
class MergeParams(ApiModel):
|
||||
generate_table_of_contents: bool = False
|
||||
remove_digital_signature: bool = False
|
||||
|
||||
|
||||
class OcrParams(ApiModel):
|
||||
additional_options: list[str] = []
|
||||
languages: list[str] = []
|
||||
ocr_render_type: str = "hocr"
|
||||
ocr_type: str = "skip-text"
|
||||
|
||||
|
||||
class OverlayPdfsParams(ApiModel):
|
||||
counts: list[float] = []
|
||||
overlay_files: list[dict[str, Any]] = []
|
||||
overlay_mode: Literal["SequentialOverlay", "InterleavedOverlay", "FixedRepeatOverlay"] = "SequentialOverlay"
|
||||
overlay_position: Literal[0, 1] = 0
|
||||
|
||||
|
||||
class PageLayoutParams(ApiModel):
|
||||
add_border: bool = False
|
||||
pages_per_sheet: float = 4
|
||||
|
||||
|
||||
class PdfToSinglePageParams(ApiModel):
|
||||
pass
|
||||
|
||||
|
||||
class RedactParams(ApiModel):
|
||||
convert_pdfto_image: bool = True
|
||||
custom_padding: float = 0.1
|
||||
mode: Literal["automatic", "manual"] = "automatic"
|
||||
redact_color: str = "#000000"
|
||||
use_regex: bool = False
|
||||
whole_word_search: bool = False
|
||||
words_to_redact: list[str] = []
|
||||
|
||||
|
||||
class RemoveAnnotationsParams(ApiModel):
|
||||
pass
|
||||
|
||||
|
||||
class RemoveBlanksParams(ApiModel):
|
||||
include_blank_pages: bool = False
|
||||
threshold: float = 10
|
||||
white_percent: float = 99.9
|
||||
|
||||
|
||||
class RemoveCertSignParams(ApiModel):
|
||||
pass
|
||||
|
||||
|
||||
class RemoveImageParams(ApiModel):
|
||||
pass
|
||||
|
||||
|
||||
class RemovePagesParams(ApiModel):
|
||||
page_numbers: str = ""
|
||||
|
||||
|
||||
class RemovePasswordParams(ApiModel):
|
||||
password: str = ""
|
||||
|
||||
|
||||
class ReorganizePagesParams(ApiModel):
|
||||
custom_mode: str | None = None
|
||||
page_numbers: str | None = None
|
||||
|
||||
|
||||
class RepairParams(ApiModel):
|
||||
pass
|
||||
|
||||
|
||||
class ReplaceColorParams(ApiModel):
|
||||
back_ground_color: str = "#ffffff"
|
||||
high_contrast_color_combination: Literal[
|
||||
"WHITE_TEXT_ON_BLACK", "BLACK_TEXT_ON_WHITE", "YELLOW_TEXT_ON_BLACK", "GREEN_TEXT_ON_BLACK"
|
||||
] = "WHITE_TEXT_ON_BLACK"
|
||||
replace_and_invert_option: Literal[
|
||||
"HIGH_CONTRAST_COLOR", "CUSTOM_COLOR", "FULL_INVERSION", "COLOR_SPACE_CONVERSION"
|
||||
] = "HIGH_CONTRAST_COLOR"
|
||||
text_color: str = "#000000"
|
||||
|
||||
|
||||
class RotateParams(ApiModel):
|
||||
angle: float = 0
|
||||
|
||||
|
||||
class SanitizeParams(ApiModel):
|
||||
remove_embedded_files: bool = True
|
||||
remove_fonts: bool = False
|
||||
remove_java_script: bool = True
|
||||
remove_links: bool = False
|
||||
remove_metadata: bool = False
|
||||
remove_xmpmetadata: bool = False
|
||||
|
||||
|
||||
class ScalePagesParams(ApiModel):
|
||||
page_size: Literal["KEEP", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "LETTER", "LEGAL"] | None = None
|
||||
scale_factor: float = 1
|
||||
|
||||
|
||||
class ScannerImageSplitParams(ApiModel):
|
||||
angle_threshold: float = 10
|
||||
border_size: float = 1
|
||||
min_area: float = 10000
|
||||
min_contour_area: float = 500
|
||||
tolerance: float = 30
|
||||
|
||||
|
||||
class SignParams(ApiModel):
|
||||
font_family: str = "Helvetica"
|
||||
font_size: float = 16
|
||||
location: str = "Digital"
|
||||
reason: str = "Document signing"
|
||||
signature_data: str | None = None
|
||||
signature_position: dict[str, float] | None = None
|
||||
signature_type: Literal["text", "image", "canvas"] = "canvas"
|
||||
signer_name: str = ""
|
||||
text_color: str = "#000000"
|
||||
|
||||
|
||||
class SplitParams(ApiModel):
|
||||
allow_duplicates: bool = False
|
||||
bookmark_level: str = "1"
|
||||
duplex_mode: bool = False
|
||||
h_div: str = "2"
|
||||
include_metadata: bool = False
|
||||
merge: bool = False
|
||||
method: Literal[
|
||||
"", "byPages", "bySections", "bySize", "byPageCount", "byDocCount", "byChapters", "byPageDivider"
|
||||
] = ""
|
||||
pages: str = ""
|
||||
split_value: str = ""
|
||||
v_div: str = "2"
|
||||
|
||||
|
||||
class UnlockPdfformsParams(ApiModel):
|
||||
pass
|
||||
|
||||
|
||||
class WatermarkParams(ApiModel):
|
||||
alphabet: str = "roman"
|
||||
convert_pdfto_image: bool = False
|
||||
custom_color: str = "#d3d3d3"
|
||||
font_size: float = 12
|
||||
height_spacer: float = 50
|
||||
opacity: float = 50
|
||||
rotation: float = 0
|
||||
watermark_image: dict[str, Any] | None = None
|
||||
watermark_text: str = ""
|
||||
watermark_type: Literal["text", "image"] | None = None
|
||||
width_spacer: float = 50
|
||||
|
||||
|
||||
type ParamToolModel = (
|
||||
AddAttachmentsParams
|
||||
| AddPasswordParams
|
||||
| AdjustContrastParams
|
||||
| AutoRenameParams
|
||||
| AutomateParams
|
||||
| BookletImpositionParams
|
||||
| CertSignParams
|
||||
| ChangeMetadataParams
|
||||
| ChangePermissionsParams
|
||||
| CompressParams
|
||||
| ConvertParams
|
||||
| CropParams
|
||||
| EditTableOfContentsParams
|
||||
| ExtractImagesParams
|
||||
| ExtractPagesParams
|
||||
| FlattenParams
|
||||
| MergeParams
|
||||
| OcrParams
|
||||
| OverlayPdfsParams
|
||||
| PageLayoutParams
|
||||
| PdfToSinglePageParams
|
||||
| RedactParams
|
||||
| RemoveAnnotationsParams
|
||||
| RemoveBlanksParams
|
||||
| RemoveCertSignParams
|
||||
| RemoveImageParams
|
||||
| RemovePagesParams
|
||||
| RemovePasswordParams
|
||||
| ReorganizePagesParams
|
||||
| RepairParams
|
||||
| ReplaceColorParams
|
||||
| RotateParams
|
||||
| SanitizeParams
|
||||
| ScalePagesParams
|
||||
| ScannerImageSplitParams
|
||||
| SignParams
|
||||
| SplitParams
|
||||
| UnlockPdfformsParams
|
||||
| WatermarkParams
|
||||
)
|
||||
type ParamToolModelType = type[ParamToolModel]
|
||||
|
||||
|
||||
class OperationId(StrEnum):
|
||||
ADD_ATTACHMENTS = "addAttachments"
|
||||
ADD_PASSWORD = "addPassword"
|
||||
ADJUST_CONTRAST = "adjustContrast"
|
||||
AUTO_RENAME = "autoRename"
|
||||
AUTOMATE = "automate"
|
||||
BOOKLET_IMPOSITION = "bookletImposition"
|
||||
CERT_SIGN = "certSign"
|
||||
CHANGE_METADATA = "changeMetadata"
|
||||
CHANGE_PERMISSIONS = "changePermissions"
|
||||
COMPRESS = "compress"
|
||||
CONVERT = "convert"
|
||||
CROP = "crop"
|
||||
EDIT_TABLE_OF_CONTENTS = "editTableOfContents"
|
||||
EXTRACT_IMAGES = "extractImages"
|
||||
EXTRACT_PAGES = "extractPages"
|
||||
FLATTEN = "flatten"
|
||||
MERGE = "merge"
|
||||
OCR = "ocr"
|
||||
OVERLAY_PDFS = "overlayPdfs"
|
||||
PAGE_LAYOUT = "pageLayout"
|
||||
PDF_TO_SINGLE_PAGE = "pdfToSinglePage"
|
||||
REDACT = "redact"
|
||||
REMOVE_ANNOTATIONS = "removeAnnotations"
|
||||
REMOVE_BLANKS = "removeBlanks"
|
||||
REMOVE_CERT_SIGN = "removeCertSign"
|
||||
REMOVE_IMAGE = "removeImage"
|
||||
REMOVE_PAGES = "removePages"
|
||||
REMOVE_PASSWORD = "removePassword"
|
||||
REORGANIZE_PAGES = "reorganizePages"
|
||||
REPAIR = "repair"
|
||||
REPLACE_COLOR = "replaceColor"
|
||||
ROTATE = "rotate"
|
||||
SANITIZE = "sanitize"
|
||||
SCALE_PAGES = "scalePages"
|
||||
SCANNER_IMAGE_SPLIT = "scannerImageSplit"
|
||||
SIGN = "sign"
|
||||
SPLIT = "split"
|
||||
UNLOCK_PDFFORMS = "unlockPDFForms"
|
||||
WATERMARK = "watermark"
|
||||
|
||||
|
||||
OPERATIONS: dict[OperationId, ParamToolModelType] = {
|
||||
OperationId.ADD_ATTACHMENTS: AddAttachmentsParams,
|
||||
OperationId.ADD_PASSWORD: AddPasswordParams,
|
||||
OperationId.ADJUST_CONTRAST: AdjustContrastParams,
|
||||
OperationId.AUTO_RENAME: AutoRenameParams,
|
||||
OperationId.AUTOMATE: AutomateParams,
|
||||
OperationId.BOOKLET_IMPOSITION: BookletImpositionParams,
|
||||
OperationId.CERT_SIGN: CertSignParams,
|
||||
OperationId.CHANGE_METADATA: ChangeMetadataParams,
|
||||
OperationId.CHANGE_PERMISSIONS: ChangePermissionsParams,
|
||||
OperationId.COMPRESS: CompressParams,
|
||||
OperationId.CONVERT: ConvertParams,
|
||||
OperationId.CROP: CropParams,
|
||||
OperationId.EDIT_TABLE_OF_CONTENTS: EditTableOfContentsParams,
|
||||
OperationId.EXTRACT_IMAGES: ExtractImagesParams,
|
||||
OperationId.EXTRACT_PAGES: ExtractPagesParams,
|
||||
OperationId.FLATTEN: FlattenParams,
|
||||
OperationId.MERGE: MergeParams,
|
||||
OperationId.OCR: OcrParams,
|
||||
OperationId.OVERLAY_PDFS: OverlayPdfsParams,
|
||||
OperationId.PAGE_LAYOUT: PageLayoutParams,
|
||||
OperationId.PDF_TO_SINGLE_PAGE: PdfToSinglePageParams,
|
||||
OperationId.REDACT: RedactParams,
|
||||
OperationId.REMOVE_ANNOTATIONS: RemoveAnnotationsParams,
|
||||
OperationId.REMOVE_BLANKS: RemoveBlanksParams,
|
||||
OperationId.REMOVE_CERT_SIGN: RemoveCertSignParams,
|
||||
OperationId.REMOVE_IMAGE: RemoveImageParams,
|
||||
OperationId.REMOVE_PAGES: RemovePagesParams,
|
||||
OperationId.REMOVE_PASSWORD: RemovePasswordParams,
|
||||
OperationId.REORGANIZE_PAGES: ReorganizePagesParams,
|
||||
OperationId.REPAIR: RepairParams,
|
||||
OperationId.REPLACE_COLOR: ReplaceColorParams,
|
||||
OperationId.ROTATE: RotateParams,
|
||||
OperationId.SANITIZE: SanitizeParams,
|
||||
OperationId.SCALE_PAGES: ScalePagesParams,
|
||||
OperationId.SCANNER_IMAGE_SPLIT: ScannerImageSplitParams,
|
||||
OperationId.SIGN: SignParams,
|
||||
OperationId.SPLIT: SplitParams,
|
||||
OperationId.UNLOCK_PDFFORMS: UnlockPdfformsParams,
|
||||
OperationId.WATERMARK: WatermarkParams,
|
||||
}
|
||||
Reference in New Issue
Block a user