Add three-stage cross-domain news research and reading briefings
Group original news into tagged fact packages, review each package with evidence and read-only research, and build complete 72-hour reading lists with independent model selections. Add paused RSS/Atom subscriptions, news-scoped Skills, versioned analysis records, and locked deployment support for SearXNG. Preserve original news and keep live migration and legacy AI cleanup separately authorized. Validate with 604 backend tests, 49 frontend tests, 19 CI control tests, lint, type checks, production build, and disposable PostgreSQL migration and three-stage smoke checks.
This commit is contained in:
1 parent
ae35d3d608
commit
80d266dba7
44 files changed
+2682
-574
No files matched your search
@@ -67,6 +67,14 @@ class Outlook(BaseModel):
|
||||
windows: list[Scenario]
|
||||
|
||||
|
||||
class OutputTruncated(ValueError):
|
||||
"""A read-only model call may be repeated with a smaller input batch."""
|
||||
|
||||
def __init__(self, message, usage=None):
|
||||
super().__init__(message)
|
||||
self.usage = usage
|
||||
|
||||
|
||||
async def complete(provider: AiProvider, system: str, payload: dict, schema: type[BaseModel]):
|
||||
text = json.dumps(payload, ensure_ascii=False)
|
||||
if not fits_context(provider, system, payload, schema):
|
||||
@@ -76,7 +84,9 @@ async def complete(provider: AiProvider, system: str, payload: dict, schema: typ
|
||||
async for item in llm.stream(provider, system, [{'role': 'user', 'text': text}], [tool], provider.reasoning_effort):
|
||||
if isinstance(item, llm.Completion):
|
||||
completion = item
|
||||
if completion is None or completion.truncated:
|
||||
if completion is not None and completion.truncated:
|
||||
raise OutputTruncated('模型输出被截断', completion.usage)
|
||||
if completion is None:
|
||||
raise ValueError('模型未完成输出或输出被截断')
|
||||
calls = [call for call in completion.tool_calls if call['name'] == 'submit']
|
||||
if len(calls) != 1:
|
||||
@@ -132,5 +142,5 @@ async def default_settings(session):
|
||||
if settings is None:
|
||||
provider = await session.scalar(select(AiProvider).where(AiProvider.is_default))
|
||||
return RiskSettings(id=1, enabled=False, provider_id=provider.id if provider else None,
|
||||
model=provider.model if provider else '')
|
||||
model=provider.model if provider else '', second_model='', third_model='')
|
||||
return settings
|
||||
Reference in new issue
Block a user