mirror of
https://github.com/yogeshojha/rengine.git
synced 2026-10-20 07:11:28 +02:00
Repo-wide sweep of every user-facing string: frontend components, routes, config and stores; API details and route docs; shared definitions and models; stage config help; report prose; MCP, toolbox, interest and connector text; notification and worker messages. Descriptions that explained, reassured, justified or restated their title are deleted. Confirm dialogs name what is removed and stop. Failed actions read "<Noun> not <verbed>", successes "<Noun> <verbed>". No reader address, no product-as-subject, no em-dashes or parentheticals in prose. Mirrors updated on both sides: EPSS band help, compare refusal reasons, interest labels. Four tests asserting on old wording follow the new text. The rules are condensed into CLAUDE.md under Writing. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SK5o8xR96cbSnAfjYSTPSe
85 lines
2.8 KiB
Python
85 lines
2.8 KiB
Python
import uuid
|
|
from datetime import datetime
|
|
|
|
from pydantic import BaseModel, ConfigDict
|
|
from pydantic import Field as PydanticField
|
|
from sqlalchemy import Column, Text
|
|
from sqlmodel import Field, SQLModel, UniqueConstraint
|
|
|
|
from shared.utils.datetime import utc_now
|
|
|
|
|
|
class AiNarrative(SQLModel, table=True):
|
|
"""Written prose keyed by what it was written from."""
|
|
|
|
__tablename__ = "ai_narratives"
|
|
__table_args__ = (
|
|
UniqueConstraint("task", "cache_key", name="uq_ai_narrative_task_key"),
|
|
)
|
|
|
|
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
|
|
task: str = Field(max_length=40, index=True)
|
|
cache_key: str = Field(max_length=64, index=True)
|
|
subject: str = Field(default="", max_length=300)
|
|
provider: str = Field(max_length=32)
|
|
model: str = Field(max_length=80)
|
|
content: str = Field(sa_column=Column(Text, nullable=False))
|
|
input_tokens: int = Field(default=0)
|
|
output_tokens: int = Field(default=0)
|
|
hits: int = Field(default=0)
|
|
created_at: datetime = Field(default_factory=utc_now, index=True)
|
|
last_used_at: datetime = Field(default_factory=utc_now)
|
|
|
|
|
|
class AiUsageRead(BaseModel):
|
|
calls: int = 0
|
|
cached: int = 0
|
|
input_tokens: int = 0
|
|
output_tokens: int = 0
|
|
cost_usd: float | None = None
|
|
reports: int = 0
|
|
since: datetime | None = None
|
|
|
|
|
|
class AiStatus(BaseModel):
|
|
"""AI connection status with the key masked."""
|
|
|
|
enabled: bool = False
|
|
configured: bool = False
|
|
provider: str | None = None
|
|
model: str | None = None
|
|
fast_model: str | None = None
|
|
workspace_id: str | None = None
|
|
key_masked: str | None = None
|
|
features: dict[str, bool] = PydanticField(default_factory=dict)
|
|
usage: AiUsageRead = PydanticField(default_factory=AiUsageRead)
|
|
cached_narratives: int = 0
|
|
|
|
|
|
class AiSettingsUpdate(BaseModel):
|
|
model_config = ConfigDict(extra="forbid")
|
|
|
|
enabled: bool | None = None
|
|
provider: str | None = PydanticField(default=None, max_length=32)
|
|
model: str | None = PydanticField(default=None, max_length=80)
|
|
fast_model: str | None = PydanticField(default=None, max_length=80)
|
|
workspace_id: str | None = PydanticField(default=None, max_length=80)
|
|
api_key: str | None = PydanticField(default=None, max_length=400)
|
|
features: dict[str, bool] | None = None
|
|
|
|
|
|
class AiTestRequest(BaseModel):
|
|
model_config = ConfigDict(extra="forbid")
|
|
|
|
provider: str | None = PydanticField(default=None, max_length=32)
|
|
model: str | None = PydanticField(default=None, max_length=80)
|
|
workspace_id: str | None = PydanticField(default=None, max_length=80)
|
|
api_key: str | None = PydanticField(default=None, max_length=400)
|
|
|
|
|
|
class AiTestResult(BaseModel):
|
|
success: bool
|
|
message: str
|
|
model: str | None = None
|
|
latency_ms: int | None = None
|