Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
262 changes: 205 additions & 57 deletions asknews_sdk/dto/alert.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from datetime import datetime
from typing import Any, Dict, List, Literal, Optional, Union
from typing import Any, Dict, List, Literal, Optional, Union, get_args
from uuid import UUID

from pydantic import BaseModel, EmailStr, Field, RootModel
Expand All @@ -23,7 +23,7 @@
"gpt-4.1-mini-2025-04-14",
]

ReportModel = Literal[
AlertReportModel = Literal[
# "gpt-5",
"gpt-4o",
"gpt-4.1-2025-04-14",
Expand All @@ -33,7 +33,7 @@
"claude-sonnet-4-20250514",
"claude-sonnet-4-5-20250929",
"claude-opus-4-5-20251101",
"claude-opuse-4-6",
"claude-opus-4-6",
"meta-llama/Meta-Llama-3.1-405B-Instruct",
"meta-llama/Meta-Llama-3.3-70B-Instruct",
]
Expand Down Expand Up @@ -91,8 +91,75 @@ class BlueskySource(BaseModel):
params: Optional[BlueskySourceParams] = Field(None, description="Bluesky source parameters")


DeepNewsSourceType = Literal["asknews", "google", "graph", "wiki", "x", "reddit", "charts"]
DeepNewsSourceTypeDefault: DeepNewsSourceType = "asknews"

DeepNewsInlineCitationType = Literal["markdown_link", "numbered", "none"]
DeepNewsInlineCitationTypeDefault: DeepNewsInlineCitationType = "markdown_link"


class DeepNewsSourceParams(BaseModel):
model: Optional[str] = Field(
default=None,
description=("The model to use for DeepNews. Check API reference for default model."),
)
filter_params: Optional[Dict[str, Any]] = Field(
default=None, description="Any filter param available on the /news endpoint."
)
search_depth: Optional[int] = Field(
default=2,
description=(
"The search depth for deep research. Higher values mean more " "thorough research."
),
)
max_depth: Optional[int] = Field(default=4, description="The maximum research depth allowed.")
sources: Optional[Union[DeepNewsSourceType, List[DeepNewsSourceType]]] = Field(
default=DeepNewsSourceTypeDefault,
description=(
"Which data sources DeepNews should use. Can be a single source or a list. "
f"Available sources are: {', '.join(get_args(DeepNewsSourceType))}"
),
)
journalist_mode: Optional[bool] = Field(
default=True,
description=(
"Activate journalist mode, with improved alignment for making claims "
"with supporting evidence. Improved journalistic style."
),
)
include_entities: Optional[bool] = Field(
default=True,
description=(
"Include entities of the sources in the internal context. "
"Activating this will increase internal token usage."
),
)
include_graphs: Optional[bool] = Field(
default=False,
description=(
"Include graphs of the sources in the internal context. "
"Activating this will increase internal token usage."
),
)
include_coordinates: Optional[bool] = Field(
default=False,
description=(
"Include geocoordinates of the sources in the internal context. "
"Activating this will increase internal token usage."
),
)
asknews_watermark: Optional[bool] = Field(
default=True, description='Append "Generated by AskNews AI" watermark.'
)


class DeepNewsSource(BaseModel):
identifier: Literal["deepnews"]
params: Optional[DeepNewsSourceParams] = Field(None, description="DeepNews source parameters")


Source = Annotated[
Union[AskNewsSource, TelegramSource, BlueskySource, WebSource],
Union[AskNewsSource, TelegramSource, BlueskySource, WebSource, DeepNewsSource],
Field(discriminator="identifier"),
]

Expand Down Expand Up @@ -177,125 +244,191 @@ class ReportRequest(BaseModel):
["human", "{summaries}"],
],
)
model: Optional[ReportModel] = Field(
None, description="The model to use for the report", examples=["gpt-4o"]
model: Optional[AlertReportModel] = Field(
None,
description=(
"The model to use for the report. Check the API reference for "
"default model. If you have DeepNews as a source, the DeepNews "
"model will be used for the report."
),
examples=["gpt-4o"],
)
logo_url: Optional[HttpUrlString] = Field(
None, description="The logo URL to use for the report"
)


AlertType = Literal["AlertRepeat", "AlertOnce", "ReportRepeat", "ReportOnce"]


class CreateAlertRequest(BaseSchema):
query: Optional[str] = Field(
None,
description=(
"The query to run for the alert. For example you ask for "
'"I want to be alerted if there is a protest in paris"'
),
query: str = Field(
...,
description=("The query to run for the alert."),
examples=[
"I want to be alerted if the president of the US says something about the economy",
],
)
cron: CronStr = Field(
sources: Sources = Field(
...,
description=(
"The cron schedule for the alert. For example hourly is '0 * * * *'."
" See https://crontab.run/ for more examples"
"The sources to use for the alert query. Available sources are: "
f"{', '.join([arg.__name__ for arg in get_args(get_args(Source)[0])])}"
),
)
alert_type: Optional[AlertType] = Field(
None,
description=(
"The type of alert. If specified, overrides 'repeat'. "
"'AlertRepeat': trigger alert actions any time the alert query is satisfied. "
"'AlertOnce': trigger alert actions when the alert query is satisfied "
"and then disable the alert. "
"'ReportRepeat': trigger alert actions and write a report any time the alert "
"query is satisfied. If not specified, the default report model (see API "
"reference) is used. "
"'ReportOnce': trigger alert actions and write a report when the alert "
"query is satisfied and then disable the alert. If not specified, "
"the default report model (see API reference) is used."
),
examples=[
"*/15 * * * *",
],
)
model: Optional[CheckAlertModel] = Field(
...,
description="The model to use for the alert check",
None,
description=(
"The model that is used to check if the alert conditions are satisfied by "
"sources (this is not the same as the model used to write the report.)"
"Check the API reference for default model."
),
examples=[
"meta-llama/Meta-Llama-3.1-8B-Instruct",
],
)
share_link: Optional[HttpUrlString] = Field(
None, description="The newsplunker share link to update when the alert triggers"
cron: CronStr = Field(
...,
description=(
"How often or when to check sources for this alert, specified as a cron expression. "
"Examples: '*/15 * * * *' (every 15 minutes), '0 * * * *' (hourly), "
"'0 9 * * *' (daily at 9am), '0 9 * * 1' (Mondays at 9am). "
" See https://crontab.run/ for more examples."
),
examples=[
"'0 0 * * *' (daily at midnight UTC)",
],
)
sources: Sources = Field(..., description="The sources to use for the alert query")
report: Optional[ReportRequest] = Field(
None, description="The report to generate when the alert triggers"
triggers: Triggers = Field(
...,
description=(
"Configuration for actions to trigger for the alert. Available actions are: "
f"{', '.join([arg.__name__ for arg in get_args(get_args(Trigger)[0])])}"
),
)
triggers: Triggers = Field(..., description="The triggers to use for the alert")
always_trigger: bool = Field(
always_trigger: Optional[bool] = Field(
False,
description=(
"Whether to always trigger the alert. Default is False. This skips the "
"alert check and run triggers immediately"
"Whether to always trigger the actions when sources are scanned. This skips the "
"check for if the alert conditions are satisfied and run triggers immediately. "
"Defaults to False."
),
)
repeat: bool = Field(
repeat: Optional[bool] = Field(
True,
description=(
"Whether to repeat the alert. Default is True. If False, the alert will be "
"disabled after it triggers once"
),
)
active: bool = Field(True, description="Whether the alert is active or not. Default is True.")
active: Optional[bool] = Field(
True, description="Whether the alert is active or not. Default is True."
)
expires_at: Optional[datetime] = Field(
None,
description=(
"The expiration date for the alert. Default is None. "
"If set, the alert will be disabled after this date."
),
)
report: Optional[ReportRequest] = Field(
None,
description=(
"Configuration for generating a written report when the alert triggers. "
"If not specified, no report is generated."
),
)
title: Optional[str] = Field(
None,
description="The title of the alert. If not provided, no title will be used.",
examples=["Alert for US President's statements on the economy"],
)
share_link: Optional[HttpUrlString] = Field(
None, description="The Newsplunker share link to update when the alert triggers"
)


class UpdateAlertRequest(BaseSchema):
query: Optional[str] = Field(
None,
description=(
"The query to run for the alert. For example you ask for "
'"I want to be alerted if there is a protest in paris"'
),
description=("The query to run for the alert."),
examples=[
"I want to be alerted if the president of the US says something about the economy",
],
)
cron: Optional[CronStr] = Field(
sources: Optional[Sources] = Field(
None,
description=(
"The cron schedule for the alert. For example hourly is '0 * * * *'."
" See https://crontab.run/ for more examples"
"The sources to use for the alert query. Available sources are: "
f"{', '.join([arg.__name__ for arg in get_args(get_args(Source)[0])])}"
),
examples=[
"*/15 * * * *",
],
)
model: Optional[CheckAlertModel] = Field(
alert_type: Optional[AlertType] = Field(
None,
description="The model to use for the alert check",
examples=[
"meta-llama/Meta-Llama-3.1-8B-Instruct",
],
description=(
"The type of alert. If specified, overrides 'repeat'. "
"'AlertRepeat': trigger alert actions any time the alert query is satisfied. "
"'AlertOnce': trigger alert actions when the alert query is satisfied "
"and then disable the alert. "
"'ReportRepeat': trigger alert actions and write a report any time the alert "
"query is satisfied. "
"'ReportOnce': trigger alert actions and write a report when the alert "
"query is satisfied and then disable the alert."
),
)
share_link: Optional[HttpUrlString] = Field(
None, description="The newsplunker share link to update when the alert triggers"
model: Optional[CheckAlertModel] = Field(
None,
description=(
"The model that is used to check if the alert conditions are satisfied by "
"sources (this is not the same as the model used to write the report.)"
),
examples=["gpt-4o-mini"],
)
filter_params: Optional[FilterParams] = Field(
None, description="The filter params to use for the alert query"
cron: Optional[CronStr] = Field(
None,
description=(
"How often or when to check sources for this alert, specified as a cron expression. "
"Examples: '*/15 * * * *' (every 15 minutes), '0 * * * *' (hourly), "
"'0 9 * * *' (daily at 9am), '0 9 * * 1' (Mondays at 9am). "
" See https://crontab.run/ for more examples."
),
examples=["'0 0 * * *' (daily at midnight UTC)"],
)
sources: Optional[Sources] = Field(None, description="The sources to use for the alert query")
report: Optional[ReportRequest] = Field(
None, description="The report to generate when the alert triggers"
triggers: Optional[Triggers] = Field(
None,
description=(
"Configuration for actions to trigger for the alert. Available actions are: "
f"{', '.join([arg.__name__ for arg in get_args(get_args(Trigger)[0])])}"
),
)
triggers: Optional[Triggers] = Field(None, description="The triggers to use for the alert")
always_trigger: Optional[bool] = Field(
None,
description=(
"Whether to always trigger the alert. Default is False. This skips the "
"alert check and run triggers immediately"
"Whether to always trigger the actions when sources are scanned. This skips the "
"check for if the alert conditions are satisfied and run triggers immediately. "
"Defaults to False."
),
)
repeat: Optional[bool] = Field(
None,
description=(
"Whether to repeat the alert. Default is True. If False, the alert will be "
"disabled after it triggers once"
"disabled after it triggers once."
),
)
active: Optional[bool] = Field(
Expand All @@ -308,6 +441,21 @@ class UpdateAlertRequest(BaseSchema):
"If set, the alert will be disabled after this date."
),
)
report: Optional[ReportRequest] = Field(
None,
description=(
"Configuration for generating a written report when the alert triggers. "
"If not specified, no report is generated."
),
)
title: Optional[str] = Field(
None,
description="The title of the alert. If not provided, no title will be used.",
examples=["Alert for US President's statements on the economy"],
)
share_link: Optional[HttpUrlString] = Field(
None, description="The Newsplunker share link to update when the alert triggers."
)


class AlertLog(BaseModel):
Expand Down
Loading