Skip to content
Merged
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
3 changes: 2 additions & 1 deletion packages/discolike-cli/src/discolike_cli/bulk.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ def companies_command(
employee_range: str | None = typer.Option(None, help="Employee count range filter."),
revenue_range: str | None = typer.Option(None, help="Revenue range filter."),
variance: str | None = typer.Option(
None, help="Result diversity: LOW, MID_LOW, MEDIUM, MID_HIGH, HIGH, UNRESTRICTED."
None,
help="Where the list stops: LOW (earliest), MID_LOW, MEDIUM, MID_HIGH, HIGH (latest), UNRESTRICTED (never).",
),
exclusion_query_id: list[str] | None = typer.Option(None, help=EXCLUSION_QUERY_ID_HELP),
param: list[str] | None = typer.Option(None, "--param", help=PARAM_HELP),
Expand Down
7 changes: 4 additions & 3 deletions packages/discolike-cli/src/discolike_cli/discover.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,11 @@ def discover_command(
max_digital_footprint: int | None = typer.Option(None, help="Maximum digital footprint score."),
min_similarity: int | None = typer.Option(None, help="Minimum similarity score to include (0-99)."),
variance: str | None = typer.Option(
None, help="Result diversity control: LOW, MID_LOW, MEDIUM, MID_HIGH, HIGH, UNRESTRICTED."
None,
help="Where the list stops: LOW (earliest), MID_LOW, MEDIUM, MID_HIGH, HIGH (latest), UNRESTRICTED (never).",
),
consensus: int | None = typer.Option(
None, help="Number of top results for the consensus search vector (1-20); higher reduces specificity."
None, help="Deprecated, no-op. Discover applies consensus itself to single-domain lookalike searches."
),
redirect: bool | None = typer.Option(None, "--redirect/--no-redirect", help=REDIRECT_HELP),
exclude_leadgen: bool | None = typer.Option(
Expand All @@ -118,7 +119,7 @@ def discover_command(
None, "--retrieval/--no-retrieval", help="Enable page data retrieval using the Extract API."
),
enhanced: bool | None = typer.Option(
None, "--enhanced/--no-enhanced", help="Enable AI-powered result enhancement for improved relevance."
None, "--enhanced/--no-enhanced", help="Deprecated, no-op. Discover no longer adds AI-suggested domains."
),
include_search_domains: bool | None = typer.Option(
None,
Expand Down
18 changes: 1 addition & 17 deletions packages/discolike/src/discolike/_generated/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2071,13 +2071,6 @@ class DiscoverParams(DiscolikeRequest):
title="Retrieval",
),
] = False
enhanced: Annotated[
bool | None,
Field(
description="Enable AI-powered result enhancement for improved relevance.",
title="Enhanced",
),
] = False
include_search_domains: Annotated[
bool | None,
Field(
Expand All @@ -2094,15 +2087,6 @@ class DiscoverParams(DiscolikeRequest):
title="Max Records",
),
] = 100
consensus: Annotated[
int | None,
Field(
description="Number of top results for consensus search vector (1-20). Higher values reduce specificity.",
ge=1,
le=20,
title="Consensus",
),
] = 1
min_similarity: Annotated[
int | None,
Field(
Expand All @@ -2115,7 +2099,7 @@ class DiscoverParams(DiscolikeRequest):
variance: Annotated[
Literal["LOW", "MID_LOW", "MEDIUM", "MID_HIGH", "HIGH", "UNRESTRICTED"] | None,
Field(
description="Result diversity control: LOW, MID_LOW, MEDIUM, MID_HIGH, HIGH, UNRESTRICTED.",
description="Where the list stops: LOW earliest (rows ~70% fit), MID_LOW, MEDIUM, MID_HIGH, HIGH latest (~30%). UNRESTRICTED never stops.",
title="Variance",
),
] = "UNRESTRICTED"
Expand Down
11 changes: 9 additions & 2 deletions packages/discolike/src/discolike/_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
"contact search no longer filters on email verification; verify emails instead."
),
}
DEPRECATED_MODEL_FIELDS: dict[str, dict[str, str]] = {
"DiscoverParams": {
"consensus": "consensus is deprecated and ignored: discover applies consensus itself to single-domain lookalike searches.",
"enhanced": "enhanced is deprecated and ignored: discover no longer adds AI-suggested domains.",
},
}


class DiscolikeModel(pydantic.BaseModel):
Expand Down Expand Up @@ -78,8 +84,9 @@ def _validate_geo_shapes(self) -> DiscolikeRequest:
@classmethod
def _warn_deprecated_fields(cls, data: object) -> object:
if isinstance(data, dict):
for name in sorted(DEPRECATED_REQUEST_FIELDS.keys() & data.keys()):
warnings.warn(DEPRECATED_REQUEST_FIELDS[name], DeprecationWarning, stacklevel=2)
deprecated = DEPRECATED_REQUEST_FIELDS | DEPRECATED_MODEL_FIELDS.get(cls.__name__, {})
for name in sorted(deprecated.keys() & data.keys()):
warnings.warn(deprecated[name], DeprecationWarning, stacklevel=2)
return data

# Mirrors the platform's text_or_intake rule on ProspectingMessageRequest, which the spec cannot express.
Expand Down
11 changes: 11 additions & 0 deletions packages/discolike/src/discolike/resources/prospecting.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,14 @@ class ProspectingInFlight(DiscolikeModel):
progress: int | None = None


class ProspectingOpenQuestion(DiscolikeModel):
question_seq: int | None
reason: str
content: str
replies: list[str] = Field(default_factory=list)
estimate: dict[str, Any] | None = None


class ProspectingRunSummary(DiscolikeModel):
run_id: UUID
status: ProspectingStatus
Expand Down Expand Up @@ -145,6 +153,9 @@ class ProspectingRun(DiscolikeModel):
actions_used: int = 0
max_actions: int
error: str | None = None
question: ProspectingOpenQuestion | None = Field(
default=None, description="What a needs_input run waits on; replies are exact labels, empty for free text."
)
title: str | None = None
plan_version: int = 1
approved_plan_version: int | None = None
Expand Down
9 changes: 9 additions & 0 deletions packages/discolike/tests/test_prospecting.py
Original file line number Diff line number Diff line change
Expand Up @@ -735,3 +735,12 @@ def handler(request: httpx2.Request) -> httpx2.Response:
with make_client(handler) as client, pytest.raises(ValidationError):
client.prospecting.answer_intake(RUN_ID, {}, idempotency_key="k")
assert seen == []


def test_run_parses_the_open_question_of_a_needs_input_run() -> None:
question = {"question_seq": 4, "reason": "plan_review", "content": "Approve the plan?", "replies": ["Approve"]}
run = module.ProspectingRun.model_validate(run_payload() | {"question": question})
assert run.question == module.ProspectingOpenQuestion(
question_seq=4, reason="plan_review", content="Approve the plan?", replies=["Approve"]
)
assert module.ProspectingRun.model_validate(run_payload()).question is None
13 changes: 13 additions & 0 deletions packages/discolike/tests/test_requests_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,19 @@ def test_email_validated_is_deprecated_but_still_accepted(model: type[DiscolikeR
assert request.to_wire() == {"email_validated": True}


@pytest.mark.parametrize("name", ["consensus", "enhanced"])
def test_discover_consensus_and_enhanced_are_deprecated_but_still_sent(name: str) -> None:
with pytest.warns(DeprecationWarning, match=f"{name} is deprecated"):
request = DiscoverParams.model_validate({name: 2 if name == "consensus" else True})
assert name in request.to_wire()


def test_contacts_consensus_is_not_deprecated() -> None:
with warnings.catch_warnings():
warnings.simplefilter("error")
assert ContactsSearchParams(consensus=2).to_wire() == {"consensus": 2}


def test_unset_email_validated_does_not_warn() -> None:
with warnings.catch_warnings():
warnings.simplefilter("error")
Expand Down
Loading