From 41b210dc69c2b9c45eeab01a0afac6a4563d41f2 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 24 Jun 2025 23:17:37 +0000
Subject: [PATCH 01/18] feat(api): api update
---
.stats.yml | 2 +-
.../query_log_list_by_group_response.py | 33 +++++++++++++++-
.../query_log_list_groups_response.py | 39 ++++++++++++++++++-
.../types/projects/query_log_list_response.py | 39 ++++++++++++++++++-
.../projects/query_log_retrieve_response.py | 38 +++++++++++++++++-
...remediation_list_resolved_logs_response.py | 39 ++++++++++++++++++-
6 files changed, 180 insertions(+), 10 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 04c1386..9e05e79 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,3 +1,3 @@
configured_endpoints: 65
-openapi_spec_hash: 80696dc202de8bacc0e43506d7c210b0
+openapi_spec_hash: 8bc7a64933cd540d1d2499d055430832
config_hash: 14b2643a0ec60cf326dfed00939644ff
diff --git a/src/codex/types/projects/query_log_list_by_group_response.py b/src/codex/types/projects/query_log_list_by_group_response.py
index d11d827..9d1e0e6 100644
--- a/src/codex/types/projects/query_log_list_by_group_response.py
+++ b/src/codex/types/projects/query_log_list_by_group_response.py
@@ -10,10 +10,31 @@
"QueryLogListByGroupResponse",
"QueryLogsByGroup",
"QueryLogsByGroupQueryLog",
+ "QueryLogsByGroupQueryLogFormattedEscalationEvalScores",
+ "QueryLogsByGroupQueryLogFormattedEvalScores",
+ "QueryLogsByGroupQueryLogFormattedGuardrailEvalScores",
"QueryLogsByGroupQueryLogContext",
]
+class QueryLogsByGroupQueryLogFormattedEscalationEvalScores(BaseModel):
+ score: float
+
+ status: Literal["pass", "fail"]
+
+
+class QueryLogsByGroupQueryLogFormattedEvalScores(BaseModel):
+ score: float
+
+ status: Literal["pass", "fail"]
+
+
+class QueryLogsByGroupQueryLogFormattedGuardrailEvalScores(BaseModel):
+ score: float
+
+ status: Literal["pass", "fail"]
+
+
class QueryLogsByGroupQueryLogContext(BaseModel):
content: str
"""The actual content/text of the document."""
@@ -36,7 +57,9 @@ class QueryLogsByGroupQueryLog(BaseModel):
created_at: datetime
- formatted_eval_scores: Optional[Dict[str, Dict[str, Union[float, Literal["pass", "fail"]]]]] = None
+ formatted_escalation_eval_scores: Optional[Dict[str, QueryLogsByGroupQueryLogFormattedEscalationEvalScores]] = None
+
+ formatted_eval_scores: Optional[Dict[str, QueryLogsByGroupQueryLogFormattedEvalScores]] = None
"""Format evaluation scores for frontend display with pass/fail status.
Returns: Dictionary mapping eval keys to their formatted representation: {
@@ -44,6 +67,8 @@ class QueryLogsByGroupQueryLog(BaseModel):
eval_scores is None.
"""
+ formatted_guardrail_eval_scores: Optional[Dict[str, QueryLogsByGroupQueryLogFormattedGuardrailEvalScores]] = None
+
is_bad_response: bool
project_id: str
@@ -67,6 +92,9 @@ class QueryLogsByGroupQueryLog(BaseModel):
escalated: Optional[bool] = None
"""If true, the question was escalated to Codex for an SME to review"""
+ escalation_evals: Optional[List[str]] = None
+ """Evals that should trigger escalation to SME"""
+
eval_issue_labels: Optional[List[str]] = None
"""Labels derived from evaluation scores"""
@@ -79,6 +107,9 @@ class QueryLogsByGroupQueryLog(BaseModel):
evaluated_response: Optional[str] = None
"""The response being evaluated from the RAG system (before any remediation)"""
+ guardrail_evals: Optional[List[str]] = None
+ """Evals that should trigger guardrail"""
+
guardrailed: Optional[bool] = None
"""If true, the response was guardrailed"""
diff --git a/src/codex/types/projects/query_log_list_groups_response.py b/src/codex/types/projects/query_log_list_groups_response.py
index fd87c30..7b77cc0 100644
--- a/src/codex/types/projects/query_log_list_groups_response.py
+++ b/src/codex/types/projects/query_log_list_groups_response.py
@@ -6,7 +6,32 @@
from ..._models import BaseModel
-__all__ = ["QueryLogListGroupsResponse", "QueryLogGroup", "QueryLogGroupContext"]
+__all__ = [
+ "QueryLogListGroupsResponse",
+ "QueryLogGroup",
+ "QueryLogGroupFormattedEscalationEvalScores",
+ "QueryLogGroupFormattedEvalScores",
+ "QueryLogGroupFormattedGuardrailEvalScores",
+ "QueryLogGroupContext",
+]
+
+
+class QueryLogGroupFormattedEscalationEvalScores(BaseModel):
+ score: float
+
+ status: Literal["pass", "fail"]
+
+
+class QueryLogGroupFormattedEvalScores(BaseModel):
+ score: float
+
+ status: Literal["pass", "fail"]
+
+
+class QueryLogGroupFormattedGuardrailEvalScores(BaseModel):
+ score: float
+
+ status: Literal["pass", "fail"]
class QueryLogGroupContext(BaseModel):
@@ -31,7 +56,9 @@ class QueryLogGroup(BaseModel):
created_at: datetime
- formatted_eval_scores: Optional[Dict[str, Dict[str, Union[float, Literal["pass", "fail"]]]]] = None
+ formatted_escalation_eval_scores: Optional[Dict[str, QueryLogGroupFormattedEscalationEvalScores]] = None
+
+ formatted_eval_scores: Optional[Dict[str, QueryLogGroupFormattedEvalScores]] = None
"""Format evaluation scores for frontend display with pass/fail status.
Returns: Dictionary mapping eval keys to their formatted representation: {
@@ -39,6 +66,8 @@ class QueryLogGroup(BaseModel):
eval_scores is None.
"""
+ formatted_guardrail_eval_scores: Optional[Dict[str, QueryLogGroupFormattedGuardrailEvalScores]] = None
+
is_bad_response: bool
needs_review: bool
@@ -68,6 +97,9 @@ class QueryLogGroup(BaseModel):
escalated: Optional[bool] = None
"""If true, the question was escalated to Codex for an SME to review"""
+ escalation_evals: Optional[List[str]] = None
+ """Evals that should trigger escalation to SME"""
+
eval_issue_labels: Optional[List[str]] = None
"""Labels derived from evaluation scores"""
@@ -80,6 +112,9 @@ class QueryLogGroup(BaseModel):
evaluated_response: Optional[str] = None
"""The response being evaluated from the RAG system (before any remediation)"""
+ guardrail_evals: Optional[List[str]] = None
+ """Evals that should trigger guardrail"""
+
guardrailed: Optional[bool] = None
"""If true, the response was guardrailed"""
diff --git a/src/codex/types/projects/query_log_list_response.py b/src/codex/types/projects/query_log_list_response.py
index bfd37cd..fa04904 100644
--- a/src/codex/types/projects/query_log_list_response.py
+++ b/src/codex/types/projects/query_log_list_response.py
@@ -6,7 +6,32 @@
from ..._models import BaseModel
-__all__ = ["QueryLogListResponse", "QueryLog", "QueryLogContext"]
+__all__ = [
+ "QueryLogListResponse",
+ "QueryLog",
+ "QueryLogFormattedEscalationEvalScores",
+ "QueryLogFormattedEvalScores",
+ "QueryLogFormattedGuardrailEvalScores",
+ "QueryLogContext",
+]
+
+
+class QueryLogFormattedEscalationEvalScores(BaseModel):
+ score: float
+
+ status: Literal["pass", "fail"]
+
+
+class QueryLogFormattedEvalScores(BaseModel):
+ score: float
+
+ status: Literal["pass", "fail"]
+
+
+class QueryLogFormattedGuardrailEvalScores(BaseModel):
+ score: float
+
+ status: Literal["pass", "fail"]
class QueryLogContext(BaseModel):
@@ -31,7 +56,9 @@ class QueryLog(BaseModel):
created_at: datetime
- formatted_eval_scores: Optional[Dict[str, Dict[str, Union[float, Literal["pass", "fail"]]]]] = None
+ formatted_escalation_eval_scores: Optional[Dict[str, QueryLogFormattedEscalationEvalScores]] = None
+
+ formatted_eval_scores: Optional[Dict[str, QueryLogFormattedEvalScores]] = None
"""Format evaluation scores for frontend display with pass/fail status.
Returns: Dictionary mapping eval keys to their formatted representation: {
@@ -39,6 +66,8 @@ class QueryLog(BaseModel):
eval_scores is None.
"""
+ formatted_guardrail_eval_scores: Optional[Dict[str, QueryLogFormattedGuardrailEvalScores]] = None
+
is_bad_response: bool
project_id: str
@@ -62,6 +91,9 @@ class QueryLog(BaseModel):
escalated: Optional[bool] = None
"""If true, the question was escalated to Codex for an SME to review"""
+ escalation_evals: Optional[List[str]] = None
+ """Evals that should trigger escalation to SME"""
+
eval_issue_labels: Optional[List[str]] = None
"""Labels derived from evaluation scores"""
@@ -74,6 +106,9 @@ class QueryLog(BaseModel):
evaluated_response: Optional[str] = None
"""The response being evaluated from the RAG system (before any remediation)"""
+ guardrail_evals: Optional[List[str]] = None
+ """Evals that should trigger guardrail"""
+
guardrailed: Optional[bool] = None
"""If true, the response was guardrailed"""
diff --git a/src/codex/types/projects/query_log_retrieve_response.py b/src/codex/types/projects/query_log_retrieve_response.py
index 3b813ee..8bb6128 100644
--- a/src/codex/types/projects/query_log_retrieve_response.py
+++ b/src/codex/types/projects/query_log_retrieve_response.py
@@ -6,7 +6,31 @@
from ..._models import BaseModel
-__all__ = ["QueryLogRetrieveResponse", "Context"]
+__all__ = [
+ "QueryLogRetrieveResponse",
+ "FormattedEscalationEvalScores",
+ "FormattedEvalScores",
+ "FormattedGuardrailEvalScores",
+ "Context",
+]
+
+
+class FormattedEscalationEvalScores(BaseModel):
+ score: float
+
+ status: Literal["pass", "fail"]
+
+
+class FormattedEvalScores(BaseModel):
+ score: float
+
+ status: Literal["pass", "fail"]
+
+
+class FormattedGuardrailEvalScores(BaseModel):
+ score: float
+
+ status: Literal["pass", "fail"]
class Context(BaseModel):
@@ -31,7 +55,9 @@ class QueryLogRetrieveResponse(BaseModel):
created_at: datetime
- formatted_eval_scores: Optional[Dict[str, Dict[str, Union[float, Literal["pass", "fail"]]]]] = None
+ formatted_escalation_eval_scores: Optional[Dict[str, FormattedEscalationEvalScores]] = None
+
+ formatted_eval_scores: Optional[Dict[str, FormattedEvalScores]] = None
"""Format evaluation scores for frontend display with pass/fail status.
Returns: Dictionary mapping eval keys to their formatted representation: {
@@ -39,6 +65,8 @@ class QueryLogRetrieveResponse(BaseModel):
eval_scores is None.
"""
+ formatted_guardrail_eval_scores: Optional[Dict[str, FormattedGuardrailEvalScores]] = None
+
is_bad_response: bool
project_id: str
@@ -62,6 +90,9 @@ class QueryLogRetrieveResponse(BaseModel):
escalated: Optional[bool] = None
"""If true, the question was escalated to Codex for an SME to review"""
+ escalation_evals: Optional[List[str]] = None
+ """Evals that should trigger escalation to SME"""
+
eval_issue_labels: Optional[List[str]] = None
"""Labels derived from evaluation scores"""
@@ -74,6 +105,9 @@ class QueryLogRetrieveResponse(BaseModel):
evaluated_response: Optional[str] = None
"""The response being evaluated from the RAG system (before any remediation)"""
+ guardrail_evals: Optional[List[str]] = None
+ """Evals that should trigger guardrail"""
+
guardrailed: Optional[bool] = None
"""If true, the response was guardrailed"""
diff --git a/src/codex/types/projects/remediation_list_resolved_logs_response.py b/src/codex/types/projects/remediation_list_resolved_logs_response.py
index 4f9682b..b2315aa 100644
--- a/src/codex/types/projects/remediation_list_resolved_logs_response.py
+++ b/src/codex/types/projects/remediation_list_resolved_logs_response.py
@@ -6,7 +6,32 @@
from ..._models import BaseModel
-__all__ = ["RemediationListResolvedLogsResponse", "QueryLog", "QueryLogContext"]
+__all__ = [
+ "RemediationListResolvedLogsResponse",
+ "QueryLog",
+ "QueryLogFormattedEscalationEvalScores",
+ "QueryLogFormattedEvalScores",
+ "QueryLogFormattedGuardrailEvalScores",
+ "QueryLogContext",
+]
+
+
+class QueryLogFormattedEscalationEvalScores(BaseModel):
+ score: float
+
+ status: Literal["pass", "fail"]
+
+
+class QueryLogFormattedEvalScores(BaseModel):
+ score: float
+
+ status: Literal["pass", "fail"]
+
+
+class QueryLogFormattedGuardrailEvalScores(BaseModel):
+ score: float
+
+ status: Literal["pass", "fail"]
class QueryLogContext(BaseModel):
@@ -31,7 +56,9 @@ class QueryLog(BaseModel):
created_at: datetime
- formatted_eval_scores: Optional[Dict[str, Dict[str, Union[float, Literal["pass", "fail"]]]]] = None
+ formatted_escalation_eval_scores: Optional[Dict[str, QueryLogFormattedEscalationEvalScores]] = None
+
+ formatted_eval_scores: Optional[Dict[str, QueryLogFormattedEvalScores]] = None
"""Format evaluation scores for frontend display with pass/fail status.
Returns: Dictionary mapping eval keys to their formatted representation: {
@@ -39,6 +66,8 @@ class QueryLog(BaseModel):
eval_scores is None.
"""
+ formatted_guardrail_eval_scores: Optional[Dict[str, QueryLogFormattedGuardrailEvalScores]] = None
+
is_bad_response: bool
project_id: str
@@ -62,6 +91,9 @@ class QueryLog(BaseModel):
escalated: Optional[bool] = None
"""If true, the question was escalated to Codex for an SME to review"""
+ escalation_evals: Optional[List[str]] = None
+ """Evals that should trigger escalation to SME"""
+
eval_issue_labels: Optional[List[str]] = None
"""Labels derived from evaluation scores"""
@@ -74,6 +106,9 @@ class QueryLog(BaseModel):
evaluated_response: Optional[str] = None
"""The response being evaluated from the RAG system (before any remediation)"""
+ guardrail_evals: Optional[List[str]] = None
+ """Evals that should trigger guardrail"""
+
guardrailed: Optional[bool] = None
"""If true, the response was guardrailed"""
From be06884d321ca5009c9d82346c1b74c7429f82fa Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 26 Jun 2025 00:17:35 +0000
Subject: [PATCH 02/18] feat(api): api update
---
.stats.yml | 2 +-
src/codex/resources/projects/projects.py | 20 ++++++++++----------
src/codex/types/project_update_params.py | 8 ++++----
tests/api_resources/test_projects.py | 24 ++++--------------------
4 files changed, 19 insertions(+), 35 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 9e05e79..31393e0 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,3 +1,3 @@
configured_endpoints: 65
-openapi_spec_hash: 8bc7a64933cd540d1d2499d055430832
+openapi_spec_hash: 5d686da2afda75185dc9e4190a42b75c
config_hash: 14b2643a0ec60cf326dfed00939644ff
diff --git a/src/codex/resources/projects/projects.py b/src/codex/resources/projects/projects.py
index 22b5caf..fc5a43a 100644
--- a/src/codex/resources/projects/projects.py
+++ b/src/codex/resources/projects/projects.py
@@ -212,10 +212,10 @@ def update(
self,
project_id: str,
*,
- config: project_update_params.Config,
- name: str,
- auto_clustering_enabled: bool | NotGiven = NOT_GIVEN,
+ auto_clustering_enabled: Optional[bool] | NotGiven = NOT_GIVEN,
+ config: Optional[project_update_params.Config] | NotGiven = NOT_GIVEN,
description: Optional[str] | NotGiven = NOT_GIVEN,
+ name: Optional[str] | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -241,10 +241,10 @@ def update(
f"/api/projects/{project_id}",
body=maybe_transform(
{
- "config": config,
- "name": name,
"auto_clustering_enabled": auto_clustering_enabled,
+ "config": config,
"description": description,
+ "name": name,
},
project_update_params.ProjectUpdateParams,
),
@@ -820,10 +820,10 @@ async def update(
self,
project_id: str,
*,
- config: project_update_params.Config,
- name: str,
- auto_clustering_enabled: bool | NotGiven = NOT_GIVEN,
+ auto_clustering_enabled: Optional[bool] | NotGiven = NOT_GIVEN,
+ config: Optional[project_update_params.Config] | NotGiven = NOT_GIVEN,
description: Optional[str] | NotGiven = NOT_GIVEN,
+ name: Optional[str] | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -849,10 +849,10 @@ async def update(
f"/api/projects/{project_id}",
body=await async_maybe_transform(
{
- "config": config,
- "name": name,
"auto_clustering_enabled": auto_clustering_enabled,
+ "config": config,
"description": description,
+ "name": name,
},
project_update_params.ProjectUpdateParams,
),
diff --git a/src/codex/types/project_update_params.py b/src/codex/types/project_update_params.py
index 73dad67..3e24441 100644
--- a/src/codex/types/project_update_params.py
+++ b/src/codex/types/project_update_params.py
@@ -21,14 +21,14 @@
class ProjectUpdateParams(TypedDict, total=False):
- config: Required[Config]
+ auto_clustering_enabled: Optional[bool]
- name: Required[str]
-
- auto_clustering_enabled: bool
+ config: Optional[Config]
description: Optional[str]
+ name: Optional[str]
+
class ConfigEvalConfigCustomEvalsEvals(TypedDict, total=False):
criteria: Required[str]
diff --git a/tests/api_resources/test_projects.py b/tests/api_resources/test_projects.py
index e7d7eb1..0764d9a 100644
--- a/tests/api_resources/test_projects.py
+++ b/tests/api_resources/test_projects.py
@@ -206,8 +206,6 @@ def test_path_params_retrieve(self, client: Codex) -> None:
def test_method_update(self, client: Codex) -> None:
project = client.projects.update(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- config={},
- name="name",
)
assert_matches_type(ProjectReturnSchema, project, path=["response"])
@@ -216,6 +214,7 @@ def test_method_update(self, client: Codex) -> None:
def test_method_update_with_all_params(self, client: Codex) -> None:
project = client.projects.update(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ auto_clustering_enabled=True,
config={
"clustering_use_llm_matching": True,
"eval_config": {
@@ -298,9 +297,8 @@ def test_method_update_with_all_params(self, client: Codex) -> None:
"query_use_llm_matching": True,
"upper_llm_match_distance_threshold": 0,
},
- name="name",
- auto_clustering_enabled=True,
description="description",
+ name="name",
)
assert_matches_type(ProjectReturnSchema, project, path=["response"])
@@ -309,8 +307,6 @@ def test_method_update_with_all_params(self, client: Codex) -> None:
def test_raw_response_update(self, client: Codex) -> None:
response = client.projects.with_raw_response.update(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- config={},
- name="name",
)
assert response.is_closed is True
@@ -323,8 +319,6 @@ def test_raw_response_update(self, client: Codex) -> None:
def test_streaming_response_update(self, client: Codex) -> None:
with client.projects.with_streaming_response.update(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- config={},
- name="name",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -340,8 +334,6 @@ def test_path_params_update(self, client: Codex) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
client.projects.with_raw_response.update(
project_id="",
- config={},
- name="name",
)
@pytest.mark.skip()
@@ -919,8 +911,6 @@ async def test_path_params_retrieve(self, async_client: AsyncCodex) -> None:
async def test_method_update(self, async_client: AsyncCodex) -> None:
project = await async_client.projects.update(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- config={},
- name="name",
)
assert_matches_type(ProjectReturnSchema, project, path=["response"])
@@ -929,6 +919,7 @@ async def test_method_update(self, async_client: AsyncCodex) -> None:
async def test_method_update_with_all_params(self, async_client: AsyncCodex) -> None:
project = await async_client.projects.update(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ auto_clustering_enabled=True,
config={
"clustering_use_llm_matching": True,
"eval_config": {
@@ -1011,9 +1002,8 @@ async def test_method_update_with_all_params(self, async_client: AsyncCodex) ->
"query_use_llm_matching": True,
"upper_llm_match_distance_threshold": 0,
},
- name="name",
- auto_clustering_enabled=True,
description="description",
+ name="name",
)
assert_matches_type(ProjectReturnSchema, project, path=["response"])
@@ -1022,8 +1012,6 @@ async def test_method_update_with_all_params(self, async_client: AsyncCodex) ->
async def test_raw_response_update(self, async_client: AsyncCodex) -> None:
response = await async_client.projects.with_raw_response.update(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- config={},
- name="name",
)
assert response.is_closed is True
@@ -1036,8 +1024,6 @@ async def test_raw_response_update(self, async_client: AsyncCodex) -> None:
async def test_streaming_response_update(self, async_client: AsyncCodex) -> None:
async with async_client.projects.with_streaming_response.update(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- config={},
- name="name",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -1053,8 +1039,6 @@ async def test_path_params_update(self, async_client: AsyncCodex) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
await async_client.projects.with_raw_response.update(
project_id="",
- config={},
- name="name",
)
@pytest.mark.skip()
From c5bb94059d507d64fbdba2d863d9682696100cdf Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 26 Jun 2025 21:17:43 +0000
Subject: [PATCH 03/18] codegen metadata
---
.stats.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.stats.yml b/.stats.yml
index 31393e0..3ff2f63 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,3 +1,3 @@
configured_endpoints: 65
-openapi_spec_hash: 5d686da2afda75185dc9e4190a42b75c
+openapi_spec_hash: 94969e7925542f0cc845f6e3d299ed3c
config_hash: 14b2643a0ec60cf326dfed00939644ff
From 1a5e444226c829392181d98bc06f8cfb8bf13bd9 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 27 Jun 2025 02:29:21 +0000
Subject: [PATCH 04/18] =?UTF-8?q?fix(ci):=20release-doctor=20=E2=80=94=20r?=
=?UTF-8?q?eport=20correct=20token=20name?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
bin/check-release-environment | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bin/check-release-environment b/bin/check-release-environment
index a1446a7..b845b0f 100644
--- a/bin/check-release-environment
+++ b/bin/check-release-environment
@@ -3,7 +3,7 @@
errors=()
if [ -z "${PYPI_TOKEN}" ]; then
- errors+=("The CODEX_PYPI_TOKEN secret has not been set. Please set it in either this repository's secrets or your organization secrets.")
+ errors+=("The PYPI_TOKEN secret has not been set. Please set it in either this repository's secrets or your organization secrets.")
fi
lenErrors=${#errors[@]}
From 6b590bd454e939b8453d95c239ee85be1a326909 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 28 Jun 2025 08:28:28 +0000
Subject: [PATCH 05/18] chore(ci): only run for pushes and fork pull requests
---
.github/workflows/ci.yml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 2f7778a..12f686e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -17,6 +17,7 @@ jobs:
timeout-minutes: 10
name: lint
runs-on: ${{ github.repository == 'stainless-sdks/codex-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
+ if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- uses: actions/checkout@v4
@@ -42,6 +43,7 @@ jobs:
contents: read
id-token: write
runs-on: depot-ubuntu-24.04
+ if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- uses: actions/checkout@v4
From 45d3bc05ab56d3e67d036ce84b2c9a1f2d8cfd69 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 30 Jun 2025 02:25:48 +0000
Subject: [PATCH 06/18] fix(ci): correct conditional
---
.github/workflows/ci.yml | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 12f686e..bbb722b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -36,14 +36,13 @@ jobs:
run: ./scripts/lint
upload:
- if: github.repository == 'stainless-sdks/codex-python'
+ if: github.repository == 'stainless-sdks/codex-python' && (github.event_name == 'push' || github.event.pull_request.head.repo.fork)
timeout-minutes: 10
name: upload
permissions:
contents: read
id-token: write
runs-on: depot-ubuntu-24.04
- if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- uses: actions/checkout@v4
From 31096f4820a7bfdd204b0a2d1d84ab1e36e32d0c Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 30 Jun 2025 19:17:38 +0000
Subject: [PATCH 07/18] feat(api): api update
---
.stats.yml | 2 +-
src/codex/resources/projects/query_logs.py | 88 +++++++++++++++++++
.../query_log_list_by_group_params.py | 12 +++
.../projects/query_log_list_groups_params.py | 12 +++
.../types/projects/query_log_list_params.py | 9 ++
.../api_resources/projects/test_query_logs.py | 22 +++++
6 files changed, 144 insertions(+), 1 deletion(-)
diff --git a/.stats.yml b/.stats.yml
index 3ff2f63..c509062 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,3 +1,3 @@
configured_endpoints: 65
-openapi_spec_hash: 94969e7925542f0cc845f6e3d299ed3c
+openapi_spec_hash: f63d4542b4bd1530ced013eb686cab99
config_hash: 14b2643a0ec60cf326dfed00939644ff
diff --git a/src/codex/resources/projects/query_logs.py b/src/codex/resources/projects/query_logs.py
index 32ec739..e97243e 100644
--- a/src/codex/resources/projects/query_logs.py
+++ b/src/codex/resources/projects/query_logs.py
@@ -92,9 +92,12 @@ def list(
created_at_end: Union[str, datetime, None] | NotGiven = NOT_GIVEN,
created_at_start: Union[str, datetime, None] | NotGiven = NOT_GIVEN,
custom_metadata: Optional[str] | NotGiven = NOT_GIVEN,
+ failed_evals: Optional[List[str]] | NotGiven = NOT_GIVEN,
+ guardrailed: Optional[bool] | NotGiven = NOT_GIVEN,
limit: int | NotGiven = NOT_GIVEN,
offset: int | NotGiven = NOT_GIVEN,
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
+ passed_evals: Optional[List[str]] | NotGiven = NOT_GIVEN,
primary_eval_issue: Optional[
List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "unsupported"]]
]
@@ -118,6 +121,12 @@ def list(
custom_metadata: Filter by custom metadata as JSON string: {"key1": "value1", "key2": "value2"}
+ failed_evals: Filter by evals that failed
+
+ guardrailed: Filter by guardrailed status
+
+ passed_evals: Filter by evals that passed
+
primary_eval_issue: Filter logs that have ANY of these primary evaluation issues (OR operation)
was_cache_hit: Filter by cache hit status
@@ -144,9 +153,12 @@ def list(
"created_at_end": created_at_end,
"created_at_start": created_at_start,
"custom_metadata": custom_metadata,
+ "failed_evals": failed_evals,
+ "guardrailed": guardrailed,
"limit": limit,
"offset": offset,
"order": order,
+ "passed_evals": passed_evals,
"primary_eval_issue": primary_eval_issue,
"sort": sort,
"was_cache_hit": was_cache_hit,
@@ -164,9 +176,13 @@ def list_by_group(
created_at_end: Union[str, datetime, None] | NotGiven = NOT_GIVEN,
created_at_start: Union[str, datetime, None] | NotGiven = NOT_GIVEN,
custom_metadata: Optional[str] | NotGiven = NOT_GIVEN,
+ failed_evals: Optional[List[str]] | NotGiven = NOT_GIVEN,
+ guardrailed: Optional[bool] | NotGiven = NOT_GIVEN,
limit: int | NotGiven = NOT_GIVEN,
+ needs_review: Optional[bool] | NotGiven = NOT_GIVEN,
offset: int | NotGiven = NOT_GIVEN,
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
+ passed_evals: Optional[List[str]] | NotGiven = NOT_GIVEN,
primary_eval_issue: Optional[
List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "unsupported"]]
]
@@ -191,6 +207,14 @@ def list_by_group(
custom_metadata: Filter by custom metadata as JSON string: {"key1": "value1", "key2": "value2"}
+ failed_evals: Filter by evals that failed
+
+ guardrailed: Filter by guardrailed status
+
+ needs_review: Filter logs that need review
+
+ passed_evals: Filter by evals that passed
+
primary_eval_issue: Filter logs that have ANY of these primary evaluation issues (OR operation)
remediation_ids: List of groups to list child logs for
@@ -219,9 +243,13 @@ def list_by_group(
"created_at_end": created_at_end,
"created_at_start": created_at_start,
"custom_metadata": custom_metadata,
+ "failed_evals": failed_evals,
+ "guardrailed": guardrailed,
"limit": limit,
+ "needs_review": needs_review,
"offset": offset,
"order": order,
+ "passed_evals": passed_evals,
"primary_eval_issue": primary_eval_issue,
"remediation_ids": remediation_ids,
"sort": sort,
@@ -240,9 +268,13 @@ def list_groups(
created_at_end: Union[str, datetime, None] | NotGiven = NOT_GIVEN,
created_at_start: Union[str, datetime, None] | NotGiven = NOT_GIVEN,
custom_metadata: Optional[str] | NotGiven = NOT_GIVEN,
+ failed_evals: Optional[List[str]] | NotGiven = NOT_GIVEN,
+ guardrailed: Optional[bool] | NotGiven = NOT_GIVEN,
limit: int | NotGiven = NOT_GIVEN,
+ needs_review: Optional[bool] | NotGiven = NOT_GIVEN,
offset: int | NotGiven = NOT_GIVEN,
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
+ passed_evals: Optional[List[str]] | NotGiven = NOT_GIVEN,
primary_eval_issue: Optional[
List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "unsupported"]]
]
@@ -267,6 +299,14 @@ def list_groups(
custom_metadata: Filter by custom metadata as JSON string: {"key1": "value1", "key2": "value2"}
+ failed_evals: Filter by evals that failed
+
+ guardrailed: Filter by guardrailed status
+
+ needs_review: Filter log groups that need review
+
+ passed_evals: Filter by evals that passed
+
primary_eval_issue: Filter logs that have ANY of these primary evaluation issues (OR operation)
was_cache_hit: Filter by cache hit status
@@ -293,9 +333,13 @@ def list_groups(
"created_at_end": created_at_end,
"created_at_start": created_at_start,
"custom_metadata": custom_metadata,
+ "failed_evals": failed_evals,
+ "guardrailed": guardrailed,
"limit": limit,
+ "needs_review": needs_review,
"offset": offset,
"order": order,
+ "passed_evals": passed_evals,
"primary_eval_issue": primary_eval_issue,
"sort": sort,
"was_cache_hit": was_cache_hit,
@@ -406,9 +450,12 @@ async def list(
created_at_end: Union[str, datetime, None] | NotGiven = NOT_GIVEN,
created_at_start: Union[str, datetime, None] | NotGiven = NOT_GIVEN,
custom_metadata: Optional[str] | NotGiven = NOT_GIVEN,
+ failed_evals: Optional[List[str]] | NotGiven = NOT_GIVEN,
+ guardrailed: Optional[bool] | NotGiven = NOT_GIVEN,
limit: int | NotGiven = NOT_GIVEN,
offset: int | NotGiven = NOT_GIVEN,
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
+ passed_evals: Optional[List[str]] | NotGiven = NOT_GIVEN,
primary_eval_issue: Optional[
List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "unsupported"]]
]
@@ -432,6 +479,12 @@ async def list(
custom_metadata: Filter by custom metadata as JSON string: {"key1": "value1", "key2": "value2"}
+ failed_evals: Filter by evals that failed
+
+ guardrailed: Filter by guardrailed status
+
+ passed_evals: Filter by evals that passed
+
primary_eval_issue: Filter logs that have ANY of these primary evaluation issues (OR operation)
was_cache_hit: Filter by cache hit status
@@ -458,9 +511,12 @@ async def list(
"created_at_end": created_at_end,
"created_at_start": created_at_start,
"custom_metadata": custom_metadata,
+ "failed_evals": failed_evals,
+ "guardrailed": guardrailed,
"limit": limit,
"offset": offset,
"order": order,
+ "passed_evals": passed_evals,
"primary_eval_issue": primary_eval_issue,
"sort": sort,
"was_cache_hit": was_cache_hit,
@@ -478,9 +534,13 @@ async def list_by_group(
created_at_end: Union[str, datetime, None] | NotGiven = NOT_GIVEN,
created_at_start: Union[str, datetime, None] | NotGiven = NOT_GIVEN,
custom_metadata: Optional[str] | NotGiven = NOT_GIVEN,
+ failed_evals: Optional[List[str]] | NotGiven = NOT_GIVEN,
+ guardrailed: Optional[bool] | NotGiven = NOT_GIVEN,
limit: int | NotGiven = NOT_GIVEN,
+ needs_review: Optional[bool] | NotGiven = NOT_GIVEN,
offset: int | NotGiven = NOT_GIVEN,
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
+ passed_evals: Optional[List[str]] | NotGiven = NOT_GIVEN,
primary_eval_issue: Optional[
List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "unsupported"]]
]
@@ -505,6 +565,14 @@ async def list_by_group(
custom_metadata: Filter by custom metadata as JSON string: {"key1": "value1", "key2": "value2"}
+ failed_evals: Filter by evals that failed
+
+ guardrailed: Filter by guardrailed status
+
+ needs_review: Filter logs that need review
+
+ passed_evals: Filter by evals that passed
+
primary_eval_issue: Filter logs that have ANY of these primary evaluation issues (OR operation)
remediation_ids: List of groups to list child logs for
@@ -533,9 +601,13 @@ async def list_by_group(
"created_at_end": created_at_end,
"created_at_start": created_at_start,
"custom_metadata": custom_metadata,
+ "failed_evals": failed_evals,
+ "guardrailed": guardrailed,
"limit": limit,
+ "needs_review": needs_review,
"offset": offset,
"order": order,
+ "passed_evals": passed_evals,
"primary_eval_issue": primary_eval_issue,
"remediation_ids": remediation_ids,
"sort": sort,
@@ -554,9 +626,13 @@ async def list_groups(
created_at_end: Union[str, datetime, None] | NotGiven = NOT_GIVEN,
created_at_start: Union[str, datetime, None] | NotGiven = NOT_GIVEN,
custom_metadata: Optional[str] | NotGiven = NOT_GIVEN,
+ failed_evals: Optional[List[str]] | NotGiven = NOT_GIVEN,
+ guardrailed: Optional[bool] | NotGiven = NOT_GIVEN,
limit: int | NotGiven = NOT_GIVEN,
+ needs_review: Optional[bool] | NotGiven = NOT_GIVEN,
offset: int | NotGiven = NOT_GIVEN,
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
+ passed_evals: Optional[List[str]] | NotGiven = NOT_GIVEN,
primary_eval_issue: Optional[
List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "unsupported"]]
]
@@ -581,6 +657,14 @@ async def list_groups(
custom_metadata: Filter by custom metadata as JSON string: {"key1": "value1", "key2": "value2"}
+ failed_evals: Filter by evals that failed
+
+ guardrailed: Filter by guardrailed status
+
+ needs_review: Filter log groups that need review
+
+ passed_evals: Filter by evals that passed
+
primary_eval_issue: Filter logs that have ANY of these primary evaluation issues (OR operation)
was_cache_hit: Filter by cache hit status
@@ -607,9 +691,13 @@ async def list_groups(
"created_at_end": created_at_end,
"created_at_start": created_at_start,
"custom_metadata": custom_metadata,
+ "failed_evals": failed_evals,
+ "guardrailed": guardrailed,
"limit": limit,
+ "needs_review": needs_review,
"offset": offset,
"order": order,
+ "passed_evals": passed_evals,
"primary_eval_issue": primary_eval_issue,
"sort": sort,
"was_cache_hit": was_cache_hit,
diff --git a/src/codex/types/projects/query_log_list_by_group_params.py b/src/codex/types/projects/query_log_list_by_group_params.py
index 66166a1..b44970a 100644
--- a/src/codex/types/projects/query_log_list_by_group_params.py
+++ b/src/codex/types/projects/query_log_list_by_group_params.py
@@ -21,12 +21,24 @@ class QueryLogListByGroupParams(TypedDict, total=False):
custom_metadata: Optional[str]
"""Filter by custom metadata as JSON string: {"key1": "value1", "key2": "value2"}"""
+ failed_evals: Optional[List[str]]
+ """Filter by evals that failed"""
+
+ guardrailed: Optional[bool]
+ """Filter by guardrailed status"""
+
limit: int
+ needs_review: Optional[bool]
+ """Filter logs that need review"""
+
offset: int
order: Literal["asc", "desc"]
+ passed_evals: Optional[List[str]]
+ """Filter by evals that passed"""
+
primary_eval_issue: Optional[
List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "unsupported"]]
]
diff --git a/src/codex/types/projects/query_log_list_groups_params.py b/src/codex/types/projects/query_log_list_groups_params.py
index 558ac0b..94d549f 100644
--- a/src/codex/types/projects/query_log_list_groups_params.py
+++ b/src/codex/types/projects/query_log_list_groups_params.py
@@ -21,12 +21,24 @@ class QueryLogListGroupsParams(TypedDict, total=False):
custom_metadata: Optional[str]
"""Filter by custom metadata as JSON string: {"key1": "value1", "key2": "value2"}"""
+ failed_evals: Optional[List[str]]
+ """Filter by evals that failed"""
+
+ guardrailed: Optional[bool]
+ """Filter by guardrailed status"""
+
limit: int
+ needs_review: Optional[bool]
+ """Filter log groups that need review"""
+
offset: int
order: Literal["asc", "desc"]
+ passed_evals: Optional[List[str]]
+ """Filter by evals that passed"""
+
primary_eval_issue: Optional[
List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "unsupported"]]
]
diff --git a/src/codex/types/projects/query_log_list_params.py b/src/codex/types/projects/query_log_list_params.py
index 9cf3211..0f72b24 100644
--- a/src/codex/types/projects/query_log_list_params.py
+++ b/src/codex/types/projects/query_log_list_params.py
@@ -21,12 +21,21 @@ class QueryLogListParams(TypedDict, total=False):
custom_metadata: Optional[str]
"""Filter by custom metadata as JSON string: {"key1": "value1", "key2": "value2"}"""
+ failed_evals: Optional[List[str]]
+ """Filter by evals that failed"""
+
+ guardrailed: Optional[bool]
+ """Filter by guardrailed status"""
+
limit: int
offset: int
order: Literal["asc", "desc"]
+ passed_evals: Optional[List[str]]
+ """Filter by evals that passed"""
+
primary_eval_issue: Optional[
List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "unsupported"]]
]
diff --git a/tests/api_resources/projects/test_query_logs.py b/tests/api_resources/projects/test_query_logs.py
index d75dcab..68d78ce 100644
--- a/tests/api_resources/projects/test_query_logs.py
+++ b/tests/api_resources/projects/test_query_logs.py
@@ -92,9 +92,12 @@ def test_method_list_with_all_params(self, client: Codex) -> None:
created_at_end=parse_datetime("2019-12-27T18:11:19.117Z"),
created_at_start=parse_datetime("2019-12-27T18:11:19.117Z"),
custom_metadata="custom_metadata",
+ failed_evals=["string"],
+ guardrailed=True,
limit=1,
offset=0,
order="asc",
+ passed_evals=["string"],
primary_eval_issue=["hallucination"],
sort="created_at",
was_cache_hit=True,
@@ -151,9 +154,13 @@ def test_method_list_by_group_with_all_params(self, client: Codex) -> None:
created_at_end=parse_datetime("2019-12-27T18:11:19.117Z"),
created_at_start=parse_datetime("2019-12-27T18:11:19.117Z"),
custom_metadata="custom_metadata",
+ failed_evals=["string"],
+ guardrailed=True,
limit=1,
+ needs_review=True,
offset=0,
order="asc",
+ passed_evals=["string"],
primary_eval_issue=["hallucination"],
remediation_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
sort="created_at",
@@ -211,9 +218,13 @@ def test_method_list_groups_with_all_params(self, client: Codex) -> None:
created_at_end=parse_datetime("2019-12-27T18:11:19.117Z"),
created_at_start=parse_datetime("2019-12-27T18:11:19.117Z"),
custom_metadata="custom_metadata",
+ failed_evals=["string"],
+ guardrailed=True,
limit=1,
+ needs_review=True,
offset=0,
order="asc",
+ passed_evals=["string"],
primary_eval_issue=["hallucination"],
sort="created_at",
was_cache_hit=True,
@@ -380,9 +391,12 @@ async def test_method_list_with_all_params(self, async_client: AsyncCodex) -> No
created_at_end=parse_datetime("2019-12-27T18:11:19.117Z"),
created_at_start=parse_datetime("2019-12-27T18:11:19.117Z"),
custom_metadata="custom_metadata",
+ failed_evals=["string"],
+ guardrailed=True,
limit=1,
offset=0,
order="asc",
+ passed_evals=["string"],
primary_eval_issue=["hallucination"],
sort="created_at",
was_cache_hit=True,
@@ -439,9 +453,13 @@ async def test_method_list_by_group_with_all_params(self, async_client: AsyncCod
created_at_end=parse_datetime("2019-12-27T18:11:19.117Z"),
created_at_start=parse_datetime("2019-12-27T18:11:19.117Z"),
custom_metadata="custom_metadata",
+ failed_evals=["string"],
+ guardrailed=True,
limit=1,
+ needs_review=True,
offset=0,
order="asc",
+ passed_evals=["string"],
primary_eval_issue=["hallucination"],
remediation_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
sort="created_at",
@@ -499,9 +517,13 @@ async def test_method_list_groups_with_all_params(self, async_client: AsyncCodex
created_at_end=parse_datetime("2019-12-27T18:11:19.117Z"),
created_at_start=parse_datetime("2019-12-27T18:11:19.117Z"),
custom_metadata="custom_metadata",
+ failed_evals=["string"],
+ guardrailed=True,
limit=1,
+ needs_review=True,
offset=0,
order="asc",
+ passed_evals=["string"],
primary_eval_issue=["hallucination"],
sort="created_at",
was_cache_hit=True,
From 0207b98b34d0a484c6701d04e32ef56190936201 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 7 Jul 2025 23:35:58 +0000
Subject: [PATCH 08/18] feat(api): api update
---
.stats.yml | 4 +-
api.md | 32 -
src/codex/resources/projects/__init__.py | 28 -
src/codex/resources/projects/clusters.py | 332 ------
src/codex/resources/projects/entries.py | 948 ---------------
src/codex/resources/projects/projects.py | 64 --
src/codex/types/projects/__init__.py | 10 -
.../types/projects/cluster_list_params.py | 34 -
.../types/projects/cluster_list_response.py | 214 ----
.../cluster_list_variants_response.py | 14 -
src/codex/types/projects/entry.py | 210 ----
.../types/projects/entry_create_params.py | 28 -
.../types/projects/entry_notify_sme_params.py | 30 -
.../projects/entry_notify_sme_response.py | 13 -
.../types/projects/entry_query_params.py | 300 -----
.../types/projects/entry_query_response.py | 194 ----
.../types/projects/entry_update_params.py | 18 -
.../query_log_list_by_group_response.py | 4 +
.../query_log_list_groups_response.py | 2 +-
.../projects/query_log_retrieve_response.py | 4 +
tests/api_resources/projects/test_clusters.py | 247 ----
tests/api_resources/projects/test_entries.py | 1014 -----------------
22 files changed, 11 insertions(+), 3733 deletions(-)
delete mode 100644 src/codex/resources/projects/clusters.py
delete mode 100644 src/codex/resources/projects/entries.py
delete mode 100644 src/codex/types/projects/cluster_list_params.py
delete mode 100644 src/codex/types/projects/cluster_list_response.py
delete mode 100644 src/codex/types/projects/cluster_list_variants_response.py
delete mode 100644 src/codex/types/projects/entry.py
delete mode 100644 src/codex/types/projects/entry_create_params.py
delete mode 100644 src/codex/types/projects/entry_notify_sme_params.py
delete mode 100644 src/codex/types/projects/entry_notify_sme_response.py
delete mode 100644 src/codex/types/projects/entry_query_params.py
delete mode 100644 src/codex/types/projects/entry_query_response.py
delete mode 100644 src/codex/types/projects/entry_update_params.py
delete mode 100644 tests/api_resources/projects/test_clusters.py
delete mode 100644 tests/api_resources/projects/test_entries.py
diff --git a/.stats.yml b/.stats.yml
index c509062..cc72a8a 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,3 +1,3 @@
-configured_endpoints: 65
-openapi_spec_hash: f63d4542b4bd1530ced013eb686cab99
+configured_endpoints: 55
+openapi_spec_hash: b2b026661b19d060e5eac490807fe445
config_hash: 14b2643a0ec60cf326dfed00939644ff
diff --git a/api.md b/api.md
index 13e8214..ba4dfd6 100644
--- a/api.md
+++ b/api.md
@@ -180,38 +180,6 @@ Methods:
- client.projects.access_keys.retrieve_project_id() -> AccessKeyRetrieveProjectIDResponse
- client.projects.access_keys.revoke(access_key_id, \*, project_id) -> None
-## Entries
-
-Types:
-
-```python
-from codex.types.projects import Entry, EntryNotifySmeResponse, EntryQueryResponse
-```
-
-Methods:
-
-- client.projects.entries.create(project_id, \*\*params) -> Entry
-- client.projects.entries.retrieve(entry_id, \*, project_id) -> Entry
-- client.projects.entries.update(entry_id, \*, project_id, \*\*params) -> Entry
-- client.projects.entries.delete(entry_id, \*, project_id) -> None
-- client.projects.entries.notify_sme(entry_id, \*, project_id, \*\*params) -> EntryNotifySmeResponse
-- client.projects.entries.publish_draft_answer(entry_id, \*, project_id) -> Entry
-- client.projects.entries.query(project_id, \*\*params) -> EntryQueryResponse
-- client.projects.entries.unpublish_answer(entry_id, \*, project_id) -> Entry
-
-## Clusters
-
-Types:
-
-```python
-from codex.types.projects import ClusterListResponse, ClusterListVariantsResponse
-```
-
-Methods:
-
-- client.projects.clusters.list(project_id, \*\*params) -> SyncOffsetPageClusters[ClusterListResponse]
-- client.projects.clusters.list_variants(representative_entry_id, \*, project_id) -> ClusterListVariantsResponse
-
## Evals
Types:
diff --git a/src/codex/resources/projects/__init__.py b/src/codex/resources/projects/__init__.py
index 178855a..c1627d2 100644
--- a/src/codex/resources/projects/__init__.py
+++ b/src/codex/resources/projects/__init__.py
@@ -8,22 +8,6 @@
EvalsResourceWithStreamingResponse,
AsyncEvalsResourceWithStreamingResponse,
)
-from .entries import (
- EntriesResource,
- AsyncEntriesResource,
- EntriesResourceWithRawResponse,
- AsyncEntriesResourceWithRawResponse,
- EntriesResourceWithStreamingResponse,
- AsyncEntriesResourceWithStreamingResponse,
-)
-from .clusters import (
- ClustersResource,
- AsyncClustersResource,
- ClustersResourceWithRawResponse,
- AsyncClustersResourceWithRawResponse,
- ClustersResourceWithStreamingResponse,
- AsyncClustersResourceWithStreamingResponse,
-)
from .projects import (
ProjectsResource,
AsyncProjectsResource,
@@ -64,18 +48,6 @@
"AsyncAccessKeysResourceWithRawResponse",
"AccessKeysResourceWithStreamingResponse",
"AsyncAccessKeysResourceWithStreamingResponse",
- "EntriesResource",
- "AsyncEntriesResource",
- "EntriesResourceWithRawResponse",
- "AsyncEntriesResourceWithRawResponse",
- "EntriesResourceWithStreamingResponse",
- "AsyncEntriesResourceWithStreamingResponse",
- "ClustersResource",
- "AsyncClustersResource",
- "ClustersResourceWithRawResponse",
- "AsyncClustersResourceWithRawResponse",
- "ClustersResourceWithStreamingResponse",
- "AsyncClustersResourceWithStreamingResponse",
"EvalsResource",
"AsyncEvalsResource",
"EvalsResourceWithRawResponse",
diff --git a/src/codex/resources/projects/clusters.py b/src/codex/resources/projects/clusters.py
deleted file mode 100644
index 9712464..0000000
--- a/src/codex/resources/projects/clusters.py
+++ /dev/null
@@ -1,332 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import List, Optional
-from typing_extensions import Literal
-
-import httpx
-
-from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven
-from ..._utils import maybe_transform
-from ..._compat import cached_property
-from ..._resource import SyncAPIResource, AsyncAPIResource
-from ..._response import (
- to_raw_response_wrapper,
- to_streamed_response_wrapper,
- async_to_raw_response_wrapper,
- async_to_streamed_response_wrapper,
-)
-from ...pagination import SyncOffsetPageClusters, AsyncOffsetPageClusters
-from ..._base_client import AsyncPaginator, make_request_options
-from ...types.projects import cluster_list_params
-from ...types.projects.cluster_list_response import ClusterListResponse
-from ...types.projects.cluster_list_variants_response import ClusterListVariantsResponse
-
-__all__ = ["ClustersResource", "AsyncClustersResource"]
-
-
-class ClustersResource(SyncAPIResource):
- @cached_property
- def with_raw_response(self) -> ClustersResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/cleanlab/codex-python#accessing-raw-response-data-eg-headers
- """
- return ClustersResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> ClustersResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/cleanlab/codex-python#with_streaming_response
- """
- return ClustersResourceWithStreamingResponse(self)
-
- def list(
- self,
- project_id: str,
- *,
- eval_issue_types: List[
- Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "unsupported"]
- ]
- | NotGiven = NOT_GIVEN,
- instruction_adherence_failure: Optional[Literal["html_format", "content_structure"]] | NotGiven = NOT_GIVEN,
- limit: int | NotGiven = NOT_GIVEN,
- offset: int | NotGiven = NOT_GIVEN,
- order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
- sort: Optional[
- Literal[
- "created_at",
- "answered_at",
- "cluster_frequency_count",
- "custom_rank",
- "eval_score",
- "html_format_score",
- "content_structure_score",
- ]
- ]
- | NotGiven = NOT_GIVEN,
- states: List[Literal["unanswered", "draft", "published", "published_with_draft"]] | NotGiven = NOT_GIVEN,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> SyncOffsetPageClusters[ClusterListResponse]:
- """
- List knowledge entries for a project.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not project_id:
- raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- return self._get_api_list(
- f"/api/projects/{project_id}/entries/clusters",
- page=SyncOffsetPageClusters[ClusterListResponse],
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "eval_issue_types": eval_issue_types,
- "instruction_adherence_failure": instruction_adherence_failure,
- "limit": limit,
- "offset": offset,
- "order": order,
- "sort": sort,
- "states": states,
- },
- cluster_list_params.ClusterListParams,
- ),
- ),
- model=ClusterListResponse,
- )
-
- def list_variants(
- self,
- representative_entry_id: str,
- *,
- project_id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> ClusterListVariantsResponse:
- """
- Get Cluster Variants Route
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not project_id:
- raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- if not representative_entry_id:
- raise ValueError(
- f"Expected a non-empty value for `representative_entry_id` but received {representative_entry_id!r}"
- )
- return self._get(
- f"/api/projects/{project_id}/entries/clusters/{representative_entry_id}",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ClusterListVariantsResponse,
- )
-
-
-class AsyncClustersResource(AsyncAPIResource):
- @cached_property
- def with_raw_response(self) -> AsyncClustersResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/cleanlab/codex-python#accessing-raw-response-data-eg-headers
- """
- return AsyncClustersResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncClustersResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/cleanlab/codex-python#with_streaming_response
- """
- return AsyncClustersResourceWithStreamingResponse(self)
-
- def list(
- self,
- project_id: str,
- *,
- eval_issue_types: List[
- Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "unsupported"]
- ]
- | NotGiven = NOT_GIVEN,
- instruction_adherence_failure: Optional[Literal["html_format", "content_structure"]] | NotGiven = NOT_GIVEN,
- limit: int | NotGiven = NOT_GIVEN,
- offset: int | NotGiven = NOT_GIVEN,
- order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
- sort: Optional[
- Literal[
- "created_at",
- "answered_at",
- "cluster_frequency_count",
- "custom_rank",
- "eval_score",
- "html_format_score",
- "content_structure_score",
- ]
- ]
- | NotGiven = NOT_GIVEN,
- states: List[Literal["unanswered", "draft", "published", "published_with_draft"]] | NotGiven = NOT_GIVEN,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> AsyncPaginator[ClusterListResponse, AsyncOffsetPageClusters[ClusterListResponse]]:
- """
- List knowledge entries for a project.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not project_id:
- raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- return self._get_api_list(
- f"/api/projects/{project_id}/entries/clusters",
- page=AsyncOffsetPageClusters[ClusterListResponse],
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "eval_issue_types": eval_issue_types,
- "instruction_adherence_failure": instruction_adherence_failure,
- "limit": limit,
- "offset": offset,
- "order": order,
- "sort": sort,
- "states": states,
- },
- cluster_list_params.ClusterListParams,
- ),
- ),
- model=ClusterListResponse,
- )
-
- async def list_variants(
- self,
- representative_entry_id: str,
- *,
- project_id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> ClusterListVariantsResponse:
- """
- Get Cluster Variants Route
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not project_id:
- raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- if not representative_entry_id:
- raise ValueError(
- f"Expected a non-empty value for `representative_entry_id` but received {representative_entry_id!r}"
- )
- return await self._get(
- f"/api/projects/{project_id}/entries/clusters/{representative_entry_id}",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ClusterListVariantsResponse,
- )
-
-
-class ClustersResourceWithRawResponse:
- def __init__(self, clusters: ClustersResource) -> None:
- self._clusters = clusters
-
- self.list = to_raw_response_wrapper(
- clusters.list,
- )
- self.list_variants = to_raw_response_wrapper(
- clusters.list_variants,
- )
-
-
-class AsyncClustersResourceWithRawResponse:
- def __init__(self, clusters: AsyncClustersResource) -> None:
- self._clusters = clusters
-
- self.list = async_to_raw_response_wrapper(
- clusters.list,
- )
- self.list_variants = async_to_raw_response_wrapper(
- clusters.list_variants,
- )
-
-
-class ClustersResourceWithStreamingResponse:
- def __init__(self, clusters: ClustersResource) -> None:
- self._clusters = clusters
-
- self.list = to_streamed_response_wrapper(
- clusters.list,
- )
- self.list_variants = to_streamed_response_wrapper(
- clusters.list_variants,
- )
-
-
-class AsyncClustersResourceWithStreamingResponse:
- def __init__(self, clusters: AsyncClustersResource) -> None:
- self._clusters = clusters
-
- self.list = async_to_streamed_response_wrapper(
- clusters.list,
- )
- self.list_variants = async_to_streamed_response_wrapper(
- clusters.list_variants,
- )
diff --git a/src/codex/resources/projects/entries.py b/src/codex/resources/projects/entries.py
deleted file mode 100644
index c6b43a4..0000000
--- a/src/codex/resources/projects/entries.py
+++ /dev/null
@@ -1,948 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import typing_extensions
-from typing import Iterable, Optional
-
-import httpx
-
-from ..._types import NOT_GIVEN, Body, Query, Headers, NoneType, NotGiven
-from ..._utils import maybe_transform, strip_not_given, async_maybe_transform
-from ..._compat import cached_property
-from ..._resource import SyncAPIResource, AsyncAPIResource
-from ..._response import (
- to_raw_response_wrapper,
- to_streamed_response_wrapper,
- async_to_raw_response_wrapper,
- async_to_streamed_response_wrapper,
-)
-from ..._base_client import make_request_options
-from ...types.projects import entry_query_params, entry_create_params, entry_update_params, entry_notify_sme_params
-from ...types.projects.entry import Entry
-from ...types.projects.entry_query_response import EntryQueryResponse
-from ...types.projects.entry_notify_sme_response import EntryNotifySmeResponse
-
-__all__ = ["EntriesResource", "AsyncEntriesResource"]
-
-
-class EntriesResource(SyncAPIResource):
- @cached_property
- def with_raw_response(self) -> EntriesResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/cleanlab/codex-python#accessing-raw-response-data-eg-headers
- """
- return EntriesResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> EntriesResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/cleanlab/codex-python#with_streaming_response
- """
- return EntriesResourceWithStreamingResponse(self)
-
- def create(
- self,
- project_id: str,
- *,
- question: str,
- answer: Optional[str] | NotGiven = NOT_GIVEN,
- client_query_metadata: Iterable[object] | NotGiven = NOT_GIVEN,
- draft_answer: Optional[str] | NotGiven = NOT_GIVEN,
- x_client_library_version: str | NotGiven = NOT_GIVEN,
- x_integration_type: str | NotGiven = NOT_GIVEN,
- x_source: str | NotGiven = NOT_GIVEN,
- x_stainless_package_version: str | NotGiven = NOT_GIVEN,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> Entry:
- """
- Create a new knowledge entry for a project.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not project_id:
- raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- extra_headers = {
- **strip_not_given(
- {
- "x-client-library-version": x_client_library_version,
- "x-integration-type": x_integration_type,
- "x-source": x_source,
- "x-stainless-package-version": x_stainless_package_version,
- }
- ),
- **(extra_headers or {}),
- }
- return self._post(
- f"/api/projects/{project_id}/entries/",
- body=maybe_transform(
- {
- "question": question,
- "answer": answer,
- "client_query_metadata": client_query_metadata,
- "draft_answer": draft_answer,
- },
- entry_create_params.EntryCreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=Entry,
- )
-
- def retrieve(
- self,
- entry_id: str,
- *,
- project_id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> Entry:
- """
- Get a knowledge entry for a project.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not project_id:
- raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- if not entry_id:
- raise ValueError(f"Expected a non-empty value for `entry_id` but received {entry_id!r}")
- return self._get(
- f"/api/projects/{project_id}/entries/{entry_id}",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=Entry,
- )
-
- def update(
- self,
- entry_id: str,
- *,
- project_id: str,
- answer: Optional[str] | NotGiven = NOT_GIVEN,
- draft_answer: Optional[str] | NotGiven = NOT_GIVEN,
- question: Optional[str] | NotGiven = NOT_GIVEN,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> Entry:
- """
- Update a knowledge entry for a project.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not project_id:
- raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- if not entry_id:
- raise ValueError(f"Expected a non-empty value for `entry_id` but received {entry_id!r}")
- return self._put(
- f"/api/projects/{project_id}/entries/{entry_id}",
- body=maybe_transform(
- {
- "answer": answer,
- "draft_answer": draft_answer,
- "question": question,
- },
- entry_update_params.EntryUpdateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=Entry,
- )
-
- def delete(
- self,
- entry_id: str,
- *,
- project_id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> None:
- """
- Delete a knowledge entry for a project.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not project_id:
- raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- if not entry_id:
- raise ValueError(f"Expected a non-empty value for `entry_id` but received {entry_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return self._delete(
- f"/api/projects/{project_id}/entries/{entry_id}",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- def notify_sme(
- self,
- entry_id: str,
- *,
- project_id: str,
- email: str,
- view_context: entry_notify_sme_params.ViewContext,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> EntryNotifySmeResponse:
- """
- Notify a subject matter expert to review and answer a specific entry.
-
- Returns: SMENotificationResponse with status and notification details
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not project_id:
- raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- if not entry_id:
- raise ValueError(f"Expected a non-empty value for `entry_id` but received {entry_id!r}")
- return self._post(
- f"/api/projects/{project_id}/entries/{entry_id}/notifications",
- body=maybe_transform(
- {
- "email": email,
- "view_context": view_context,
- },
- entry_notify_sme_params.EntryNotifySmeParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=EntryNotifySmeResponse,
- )
-
- def publish_draft_answer(
- self,
- entry_id: str,
- *,
- project_id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> Entry:
- """Promote a draft answer to a published answer for a knowledge entry.
-
- This always
- results in the entry's draft answer being removed. If the entry already has a
- published answer, it will be overwritten and permanently lost.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not project_id:
- raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- if not entry_id:
- raise ValueError(f"Expected a non-empty value for `entry_id` but received {entry_id!r}")
- return self._put(
- f"/api/projects/{project_id}/entries/{entry_id}/publish_draft_answer",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=Entry,
- )
-
- @typing_extensions.deprecated("deprecated")
- def query(
- self,
- project_id: str,
- *,
- question: str,
- use_llm_matching: bool | NotGiven = NOT_GIVEN,
- client_metadata: Optional[object] | NotGiven = NOT_GIVEN,
- query_metadata: Optional[entry_query_params.QueryMetadata] | NotGiven = NOT_GIVEN,
- x_client_library_version: str | NotGiven = NOT_GIVEN,
- x_integration_type: str | NotGiven = NOT_GIVEN,
- x_source: str | NotGiven = NOT_GIVEN,
- x_stainless_package_version: str | NotGiven = NOT_GIVEN,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> EntryQueryResponse:
- """
- Query Entries Route
-
- Args:
- client_metadata: Deprecated: Use query_metadata instead
-
- query_metadata: Optional logging data that can be provided by the client.
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not project_id:
- raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- extra_headers = {
- **strip_not_given(
- {
- "x-client-library-version": x_client_library_version,
- "x-integration-type": x_integration_type,
- "x-source": x_source,
- "x-stainless-package-version": x_stainless_package_version,
- }
- ),
- **(extra_headers or {}),
- }
- return self._post(
- f"/api/projects/{project_id}/entries/query",
- body=maybe_transform(
- {
- "question": question,
- "client_metadata": client_metadata,
- "query_metadata": query_metadata,
- },
- entry_query_params.EntryQueryParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform({"use_llm_matching": use_llm_matching}, entry_query_params.EntryQueryParams),
- ),
- cast_to=EntryQueryResponse,
- )
-
- def unpublish_answer(
- self,
- entry_id: str,
- *,
- project_id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> Entry:
- """Unpublish an answer for a knowledge entry.
-
- This always results in the entry's
- answer being removed. If the entry does not already have a draft answer, the
- current answer will be retained as the draft answer.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not project_id:
- raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- if not entry_id:
- raise ValueError(f"Expected a non-empty value for `entry_id` but received {entry_id!r}")
- return self._put(
- f"/api/projects/{project_id}/entries/{entry_id}/unpublish_answer",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=Entry,
- )
-
-
-class AsyncEntriesResource(AsyncAPIResource):
- @cached_property
- def with_raw_response(self) -> AsyncEntriesResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/cleanlab/codex-python#accessing-raw-response-data-eg-headers
- """
- return AsyncEntriesResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncEntriesResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/cleanlab/codex-python#with_streaming_response
- """
- return AsyncEntriesResourceWithStreamingResponse(self)
-
- async def create(
- self,
- project_id: str,
- *,
- question: str,
- answer: Optional[str] | NotGiven = NOT_GIVEN,
- client_query_metadata: Iterable[object] | NotGiven = NOT_GIVEN,
- draft_answer: Optional[str] | NotGiven = NOT_GIVEN,
- x_client_library_version: str | NotGiven = NOT_GIVEN,
- x_integration_type: str | NotGiven = NOT_GIVEN,
- x_source: str | NotGiven = NOT_GIVEN,
- x_stainless_package_version: str | NotGiven = NOT_GIVEN,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> Entry:
- """
- Create a new knowledge entry for a project.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not project_id:
- raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- extra_headers = {
- **strip_not_given(
- {
- "x-client-library-version": x_client_library_version,
- "x-integration-type": x_integration_type,
- "x-source": x_source,
- "x-stainless-package-version": x_stainless_package_version,
- }
- ),
- **(extra_headers or {}),
- }
- return await self._post(
- f"/api/projects/{project_id}/entries/",
- body=await async_maybe_transform(
- {
- "question": question,
- "answer": answer,
- "client_query_metadata": client_query_metadata,
- "draft_answer": draft_answer,
- },
- entry_create_params.EntryCreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=Entry,
- )
-
- async def retrieve(
- self,
- entry_id: str,
- *,
- project_id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> Entry:
- """
- Get a knowledge entry for a project.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not project_id:
- raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- if not entry_id:
- raise ValueError(f"Expected a non-empty value for `entry_id` but received {entry_id!r}")
- return await self._get(
- f"/api/projects/{project_id}/entries/{entry_id}",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=Entry,
- )
-
- async def update(
- self,
- entry_id: str,
- *,
- project_id: str,
- answer: Optional[str] | NotGiven = NOT_GIVEN,
- draft_answer: Optional[str] | NotGiven = NOT_GIVEN,
- question: Optional[str] | NotGiven = NOT_GIVEN,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> Entry:
- """
- Update a knowledge entry for a project.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not project_id:
- raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- if not entry_id:
- raise ValueError(f"Expected a non-empty value for `entry_id` but received {entry_id!r}")
- return await self._put(
- f"/api/projects/{project_id}/entries/{entry_id}",
- body=await async_maybe_transform(
- {
- "answer": answer,
- "draft_answer": draft_answer,
- "question": question,
- },
- entry_update_params.EntryUpdateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=Entry,
- )
-
- async def delete(
- self,
- entry_id: str,
- *,
- project_id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> None:
- """
- Delete a knowledge entry for a project.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not project_id:
- raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- if not entry_id:
- raise ValueError(f"Expected a non-empty value for `entry_id` but received {entry_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return await self._delete(
- f"/api/projects/{project_id}/entries/{entry_id}",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- async def notify_sme(
- self,
- entry_id: str,
- *,
- project_id: str,
- email: str,
- view_context: entry_notify_sme_params.ViewContext,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> EntryNotifySmeResponse:
- """
- Notify a subject matter expert to review and answer a specific entry.
-
- Returns: SMENotificationResponse with status and notification details
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not project_id:
- raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- if not entry_id:
- raise ValueError(f"Expected a non-empty value for `entry_id` but received {entry_id!r}")
- return await self._post(
- f"/api/projects/{project_id}/entries/{entry_id}/notifications",
- body=await async_maybe_transform(
- {
- "email": email,
- "view_context": view_context,
- },
- entry_notify_sme_params.EntryNotifySmeParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=EntryNotifySmeResponse,
- )
-
- async def publish_draft_answer(
- self,
- entry_id: str,
- *,
- project_id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> Entry:
- """Promote a draft answer to a published answer for a knowledge entry.
-
- This always
- results in the entry's draft answer being removed. If the entry already has a
- published answer, it will be overwritten and permanently lost.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not project_id:
- raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- if not entry_id:
- raise ValueError(f"Expected a non-empty value for `entry_id` but received {entry_id!r}")
- return await self._put(
- f"/api/projects/{project_id}/entries/{entry_id}/publish_draft_answer",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=Entry,
- )
-
- @typing_extensions.deprecated("deprecated")
- async def query(
- self,
- project_id: str,
- *,
- question: str,
- use_llm_matching: bool | NotGiven = NOT_GIVEN,
- client_metadata: Optional[object] | NotGiven = NOT_GIVEN,
- query_metadata: Optional[entry_query_params.QueryMetadata] | NotGiven = NOT_GIVEN,
- x_client_library_version: str | NotGiven = NOT_GIVEN,
- x_integration_type: str | NotGiven = NOT_GIVEN,
- x_source: str | NotGiven = NOT_GIVEN,
- x_stainless_package_version: str | NotGiven = NOT_GIVEN,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> EntryQueryResponse:
- """
- Query Entries Route
-
- Args:
- client_metadata: Deprecated: Use query_metadata instead
-
- query_metadata: Optional logging data that can be provided by the client.
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not project_id:
- raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- extra_headers = {
- **strip_not_given(
- {
- "x-client-library-version": x_client_library_version,
- "x-integration-type": x_integration_type,
- "x-source": x_source,
- "x-stainless-package-version": x_stainless_package_version,
- }
- ),
- **(extra_headers or {}),
- }
- return await self._post(
- f"/api/projects/{project_id}/entries/query",
- body=await async_maybe_transform(
- {
- "question": question,
- "client_metadata": client_metadata,
- "query_metadata": query_metadata,
- },
- entry_query_params.EntryQueryParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {"use_llm_matching": use_llm_matching}, entry_query_params.EntryQueryParams
- ),
- ),
- cast_to=EntryQueryResponse,
- )
-
- async def unpublish_answer(
- self,
- entry_id: str,
- *,
- project_id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> Entry:
- """Unpublish an answer for a knowledge entry.
-
- This always results in the entry's
- answer being removed. If the entry does not already have a draft answer, the
- current answer will be retained as the draft answer.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not project_id:
- raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- if not entry_id:
- raise ValueError(f"Expected a non-empty value for `entry_id` but received {entry_id!r}")
- return await self._put(
- f"/api/projects/{project_id}/entries/{entry_id}/unpublish_answer",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=Entry,
- )
-
-
-class EntriesResourceWithRawResponse:
- def __init__(self, entries: EntriesResource) -> None:
- self._entries = entries
-
- self.create = to_raw_response_wrapper(
- entries.create,
- )
- self.retrieve = to_raw_response_wrapper(
- entries.retrieve,
- )
- self.update = to_raw_response_wrapper(
- entries.update,
- )
- self.delete = to_raw_response_wrapper(
- entries.delete,
- )
- self.notify_sme = to_raw_response_wrapper(
- entries.notify_sme,
- )
- self.publish_draft_answer = to_raw_response_wrapper(
- entries.publish_draft_answer,
- )
- self.query = ( # pyright: ignore[reportDeprecated]
- to_raw_response_wrapper(
- entries.query # pyright: ignore[reportDeprecated],
- )
- )
- self.unpublish_answer = to_raw_response_wrapper(
- entries.unpublish_answer,
- )
-
-
-class AsyncEntriesResourceWithRawResponse:
- def __init__(self, entries: AsyncEntriesResource) -> None:
- self._entries = entries
-
- self.create = async_to_raw_response_wrapper(
- entries.create,
- )
- self.retrieve = async_to_raw_response_wrapper(
- entries.retrieve,
- )
- self.update = async_to_raw_response_wrapper(
- entries.update,
- )
- self.delete = async_to_raw_response_wrapper(
- entries.delete,
- )
- self.notify_sme = async_to_raw_response_wrapper(
- entries.notify_sme,
- )
- self.publish_draft_answer = async_to_raw_response_wrapper(
- entries.publish_draft_answer,
- )
- self.query = ( # pyright: ignore[reportDeprecated]
- async_to_raw_response_wrapper(
- entries.query # pyright: ignore[reportDeprecated],
- )
- )
- self.unpublish_answer = async_to_raw_response_wrapper(
- entries.unpublish_answer,
- )
-
-
-class EntriesResourceWithStreamingResponse:
- def __init__(self, entries: EntriesResource) -> None:
- self._entries = entries
-
- self.create = to_streamed_response_wrapper(
- entries.create,
- )
- self.retrieve = to_streamed_response_wrapper(
- entries.retrieve,
- )
- self.update = to_streamed_response_wrapper(
- entries.update,
- )
- self.delete = to_streamed_response_wrapper(
- entries.delete,
- )
- self.notify_sme = to_streamed_response_wrapper(
- entries.notify_sme,
- )
- self.publish_draft_answer = to_streamed_response_wrapper(
- entries.publish_draft_answer,
- )
- self.query = ( # pyright: ignore[reportDeprecated]
- to_streamed_response_wrapper(
- entries.query # pyright: ignore[reportDeprecated],
- )
- )
- self.unpublish_answer = to_streamed_response_wrapper(
- entries.unpublish_answer,
- )
-
-
-class AsyncEntriesResourceWithStreamingResponse:
- def __init__(self, entries: AsyncEntriesResource) -> None:
- self._entries = entries
-
- self.create = async_to_streamed_response_wrapper(
- entries.create,
- )
- self.retrieve = async_to_streamed_response_wrapper(
- entries.retrieve,
- )
- self.update = async_to_streamed_response_wrapper(
- entries.update,
- )
- self.delete = async_to_streamed_response_wrapper(
- entries.delete,
- )
- self.notify_sme = async_to_streamed_response_wrapper(
- entries.notify_sme,
- )
- self.publish_draft_answer = async_to_streamed_response_wrapper(
- entries.publish_draft_answer,
- )
- self.query = ( # pyright: ignore[reportDeprecated]
- async_to_streamed_response_wrapper(
- entries.query # pyright: ignore[reportDeprecated],
- )
- )
- self.unpublish_answer = async_to_streamed_response_wrapper(
- entries.unpublish_answer,
- )
diff --git a/src/codex/resources/projects/projects.py b/src/codex/resources/projects/projects.py
index fc5a43a..1314b7b 100644
--- a/src/codex/resources/projects/projects.py
+++ b/src/codex/resources/projects/projects.py
@@ -25,24 +25,8 @@
project_increment_queries_params,
project_retrieve_analytics_params,
)
-from .entries import (
- EntriesResource,
- AsyncEntriesResource,
- EntriesResourceWithRawResponse,
- AsyncEntriesResourceWithRawResponse,
- EntriesResourceWithStreamingResponse,
- AsyncEntriesResourceWithStreamingResponse,
-)
from ..._types import NOT_GIVEN, Body, Query, Headers, NoneType, NotGiven
from ..._utils import maybe_transform, strip_not_given, async_maybe_transform
-from .clusters import (
- ClustersResource,
- AsyncClustersResource,
- ClustersResourceWithRawResponse,
- AsyncClustersResourceWithRawResponse,
- ClustersResourceWithStreamingResponse,
- AsyncClustersResourceWithStreamingResponse,
-)
from ..._compat import cached_property
from .query_logs import (
QueryLogsResource,
@@ -91,14 +75,6 @@ class ProjectsResource(SyncAPIResource):
def access_keys(self) -> AccessKeysResource:
return AccessKeysResource(self._client)
- @cached_property
- def entries(self) -> EntriesResource:
- return EntriesResource(self._client)
-
- @cached_property
- def clusters(self) -> ClustersResource:
- return ClustersResource(self._client)
-
@cached_property
def evals(self) -> EvalsResource:
return EvalsResource(self._client)
@@ -699,14 +675,6 @@ class AsyncProjectsResource(AsyncAPIResource):
def access_keys(self) -> AsyncAccessKeysResource:
return AsyncAccessKeysResource(self._client)
- @cached_property
- def entries(self) -> AsyncEntriesResource:
- return AsyncEntriesResource(self._client)
-
- @cached_property
- def clusters(self) -> AsyncClustersResource:
- return AsyncClustersResource(self._client)
-
@cached_property
def evals(self) -> AsyncEvalsResource:
return AsyncEvalsResource(self._client)
@@ -1345,14 +1313,6 @@ def __init__(self, projects: ProjectsResource) -> None:
def access_keys(self) -> AccessKeysResourceWithRawResponse:
return AccessKeysResourceWithRawResponse(self._projects.access_keys)
- @cached_property
- def entries(self) -> EntriesResourceWithRawResponse:
- return EntriesResourceWithRawResponse(self._projects.entries)
-
- @cached_property
- def clusters(self) -> ClustersResourceWithRawResponse:
- return ClustersResourceWithRawResponse(self._projects.clusters)
-
@cached_property
def evals(self) -> EvalsResourceWithRawResponse:
return EvalsResourceWithRawResponse(self._projects.evals)
@@ -1407,14 +1367,6 @@ def __init__(self, projects: AsyncProjectsResource) -> None:
def access_keys(self) -> AsyncAccessKeysResourceWithRawResponse:
return AsyncAccessKeysResourceWithRawResponse(self._projects.access_keys)
- @cached_property
- def entries(self) -> AsyncEntriesResourceWithRawResponse:
- return AsyncEntriesResourceWithRawResponse(self._projects.entries)
-
- @cached_property
- def clusters(self) -> AsyncClustersResourceWithRawResponse:
- return AsyncClustersResourceWithRawResponse(self._projects.clusters)
-
@cached_property
def evals(self) -> AsyncEvalsResourceWithRawResponse:
return AsyncEvalsResourceWithRawResponse(self._projects.evals)
@@ -1469,14 +1421,6 @@ def __init__(self, projects: ProjectsResource) -> None:
def access_keys(self) -> AccessKeysResourceWithStreamingResponse:
return AccessKeysResourceWithStreamingResponse(self._projects.access_keys)
- @cached_property
- def entries(self) -> EntriesResourceWithStreamingResponse:
- return EntriesResourceWithStreamingResponse(self._projects.entries)
-
- @cached_property
- def clusters(self) -> ClustersResourceWithStreamingResponse:
- return ClustersResourceWithStreamingResponse(self._projects.clusters)
-
@cached_property
def evals(self) -> EvalsResourceWithStreamingResponse:
return EvalsResourceWithStreamingResponse(self._projects.evals)
@@ -1531,14 +1475,6 @@ def __init__(self, projects: AsyncProjectsResource) -> None:
def access_keys(self) -> AsyncAccessKeysResourceWithStreamingResponse:
return AsyncAccessKeysResourceWithStreamingResponse(self._projects.access_keys)
- @cached_property
- def entries(self) -> AsyncEntriesResourceWithStreamingResponse:
- return AsyncEntriesResourceWithStreamingResponse(self._projects.entries)
-
- @cached_property
- def clusters(self) -> AsyncClustersResourceWithStreamingResponse:
- return AsyncClustersResourceWithStreamingResponse(self._projects.clusters)
-
@cached_property
def evals(self) -> AsyncEvalsResourceWithStreamingResponse:
return AsyncEvalsResourceWithStreamingResponse(self._projects.evals)
diff --git a/src/codex/types/projects/__init__.py b/src/codex/types/projects/__init__.py
index 8a26aa0..4f75470 100644
--- a/src/codex/types/projects/__init__.py
+++ b/src/codex/types/projects/__init__.py
@@ -2,25 +2,16 @@
from __future__ import annotations
-from .entry import Entry as Entry
from .access_key_schema import AccessKeySchema as AccessKeySchema
-from .entry_query_params import EntryQueryParams as EntryQueryParams
from .eval_create_params import EvalCreateParams as EvalCreateParams
from .eval_list_response import EvalListResponse as EvalListResponse
from .eval_update_params import EvalUpdateParams as EvalUpdateParams
-from .cluster_list_params import ClusterListParams as ClusterListParams
-from .entry_create_params import EntryCreateParams as EntryCreateParams
-from .entry_update_params import EntryUpdateParams as EntryUpdateParams
-from .entry_query_response import EntryQueryResponse as EntryQueryResponse
-from .cluster_list_response import ClusterListResponse as ClusterListResponse
from .query_log_list_params import QueryLogListParams as QueryLogListParams
-from .entry_notify_sme_params import EntryNotifySmeParams as EntryNotifySmeParams
from .query_log_list_response import QueryLogListResponse as QueryLogListResponse
from .remediation_list_params import RemediationListParams as RemediationListParams
from .access_key_create_params import AccessKeyCreateParams as AccessKeyCreateParams
from .access_key_list_response import AccessKeyListResponse as AccessKeyListResponse
from .access_key_update_params import AccessKeyUpdateParams as AccessKeyUpdateParams
-from .entry_notify_sme_response import EntryNotifySmeResponse as EntryNotifySmeResponse
from .remediation_create_params import RemediationCreateParams as RemediationCreateParams
from .remediation_list_response import RemediationListResponse as RemediationListResponse
from .remediation_pause_response import RemediationPauseResponse as RemediationPauseResponse
@@ -30,7 +21,6 @@
from .remediation_publish_response import RemediationPublishResponse as RemediationPublishResponse
from .remediation_unpause_response import RemediationUnpauseResponse as RemediationUnpauseResponse
from .remediation_retrieve_response import RemediationRetrieveResponse as RemediationRetrieveResponse
-from .cluster_list_variants_response import ClusterListVariantsResponse as ClusterListVariantsResponse
from .query_log_list_by_group_params import QueryLogListByGroupParams as QueryLogListByGroupParams
from .query_log_list_groups_response import QueryLogListGroupsResponse as QueryLogListGroupsResponse
from .remediation_edit_answer_params import RemediationEditAnswerParams as RemediationEditAnswerParams
diff --git a/src/codex/types/projects/cluster_list_params.py b/src/codex/types/projects/cluster_list_params.py
deleted file mode 100644
index 20284d8..0000000
--- a/src/codex/types/projects/cluster_list_params.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import List, Optional
-from typing_extensions import Literal, TypedDict
-
-__all__ = ["ClusterListParams"]
-
-
-class ClusterListParams(TypedDict, total=False):
- eval_issue_types: List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "unsupported"]]
-
- instruction_adherence_failure: Optional[Literal["html_format", "content_structure"]]
-
- limit: int
-
- offset: int
-
- order: Literal["asc", "desc"]
-
- sort: Optional[
- Literal[
- "created_at",
- "answered_at",
- "cluster_frequency_count",
- "custom_rank",
- "eval_score",
- "html_format_score",
- "content_structure_score",
- ]
- ]
-
- states: List[Literal["unanswered", "draft", "published", "published_with_draft"]]
diff --git a/src/codex/types/projects/cluster_list_response.py b/src/codex/types/projects/cluster_list_response.py
deleted file mode 100644
index 1fc8bd5..0000000
--- a/src/codex/types/projects/cluster_list_response.py
+++ /dev/null
@@ -1,214 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from ..._models import BaseModel
-
-__all__ = [
- "ClusterListResponse",
- "ManagedMetadata",
- "ManagedMetadataContentStructureScores",
- "ManagedMetadataContextSufficiency",
- "ManagedMetadataHTMLFormatScores",
- "ManagedMetadataQueryEaseCustomized",
- "ManagedMetadataResponseGroundedness",
- "ManagedMetadataResponseHelpfulness",
- "ManagedMetadataTrustworthiness",
-]
-
-
-class ManagedMetadataContentStructureScores(BaseModel):
- average: Optional[float] = None
- """The average of all scores."""
-
- latest: Optional[float] = None
- """The most recent score."""
-
- max: Optional[float] = None
- """The maximum score."""
-
- min: Optional[float] = None
- """The minimum score."""
-
- scores: Optional[List[float]] = None
-
-
-class ManagedMetadataContextSufficiency(BaseModel):
- average: Optional[float] = None
- """The average of all scores."""
-
- latest: Optional[float] = None
- """The most recent score."""
-
- max: Optional[float] = None
- """The maximum score."""
-
- min: Optional[float] = None
- """The minimum score."""
-
- scores: Optional[List[float]] = None
-
-
-class ManagedMetadataHTMLFormatScores(BaseModel):
- average: Optional[float] = None
- """The average of all scores."""
-
- latest: Optional[float] = None
- """The most recent score."""
-
- max: Optional[float] = None
- """The maximum score."""
-
- min: Optional[float] = None
- """The minimum score."""
-
- scores: Optional[List[float]] = None
-
-
-class ManagedMetadataQueryEaseCustomized(BaseModel):
- average: Optional[float] = None
- """The average of all scores."""
-
- latest: Optional[float] = None
- """The most recent score."""
-
- max: Optional[float] = None
- """The maximum score."""
-
- min: Optional[float] = None
- """The minimum score."""
-
- scores: Optional[List[float]] = None
-
-
-class ManagedMetadataResponseGroundedness(BaseModel):
- average: Optional[float] = None
- """The average of all scores."""
-
- latest: Optional[float] = None
- """The most recent score."""
-
- max: Optional[float] = None
- """The maximum score."""
-
- min: Optional[float] = None
- """The minimum score."""
-
- scores: Optional[List[float]] = None
-
-
-class ManagedMetadataResponseHelpfulness(BaseModel):
- average: Optional[float] = None
- """The average of all scores."""
-
- latest: Optional[float] = None
- """The most recent score."""
-
- max: Optional[float] = None
- """The maximum score."""
-
- min: Optional[float] = None
- """The minimum score."""
-
- scores: Optional[List[float]] = None
-
-
-class ManagedMetadataTrustworthiness(BaseModel):
- average: Optional[float] = None
- """The average of all scores."""
-
- latest: Optional[float] = None
- """The most recent score."""
-
- max: Optional[float] = None
- """The maximum score."""
-
- min: Optional[float] = None
- """The minimum score."""
-
- scores: Optional[List[float]] = None
-
-
-class ManagedMetadata(BaseModel):
- latest_context: Optional[str] = None
- """The most recent context string."""
-
- latest_entry_point: Optional[str] = None
- """The most recent entry point string."""
-
- latest_llm_response: Optional[str] = None
- """The most recent LLM response string."""
-
- latest_location: Optional[str] = None
- """The most recent location string."""
-
- content_structure_scores: Optional[ManagedMetadataContentStructureScores] = None
- """Holds a list of scores and computes aggregate statistics."""
-
- context_sufficiency: Optional[ManagedMetadataContextSufficiency] = None
- """Holds a list of scores and computes aggregate statistics."""
-
- contexts: Optional[List[str]] = None
-
- entry_points: Optional[List[str]] = None
-
- html_format_scores: Optional[ManagedMetadataHTMLFormatScores] = None
- """Holds a list of scores and computes aggregate statistics."""
-
- llm_responses: Optional[List[str]] = None
-
- locations: Optional[List[str]] = None
-
- query_ease_customized: Optional[ManagedMetadataQueryEaseCustomized] = None
- """Holds a list of scores and computes aggregate statistics."""
-
- response_groundedness: Optional[ManagedMetadataResponseGroundedness] = None
- """Holds a list of scores and computes aggregate statistics."""
-
- response_helpfulness: Optional[ManagedMetadataResponseHelpfulness] = None
- """Holds a list of scores and computes aggregate statistics."""
-
- trustworthiness: Optional[ManagedMetadataTrustworthiness] = None
- """Holds a list of scores and computes aggregate statistics."""
-
-
-class ClusterListResponse(BaseModel):
- id: str
-
- cluster_frequency_count: int
-
- created_at: datetime
-
- managed_metadata: ManagedMetadata
- """Extract system-defined, managed metadata from client_query_metadata."""
-
- project_id: str
-
- question: str
-
- state: Literal["unanswered", "draft", "published", "published_with_draft"]
-
- answer: Optional[str] = None
-
- answered_at: Optional[datetime] = None
-
- client_query_metadata: Optional[List[object]] = None
-
- content_structure_score: Optional[float] = None
-
- draft_answer: Optional[str] = None
-
- draft_answer_last_edited: Optional[datetime] = None
-
- eval_issue_type: Optional[str] = None
-
- eval_score: Optional[float] = None
-
- frequency_count: Optional[int] = None
- """number of times the entry matched for a /query request"""
-
- html_format_score: Optional[float] = None
-
- representative_entry_id: Optional[str] = None
diff --git a/src/codex/types/projects/cluster_list_variants_response.py b/src/codex/types/projects/cluster_list_variants_response.py
deleted file mode 100644
index aa35905..0000000
--- a/src/codex/types/projects/cluster_list_variants_response.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List
-
-from .entry import Entry
-from ..._models import BaseModel
-
-__all__ = ["ClusterListVariantsResponse"]
-
-
-class ClusterListVariantsResponse(BaseModel):
- entries: List[Entry]
-
- total_count: int
diff --git a/src/codex/types/projects/entry.py b/src/codex/types/projects/entry.py
deleted file mode 100644
index 3f7a86d..0000000
--- a/src/codex/types/projects/entry.py
+++ /dev/null
@@ -1,210 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from ..._models import BaseModel
-
-__all__ = [
- "Entry",
- "ManagedMetadata",
- "ManagedMetadataContentStructureScores",
- "ManagedMetadataContextSufficiency",
- "ManagedMetadataHTMLFormatScores",
- "ManagedMetadataQueryEaseCustomized",
- "ManagedMetadataResponseGroundedness",
- "ManagedMetadataResponseHelpfulness",
- "ManagedMetadataTrustworthiness",
-]
-
-
-class ManagedMetadataContentStructureScores(BaseModel):
- average: Optional[float] = None
- """The average of all scores."""
-
- latest: Optional[float] = None
- """The most recent score."""
-
- max: Optional[float] = None
- """The maximum score."""
-
- min: Optional[float] = None
- """The minimum score."""
-
- scores: Optional[List[float]] = None
-
-
-class ManagedMetadataContextSufficiency(BaseModel):
- average: Optional[float] = None
- """The average of all scores."""
-
- latest: Optional[float] = None
- """The most recent score."""
-
- max: Optional[float] = None
- """The maximum score."""
-
- min: Optional[float] = None
- """The minimum score."""
-
- scores: Optional[List[float]] = None
-
-
-class ManagedMetadataHTMLFormatScores(BaseModel):
- average: Optional[float] = None
- """The average of all scores."""
-
- latest: Optional[float] = None
- """The most recent score."""
-
- max: Optional[float] = None
- """The maximum score."""
-
- min: Optional[float] = None
- """The minimum score."""
-
- scores: Optional[List[float]] = None
-
-
-class ManagedMetadataQueryEaseCustomized(BaseModel):
- average: Optional[float] = None
- """The average of all scores."""
-
- latest: Optional[float] = None
- """The most recent score."""
-
- max: Optional[float] = None
- """The maximum score."""
-
- min: Optional[float] = None
- """The minimum score."""
-
- scores: Optional[List[float]] = None
-
-
-class ManagedMetadataResponseGroundedness(BaseModel):
- average: Optional[float] = None
- """The average of all scores."""
-
- latest: Optional[float] = None
- """The most recent score."""
-
- max: Optional[float] = None
- """The maximum score."""
-
- min: Optional[float] = None
- """The minimum score."""
-
- scores: Optional[List[float]] = None
-
-
-class ManagedMetadataResponseHelpfulness(BaseModel):
- average: Optional[float] = None
- """The average of all scores."""
-
- latest: Optional[float] = None
- """The most recent score."""
-
- max: Optional[float] = None
- """The maximum score."""
-
- min: Optional[float] = None
- """The minimum score."""
-
- scores: Optional[List[float]] = None
-
-
-class ManagedMetadataTrustworthiness(BaseModel):
- average: Optional[float] = None
- """The average of all scores."""
-
- latest: Optional[float] = None
- """The most recent score."""
-
- max: Optional[float] = None
- """The maximum score."""
-
- min: Optional[float] = None
- """The minimum score."""
-
- scores: Optional[List[float]] = None
-
-
-class ManagedMetadata(BaseModel):
- latest_context: Optional[str] = None
- """The most recent context string."""
-
- latest_entry_point: Optional[str] = None
- """The most recent entry point string."""
-
- latest_llm_response: Optional[str] = None
- """The most recent LLM response string."""
-
- latest_location: Optional[str] = None
- """The most recent location string."""
-
- content_structure_scores: Optional[ManagedMetadataContentStructureScores] = None
- """Holds a list of scores and computes aggregate statistics."""
-
- context_sufficiency: Optional[ManagedMetadataContextSufficiency] = None
- """Holds a list of scores and computes aggregate statistics."""
-
- contexts: Optional[List[str]] = None
-
- entry_points: Optional[List[str]] = None
-
- html_format_scores: Optional[ManagedMetadataHTMLFormatScores] = None
- """Holds a list of scores and computes aggregate statistics."""
-
- llm_responses: Optional[List[str]] = None
-
- locations: Optional[List[str]] = None
-
- query_ease_customized: Optional[ManagedMetadataQueryEaseCustomized] = None
- """Holds a list of scores and computes aggregate statistics."""
-
- response_groundedness: Optional[ManagedMetadataResponseGroundedness] = None
- """Holds a list of scores and computes aggregate statistics."""
-
- response_helpfulness: Optional[ManagedMetadataResponseHelpfulness] = None
- """Holds a list of scores and computes aggregate statistics."""
-
- trustworthiness: Optional[ManagedMetadataTrustworthiness] = None
- """Holds a list of scores and computes aggregate statistics."""
-
-
-class Entry(BaseModel):
- id: str
-
- created_at: datetime
-
- managed_metadata: ManagedMetadata
- """Extract system-defined, managed metadata from client_query_metadata."""
-
- project_id: str
-
- question: str
-
- state: Literal["unanswered", "draft", "published", "published_with_draft"]
-
- answer: Optional[str] = None
-
- answered_at: Optional[datetime] = None
-
- client_query_metadata: Optional[List[object]] = None
-
- content_structure_score: Optional[float] = None
-
- draft_answer: Optional[str] = None
-
- draft_answer_last_edited: Optional[datetime] = None
-
- eval_issue_type: Optional[str] = None
-
- eval_score: Optional[float] = None
-
- frequency_count: Optional[int] = None
- """number of times the entry matched for a /query request"""
-
- html_format_score: Optional[float] = None
diff --git a/src/codex/types/projects/entry_create_params.py b/src/codex/types/projects/entry_create_params.py
deleted file mode 100644
index f06846b..0000000
--- a/src/codex/types/projects/entry_create_params.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Iterable, Optional
-from typing_extensions import Required, Annotated, TypedDict
-
-from ..._utils import PropertyInfo
-
-__all__ = ["EntryCreateParams"]
-
-
-class EntryCreateParams(TypedDict, total=False):
- question: Required[str]
-
- answer: Optional[str]
-
- client_query_metadata: Iterable[object]
-
- draft_answer: Optional[str]
-
- x_client_library_version: Annotated[str, PropertyInfo(alias="x-client-library-version")]
-
- x_integration_type: Annotated[str, PropertyInfo(alias="x-integration-type")]
-
- x_source: Annotated[str, PropertyInfo(alias="x-source")]
-
- x_stainless_package_version: Annotated[str, PropertyInfo(alias="x-stainless-package-version")]
diff --git a/src/codex/types/projects/entry_notify_sme_params.py b/src/codex/types/projects/entry_notify_sme_params.py
deleted file mode 100644
index 3d06d1a..0000000
--- a/src/codex/types/projects/entry_notify_sme_params.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal, Required, TypedDict
-
-__all__ = ["EntryNotifySmeParams", "ViewContext"]
-
-
-class EntryNotifySmeParams(TypedDict, total=False):
- project_id: Required[str]
-
- email: Required[str]
-
- view_context: Required[ViewContext]
-
-
-class ViewContext(TypedDict, total=False):
- page: Required[int]
-
- filter: Literal[
- "unanswered",
- "answered",
- "all",
- "hallucination",
- "search_failure",
- "unhelpful",
- "difficult_query",
- "unsupported",
- ]
diff --git a/src/codex/types/projects/entry_notify_sme_response.py b/src/codex/types/projects/entry_notify_sme_response.py
deleted file mode 100644
index b3c5b37..0000000
--- a/src/codex/types/projects/entry_notify_sme_response.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from ..._models import BaseModel
-
-__all__ = ["EntryNotifySmeResponse"]
-
-
-class EntryNotifySmeResponse(BaseModel):
- entry_id: str
-
- recipient_email: str
-
- status: str
diff --git a/src/codex/types/projects/entry_query_params.py b/src/codex/types/projects/entry_query_params.py
deleted file mode 100644
index 2ba33b8..0000000
--- a/src/codex/types/projects/entry_query_params.py
+++ /dev/null
@@ -1,300 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Dict, List, Union, Iterable, Optional
-from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict
-
-from ..._utils import PropertyInfo
-
-__all__ = [
- "EntryQueryParams",
- "QueryMetadata",
- "QueryMetadataContextUnionMember3",
- "QueryMetadataMessage",
- "QueryMetadataMessageChatCompletionDeveloperMessageParam",
- "QueryMetadataMessageChatCompletionDeveloperMessageParamContentUnionMember1",
- "QueryMetadataMessageChatCompletionSystemMessageParam",
- "QueryMetadataMessageChatCompletionSystemMessageParamContentUnionMember1",
- "QueryMetadataMessageChatCompletionUserMessageParam",
- "QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1",
- "QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1ChatCompletionContentPartTextParam",
- "QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1ChatCompletionContentPartImageParam",
- "QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1ChatCompletionContentPartImageParamImageURL",
- "QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1ChatCompletionContentPartInputAudioParam",
- "QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1ChatCompletionContentPartInputAudioParamInputAudio",
- "QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1File",
- "QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1FileFile",
- "QueryMetadataMessageChatCompletionAssistantMessageParam",
- "QueryMetadataMessageChatCompletionAssistantMessageParamAudio",
- "QueryMetadataMessageChatCompletionAssistantMessageParamContentUnionMember1",
- "QueryMetadataMessageChatCompletionAssistantMessageParamContentUnionMember1ChatCompletionContentPartTextParam",
- "QueryMetadataMessageChatCompletionAssistantMessageParamContentUnionMember1ChatCompletionContentPartRefusalParam",
- "QueryMetadataMessageChatCompletionAssistantMessageParamFunctionCall",
- "QueryMetadataMessageChatCompletionAssistantMessageParamToolCall",
- "QueryMetadataMessageChatCompletionAssistantMessageParamToolCallFunction",
- "QueryMetadataMessageChatCompletionToolMessageParam",
- "QueryMetadataMessageChatCompletionToolMessageParamContentUnionMember1",
- "QueryMetadataMessageChatCompletionFunctionMessageParam",
-]
-
-
-class EntryQueryParams(TypedDict, total=False):
- question: Required[str]
-
- use_llm_matching: bool
-
- client_metadata: Optional[object]
- """Deprecated: Use query_metadata instead"""
-
- query_metadata: Optional[QueryMetadata]
- """Optional logging data that can be provided by the client."""
-
- x_client_library_version: Annotated[str, PropertyInfo(alias="x-client-library-version")]
-
- x_integration_type: Annotated[str, PropertyInfo(alias="x-integration-type")]
-
- x_source: Annotated[str, PropertyInfo(alias="x-source")]
-
- x_stainless_package_version: Annotated[str, PropertyInfo(alias="x-stainless-package-version")]
-
-
-class QueryMetadataContextUnionMember3(TypedDict, total=False):
- content: Required[str]
- """The actual content/text of the document."""
-
- id: Optional[str]
- """Unique identifier for the document. Useful for tracking documents"""
-
- source: Optional[str]
- """Source or origin of the document. Useful for citations."""
-
- tags: Optional[List[str]]
- """Tags or categories for the document. Useful for filtering"""
-
- title: Optional[str]
- """Title or heading of the document. Useful for display and context."""
-
-
-class QueryMetadataMessageChatCompletionDeveloperMessageParamContentUnionMember1(TypedDict, total=False):
- text: Required[str]
-
- type: Required[Literal["text"]]
-
-
-class QueryMetadataMessageChatCompletionDeveloperMessageParam(TypedDict, total=False):
- content: Required[Union[str, Iterable[QueryMetadataMessageChatCompletionDeveloperMessageParamContentUnionMember1]]]
-
- role: Required[Literal["developer"]]
-
- name: str
-
-
-class QueryMetadataMessageChatCompletionSystemMessageParamContentUnionMember1(TypedDict, total=False):
- text: Required[str]
-
- type: Required[Literal["text"]]
-
-
-class QueryMetadataMessageChatCompletionSystemMessageParam(TypedDict, total=False):
- content: Required[Union[str, Iterable[QueryMetadataMessageChatCompletionSystemMessageParamContentUnionMember1]]]
-
- role: Required[Literal["system"]]
-
- name: str
-
-
-class QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1ChatCompletionContentPartTextParam(
- TypedDict, total=False
-):
- text: Required[str]
-
- type: Required[Literal["text"]]
-
-
-class QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1ChatCompletionContentPartImageParamImageURL(
- TypedDict, total=False
-):
- url: Required[str]
-
- detail: Literal["auto", "low", "high"]
-
-
-class QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1ChatCompletionContentPartImageParam(
- TypedDict, total=False
-):
- image_url: Required[
- QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1ChatCompletionContentPartImageParamImageURL
- ]
-
- type: Required[Literal["image_url"]]
-
-
-class QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1ChatCompletionContentPartInputAudioParamInputAudio(
- TypedDict, total=False
-):
- data: Required[str]
-
- format: Required[Literal["wav", "mp3"]]
-
-
-class QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1ChatCompletionContentPartInputAudioParam(
- TypedDict, total=False
-):
- input_audio: Required[
- QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1ChatCompletionContentPartInputAudioParamInputAudio
- ]
-
- type: Required[Literal["input_audio"]]
-
-
-class QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1FileFile(TypedDict, total=False):
- file_data: str
-
- file_id: str
-
- filename: str
-
-
-class QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1File(TypedDict, total=False):
- file: Required[QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1FileFile]
-
- type: Required[Literal["file"]]
-
-
-QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1: TypeAlias = Union[
- QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1ChatCompletionContentPartTextParam,
- QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1ChatCompletionContentPartImageParam,
- QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1ChatCompletionContentPartInputAudioParam,
- QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1File,
-]
-
-
-class QueryMetadataMessageChatCompletionUserMessageParam(TypedDict, total=False):
- content: Required[Union[str, Iterable[QueryMetadataMessageChatCompletionUserMessageParamContentUnionMember1]]]
-
- role: Required[Literal["user"]]
-
- name: str
-
-
-class QueryMetadataMessageChatCompletionAssistantMessageParamAudio(TypedDict, total=False):
- id: Required[str]
-
-
-class QueryMetadataMessageChatCompletionAssistantMessageParamContentUnionMember1ChatCompletionContentPartTextParam(
- TypedDict, total=False
-):
- text: Required[str]
-
- type: Required[Literal["text"]]
-
-
-class QueryMetadataMessageChatCompletionAssistantMessageParamContentUnionMember1ChatCompletionContentPartRefusalParam(
- TypedDict, total=False
-):
- refusal: Required[str]
-
- type: Required[Literal["refusal"]]
-
-
-QueryMetadataMessageChatCompletionAssistantMessageParamContentUnionMember1: TypeAlias = Union[
- QueryMetadataMessageChatCompletionAssistantMessageParamContentUnionMember1ChatCompletionContentPartTextParam,
- QueryMetadataMessageChatCompletionAssistantMessageParamContentUnionMember1ChatCompletionContentPartRefusalParam,
-]
-
-
-class QueryMetadataMessageChatCompletionAssistantMessageParamFunctionCall(TypedDict, total=False):
- arguments: Required[str]
-
- name: Required[str]
-
-
-class QueryMetadataMessageChatCompletionAssistantMessageParamToolCallFunction(TypedDict, total=False):
- arguments: Required[str]
-
- name: Required[str]
-
-
-class QueryMetadataMessageChatCompletionAssistantMessageParamToolCall(TypedDict, total=False):
- id: Required[str]
-
- function: Required[QueryMetadataMessageChatCompletionAssistantMessageParamToolCallFunction]
-
- type: Required[Literal["function"]]
-
-
-class QueryMetadataMessageChatCompletionAssistantMessageParam(TypedDict, total=False):
- role: Required[Literal["assistant"]]
-
- audio: Optional[QueryMetadataMessageChatCompletionAssistantMessageParamAudio]
-
- content: Union[str, Iterable[QueryMetadataMessageChatCompletionAssistantMessageParamContentUnionMember1], None]
-
- function_call: Optional[QueryMetadataMessageChatCompletionAssistantMessageParamFunctionCall]
-
- name: str
-
- refusal: Optional[str]
-
- tool_calls: Iterable[QueryMetadataMessageChatCompletionAssistantMessageParamToolCall]
-
-
-class QueryMetadataMessageChatCompletionToolMessageParamContentUnionMember1(TypedDict, total=False):
- text: Required[str]
-
- type: Required[Literal["text"]]
-
-
-class QueryMetadataMessageChatCompletionToolMessageParam(TypedDict, total=False):
- content: Required[Union[str, Iterable[QueryMetadataMessageChatCompletionToolMessageParamContentUnionMember1]]]
-
- role: Required[Literal["tool"]]
-
- tool_call_id: Required[str]
-
-
-class QueryMetadataMessageChatCompletionFunctionMessageParam(TypedDict, total=False):
- content: Required[Optional[str]]
-
- name: Required[str]
-
- role: Required[Literal["function"]]
-
-
-QueryMetadataMessage: TypeAlias = Union[
- QueryMetadataMessageChatCompletionDeveloperMessageParam,
- QueryMetadataMessageChatCompletionSystemMessageParam,
- QueryMetadataMessageChatCompletionUserMessageParam,
- QueryMetadataMessageChatCompletionAssistantMessageParam,
- QueryMetadataMessageChatCompletionToolMessageParam,
- QueryMetadataMessageChatCompletionFunctionMessageParam,
-]
-
-
-class QueryMetadata(TypedDict, total=False):
- context: Union[str, List[str], Iterable[object], Iterable[QueryMetadataContextUnionMember3], None]
- """RAG context used for the query"""
-
- custom_metadata: Optional[object]
- """Arbitrary metadata supplied by the user/system"""
-
- eval_scores: Optional[Dict[str, float]]
- """Evaluation scores for the original response"""
-
- evaluated_response: Optional[str]
- """The response being evaluated from the RAG system(before any remediation)"""
-
- messages: Optional[Iterable[QueryMetadataMessage]]
- """Optional message history to provide conversation context for the query.
-
- Used to rewrite query into a self-contained version of itself. If not provided,
- the query will be treated as self-contained.
- """
-
- original_question: Optional[str]
- """The original question that was asked before any rewriting or processing.
-
- For all non-conversational RAG, original_question should be the same as the
- final question seen in Codex.
- """
diff --git a/src/codex/types/projects/entry_query_response.py b/src/codex/types/projects/entry_query_response.py
deleted file mode 100644
index cd5a4c9..0000000
--- a/src/codex/types/projects/entry_query_response.py
+++ /dev/null
@@ -1,194 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-
-from ..._models import BaseModel
-
-__all__ = [
- "EntryQueryResponse",
- "Entry",
- "EntryManagedMetadata",
- "EntryManagedMetadataContentStructureScores",
- "EntryManagedMetadataContextSufficiency",
- "EntryManagedMetadataHTMLFormatScores",
- "EntryManagedMetadataQueryEaseCustomized",
- "EntryManagedMetadataResponseGroundedness",
- "EntryManagedMetadataResponseHelpfulness",
- "EntryManagedMetadataTrustworthiness",
-]
-
-
-class EntryManagedMetadataContentStructureScores(BaseModel):
- average: Optional[float] = None
- """The average of all scores."""
-
- latest: Optional[float] = None
- """The most recent score."""
-
- max: Optional[float] = None
- """The maximum score."""
-
- min: Optional[float] = None
- """The minimum score."""
-
- scores: Optional[List[float]] = None
-
-
-class EntryManagedMetadataContextSufficiency(BaseModel):
- average: Optional[float] = None
- """The average of all scores."""
-
- latest: Optional[float] = None
- """The most recent score."""
-
- max: Optional[float] = None
- """The maximum score."""
-
- min: Optional[float] = None
- """The minimum score."""
-
- scores: Optional[List[float]] = None
-
-
-class EntryManagedMetadataHTMLFormatScores(BaseModel):
- average: Optional[float] = None
- """The average of all scores."""
-
- latest: Optional[float] = None
- """The most recent score."""
-
- max: Optional[float] = None
- """The maximum score."""
-
- min: Optional[float] = None
- """The minimum score."""
-
- scores: Optional[List[float]] = None
-
-
-class EntryManagedMetadataQueryEaseCustomized(BaseModel):
- average: Optional[float] = None
- """The average of all scores."""
-
- latest: Optional[float] = None
- """The most recent score."""
-
- max: Optional[float] = None
- """The maximum score."""
-
- min: Optional[float] = None
- """The minimum score."""
-
- scores: Optional[List[float]] = None
-
-
-class EntryManagedMetadataResponseGroundedness(BaseModel):
- average: Optional[float] = None
- """The average of all scores."""
-
- latest: Optional[float] = None
- """The most recent score."""
-
- max: Optional[float] = None
- """The maximum score."""
-
- min: Optional[float] = None
- """The minimum score."""
-
- scores: Optional[List[float]] = None
-
-
-class EntryManagedMetadataResponseHelpfulness(BaseModel):
- average: Optional[float] = None
- """The average of all scores."""
-
- latest: Optional[float] = None
- """The most recent score."""
-
- max: Optional[float] = None
- """The maximum score."""
-
- min: Optional[float] = None
- """The minimum score."""
-
- scores: Optional[List[float]] = None
-
-
-class EntryManagedMetadataTrustworthiness(BaseModel):
- average: Optional[float] = None
- """The average of all scores."""
-
- latest: Optional[float] = None
- """The most recent score."""
-
- max: Optional[float] = None
- """The maximum score."""
-
- min: Optional[float] = None
- """The minimum score."""
-
- scores: Optional[List[float]] = None
-
-
-class EntryManagedMetadata(BaseModel):
- latest_context: Optional[str] = None
- """The most recent context string."""
-
- latest_entry_point: Optional[str] = None
- """The most recent entry point string."""
-
- latest_llm_response: Optional[str] = None
- """The most recent LLM response string."""
-
- latest_location: Optional[str] = None
- """The most recent location string."""
-
- content_structure_scores: Optional[EntryManagedMetadataContentStructureScores] = None
- """Holds a list of scores and computes aggregate statistics."""
-
- context_sufficiency: Optional[EntryManagedMetadataContextSufficiency] = None
- """Holds a list of scores and computes aggregate statistics."""
-
- contexts: Optional[List[str]] = None
-
- entry_points: Optional[List[str]] = None
-
- html_format_scores: Optional[EntryManagedMetadataHTMLFormatScores] = None
- """Holds a list of scores and computes aggregate statistics."""
-
- llm_responses: Optional[List[str]] = None
-
- locations: Optional[List[str]] = None
-
- query_ease_customized: Optional[EntryManagedMetadataQueryEaseCustomized] = None
- """Holds a list of scores and computes aggregate statistics."""
-
- response_groundedness: Optional[EntryManagedMetadataResponseGroundedness] = None
- """Holds a list of scores and computes aggregate statistics."""
-
- response_helpfulness: Optional[EntryManagedMetadataResponseHelpfulness] = None
- """Holds a list of scores and computes aggregate statistics."""
-
- trustworthiness: Optional[EntryManagedMetadataTrustworthiness] = None
- """Holds a list of scores and computes aggregate statistics."""
-
-
-class Entry(BaseModel):
- id: str
-
- managed_metadata: EntryManagedMetadata
- """Extract system-defined, managed metadata from client_query_metadata."""
-
- question: str
-
- answer: Optional[str] = None
-
- client_query_metadata: Optional[List[object]] = None
-
- draft_answer: Optional[str] = None
-
-
-class EntryQueryResponse(BaseModel):
- entry: Entry
-
- answer: Optional[str] = None
diff --git a/src/codex/types/projects/entry_update_params.py b/src/codex/types/projects/entry_update_params.py
deleted file mode 100644
index aac256f..0000000
--- a/src/codex/types/projects/entry_update_params.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Optional
-from typing_extensions import Required, TypedDict
-
-__all__ = ["EntryUpdateParams"]
-
-
-class EntryUpdateParams(TypedDict, total=False):
- project_id: Required[str]
-
- answer: Optional[str]
-
- draft_answer: Optional[str]
-
- question: Optional[str]
diff --git a/src/codex/types/projects/query_log_list_by_group_response.py b/src/codex/types/projects/query_log_list_by_group_response.py
index 9d1e0e6..c294d93 100644
--- a/src/codex/types/projects/query_log_list_by_group_response.py
+++ b/src/codex/types/projects/query_log_list_by_group_response.py
@@ -71,12 +71,16 @@ class QueryLogsByGroupQueryLog(BaseModel):
is_bad_response: bool
+ needs_review: bool
+
project_id: str
question: str
remediation_id: str
+ remediation_status: Literal["ACTIVE", "DRAFT", "ACTIVE_WITH_DRAFT", "NOT_STARTED", "PAUSED", "NO_ACTION_NEEDED"]
+
was_cache_hit: Optional[bool] = None
"""If similar query already answered, or None if cache was not checked"""
diff --git a/src/codex/types/projects/query_log_list_groups_response.py b/src/codex/types/projects/query_log_list_groups_response.py
index 7b77cc0..ce5806b 100644
--- a/src/codex/types/projects/query_log_list_groups_response.py
+++ b/src/codex/types/projects/query_log_list_groups_response.py
@@ -78,7 +78,7 @@ class QueryLogGroup(BaseModel):
remediation_id: str
- status: Literal["ACTIVE", "DRAFT", "ACTIVE_WITH_DRAFT", "NOT_STARTED", "PAUSED", "NO_ACTION_NEEDED"]
+ remediation_status: Literal["ACTIVE", "DRAFT", "ACTIVE_WITH_DRAFT", "NOT_STARTED", "PAUSED", "NO_ACTION_NEEDED"]
total_count: int
diff --git a/src/codex/types/projects/query_log_retrieve_response.py b/src/codex/types/projects/query_log_retrieve_response.py
index 8bb6128..5214cff 100644
--- a/src/codex/types/projects/query_log_retrieve_response.py
+++ b/src/codex/types/projects/query_log_retrieve_response.py
@@ -69,12 +69,16 @@ class QueryLogRetrieveResponse(BaseModel):
is_bad_response: bool
+ needs_review: bool
+
project_id: str
question: str
remediation_id: str
+ remediation_status: Literal["ACTIVE", "DRAFT", "ACTIVE_WITH_DRAFT", "NOT_STARTED", "PAUSED", "NO_ACTION_NEEDED"]
+
was_cache_hit: Optional[bool] = None
"""If similar query already answered, or None if cache was not checked"""
diff --git a/tests/api_resources/projects/test_clusters.py b/tests/api_resources/projects/test_clusters.py
deleted file mode 100644
index 8773427..0000000
--- a/tests/api_resources/projects/test_clusters.py
+++ /dev/null
@@ -1,247 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import pytest
-
-from codex import Codex, AsyncCodex
-from tests.utils import assert_matches_type
-from codex.pagination import SyncOffsetPageClusters, AsyncOffsetPageClusters
-from codex.types.projects import ClusterListResponse, ClusterListVariantsResponse
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestClusters:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @pytest.mark.skip()
- @parametrize
- def test_method_list(self, client: Codex) -> None:
- cluster = client.projects.clusters.list(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
- assert_matches_type(SyncOffsetPageClusters[ClusterListResponse], cluster, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- def test_method_list_with_all_params(self, client: Codex) -> None:
- cluster = client.projects.clusters.list(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- eval_issue_types=["hallucination"],
- instruction_adherence_failure="html_format",
- limit=1,
- offset=0,
- order="asc",
- sort="created_at",
- states=["unanswered"],
- )
- assert_matches_type(SyncOffsetPageClusters[ClusterListResponse], cluster, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- def test_raw_response_list(self, client: Codex) -> None:
- response = client.projects.clusters.with_raw_response.list(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- cluster = response.parse()
- assert_matches_type(SyncOffsetPageClusters[ClusterListResponse], cluster, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- def test_streaming_response_list(self, client: Codex) -> None:
- with client.projects.clusters.with_streaming_response.list(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- cluster = response.parse()
- assert_matches_type(SyncOffsetPageClusters[ClusterListResponse], cluster, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip()
- @parametrize
- def test_path_params_list(self, client: Codex) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
- client.projects.clusters.with_raw_response.list(
- project_id="",
- )
-
- @pytest.mark.skip()
- @parametrize
- def test_method_list_variants(self, client: Codex) -> None:
- cluster = client.projects.clusters.list_variants(
- representative_entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
- assert_matches_type(ClusterListVariantsResponse, cluster, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- def test_raw_response_list_variants(self, client: Codex) -> None:
- response = client.projects.clusters.with_raw_response.list_variants(
- representative_entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- cluster = response.parse()
- assert_matches_type(ClusterListVariantsResponse, cluster, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- def test_streaming_response_list_variants(self, client: Codex) -> None:
- with client.projects.clusters.with_streaming_response.list_variants(
- representative_entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- cluster = response.parse()
- assert_matches_type(ClusterListVariantsResponse, cluster, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip()
- @parametrize
- def test_path_params_list_variants(self, client: Codex) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
- client.projects.clusters.with_raw_response.list_variants(
- representative_entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="",
- )
-
- with pytest.raises(
- ValueError, match=r"Expected a non-empty value for `representative_entry_id` but received ''"
- ):
- client.projects.clusters.with_raw_response.list_variants(
- representative_entry_id="",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
-
-class TestAsyncClusters:
- parametrize = pytest.mark.parametrize(
- "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
- )
-
- @pytest.mark.skip()
- @parametrize
- async def test_method_list(self, async_client: AsyncCodex) -> None:
- cluster = await async_client.projects.clusters.list(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
- assert_matches_type(AsyncOffsetPageClusters[ClusterListResponse], cluster, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- async def test_method_list_with_all_params(self, async_client: AsyncCodex) -> None:
- cluster = await async_client.projects.clusters.list(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- eval_issue_types=["hallucination"],
- instruction_adherence_failure="html_format",
- limit=1,
- offset=0,
- order="asc",
- sort="created_at",
- states=["unanswered"],
- )
- assert_matches_type(AsyncOffsetPageClusters[ClusterListResponse], cluster, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- async def test_raw_response_list(self, async_client: AsyncCodex) -> None:
- response = await async_client.projects.clusters.with_raw_response.list(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- cluster = await response.parse()
- assert_matches_type(AsyncOffsetPageClusters[ClusterListResponse], cluster, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- async def test_streaming_response_list(self, async_client: AsyncCodex) -> None:
- async with async_client.projects.clusters.with_streaming_response.list(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- cluster = await response.parse()
- assert_matches_type(AsyncOffsetPageClusters[ClusterListResponse], cluster, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip()
- @parametrize
- async def test_path_params_list(self, async_client: AsyncCodex) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
- await async_client.projects.clusters.with_raw_response.list(
- project_id="",
- )
-
- @pytest.mark.skip()
- @parametrize
- async def test_method_list_variants(self, async_client: AsyncCodex) -> None:
- cluster = await async_client.projects.clusters.list_variants(
- representative_entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
- assert_matches_type(ClusterListVariantsResponse, cluster, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- async def test_raw_response_list_variants(self, async_client: AsyncCodex) -> None:
- response = await async_client.projects.clusters.with_raw_response.list_variants(
- representative_entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- cluster = await response.parse()
- assert_matches_type(ClusterListVariantsResponse, cluster, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- async def test_streaming_response_list_variants(self, async_client: AsyncCodex) -> None:
- async with async_client.projects.clusters.with_streaming_response.list_variants(
- representative_entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- cluster = await response.parse()
- assert_matches_type(ClusterListVariantsResponse, cluster, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip()
- @parametrize
- async def test_path_params_list_variants(self, async_client: AsyncCodex) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
- await async_client.projects.clusters.with_raw_response.list_variants(
- representative_entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="",
- )
-
- with pytest.raises(
- ValueError, match=r"Expected a non-empty value for `representative_entry_id` but received ''"
- ):
- await async_client.projects.clusters.with_raw_response.list_variants(
- representative_entry_id="",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
diff --git a/tests/api_resources/projects/test_entries.py b/tests/api_resources/projects/test_entries.py
deleted file mode 100644
index 1b077d1..0000000
--- a/tests/api_resources/projects/test_entries.py
+++ /dev/null
@@ -1,1014 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import pytest
-
-from codex import Codex, AsyncCodex
-from tests.utils import assert_matches_type
-from codex.types.projects import (
- Entry,
- EntryQueryResponse,
- EntryNotifySmeResponse,
-)
-
-# pyright: reportDeprecated=false
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestEntries:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @pytest.mark.skip()
- @parametrize
- def test_method_create(self, client: Codex) -> None:
- entry = client.projects.entries.create(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- question="question",
- )
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- def test_method_create_with_all_params(self, client: Codex) -> None:
- entry = client.projects.entries.create(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- question="question",
- answer="answer",
- client_query_metadata=[{}],
- draft_answer="draft_answer",
- x_client_library_version="x-client-library-version",
- x_integration_type="x-integration-type",
- x_source="x-source",
- x_stainless_package_version="x-stainless-package-version",
- )
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- def test_raw_response_create(self, client: Codex) -> None:
- response = client.projects.entries.with_raw_response.create(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- question="question",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- entry = response.parse()
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- def test_streaming_response_create(self, client: Codex) -> None:
- with client.projects.entries.with_streaming_response.create(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- question="question",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- entry = response.parse()
- assert_matches_type(Entry, entry, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip()
- @parametrize
- def test_path_params_create(self, client: Codex) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
- client.projects.entries.with_raw_response.create(
- project_id="",
- question="question",
- )
-
- @pytest.mark.skip()
- @parametrize
- def test_method_retrieve(self, client: Codex) -> None:
- entry = client.projects.entries.retrieve(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- def test_raw_response_retrieve(self, client: Codex) -> None:
- response = client.projects.entries.with_raw_response.retrieve(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- entry = response.parse()
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- def test_streaming_response_retrieve(self, client: Codex) -> None:
- with client.projects.entries.with_streaming_response.retrieve(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- entry = response.parse()
- assert_matches_type(Entry, entry, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip()
- @parametrize
- def test_path_params_retrieve(self, client: Codex) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
- client.projects.entries.with_raw_response.retrieve(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `entry_id` but received ''"):
- client.projects.entries.with_raw_response.retrieve(
- entry_id="",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- @pytest.mark.skip()
- @parametrize
- def test_method_update(self, client: Codex) -> None:
- entry = client.projects.entries.update(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- def test_method_update_with_all_params(self, client: Codex) -> None:
- entry = client.projects.entries.update(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- answer="answer",
- draft_answer="draft_answer",
- question="question",
- )
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- def test_raw_response_update(self, client: Codex) -> None:
- response = client.projects.entries.with_raw_response.update(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- entry = response.parse()
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- def test_streaming_response_update(self, client: Codex) -> None:
- with client.projects.entries.with_streaming_response.update(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- entry = response.parse()
- assert_matches_type(Entry, entry, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip()
- @parametrize
- def test_path_params_update(self, client: Codex) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
- client.projects.entries.with_raw_response.update(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `entry_id` but received ''"):
- client.projects.entries.with_raw_response.update(
- entry_id="",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- @pytest.mark.skip()
- @parametrize
- def test_method_delete(self, client: Codex) -> None:
- entry = client.projects.entries.delete(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
- assert entry is None
-
- @pytest.mark.skip()
- @parametrize
- def test_raw_response_delete(self, client: Codex) -> None:
- response = client.projects.entries.with_raw_response.delete(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- entry = response.parse()
- assert entry is None
-
- @pytest.mark.skip()
- @parametrize
- def test_streaming_response_delete(self, client: Codex) -> None:
- with client.projects.entries.with_streaming_response.delete(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- entry = response.parse()
- assert entry is None
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip()
- @parametrize
- def test_path_params_delete(self, client: Codex) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
- client.projects.entries.with_raw_response.delete(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `entry_id` but received ''"):
- client.projects.entries.with_raw_response.delete(
- entry_id="",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- @pytest.mark.skip()
- @parametrize
- def test_method_notify_sme(self, client: Codex) -> None:
- entry = client.projects.entries.notify_sme(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- email="email",
- view_context={"page": 0},
- )
- assert_matches_type(EntryNotifySmeResponse, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- def test_method_notify_sme_with_all_params(self, client: Codex) -> None:
- entry = client.projects.entries.notify_sme(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- email="email",
- view_context={
- "page": 0,
- "filter": "unanswered",
- },
- )
- assert_matches_type(EntryNotifySmeResponse, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- def test_raw_response_notify_sme(self, client: Codex) -> None:
- response = client.projects.entries.with_raw_response.notify_sme(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- email="email",
- view_context={"page": 0},
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- entry = response.parse()
- assert_matches_type(EntryNotifySmeResponse, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- def test_streaming_response_notify_sme(self, client: Codex) -> None:
- with client.projects.entries.with_streaming_response.notify_sme(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- email="email",
- view_context={"page": 0},
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- entry = response.parse()
- assert_matches_type(EntryNotifySmeResponse, entry, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip()
- @parametrize
- def test_path_params_notify_sme(self, client: Codex) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
- client.projects.entries.with_raw_response.notify_sme(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="",
- email="email",
- view_context={"page": 0},
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `entry_id` but received ''"):
- client.projects.entries.with_raw_response.notify_sme(
- entry_id="",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- email="email",
- view_context={"page": 0},
- )
-
- @pytest.mark.skip()
- @parametrize
- def test_method_publish_draft_answer(self, client: Codex) -> None:
- entry = client.projects.entries.publish_draft_answer(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- def test_raw_response_publish_draft_answer(self, client: Codex) -> None:
- response = client.projects.entries.with_raw_response.publish_draft_answer(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- entry = response.parse()
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- def test_streaming_response_publish_draft_answer(self, client: Codex) -> None:
- with client.projects.entries.with_streaming_response.publish_draft_answer(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- entry = response.parse()
- assert_matches_type(Entry, entry, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip()
- @parametrize
- def test_path_params_publish_draft_answer(self, client: Codex) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
- client.projects.entries.with_raw_response.publish_draft_answer(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `entry_id` but received ''"):
- client.projects.entries.with_raw_response.publish_draft_answer(
- entry_id="",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- @pytest.mark.skip()
- @parametrize
- def test_method_query(self, client: Codex) -> None:
- with pytest.warns(DeprecationWarning):
- entry = client.projects.entries.query(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- question="question",
- )
-
- assert_matches_type(EntryQueryResponse, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- def test_method_query_with_all_params(self, client: Codex) -> None:
- with pytest.warns(DeprecationWarning):
- entry = client.projects.entries.query(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- question="question",
- use_llm_matching=True,
- client_metadata={},
- query_metadata={
- "context": "string",
- "custom_metadata": {},
- "eval_scores": {"foo": 0},
- "evaluated_response": "evaluated_response",
- "messages": [
- {
- "content": "string",
- "role": "developer",
- "name": "name",
- }
- ],
- "original_question": "original_question",
- },
- x_client_library_version="x-client-library-version",
- x_integration_type="x-integration-type",
- x_source="x-source",
- x_stainless_package_version="x-stainless-package-version",
- )
-
- assert_matches_type(EntryQueryResponse, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- def test_raw_response_query(self, client: Codex) -> None:
- with pytest.warns(DeprecationWarning):
- response = client.projects.entries.with_raw_response.query(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- question="question",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- entry = response.parse()
- assert_matches_type(EntryQueryResponse, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- def test_streaming_response_query(self, client: Codex) -> None:
- with pytest.warns(DeprecationWarning):
- with client.projects.entries.with_streaming_response.query(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- question="question",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- entry = response.parse()
- assert_matches_type(EntryQueryResponse, entry, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip()
- @parametrize
- def test_path_params_query(self, client: Codex) -> None:
- with pytest.warns(DeprecationWarning):
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
- client.projects.entries.with_raw_response.query(
- project_id="",
- question="question",
- )
-
- @pytest.mark.skip()
- @parametrize
- def test_method_unpublish_answer(self, client: Codex) -> None:
- entry = client.projects.entries.unpublish_answer(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- def test_raw_response_unpublish_answer(self, client: Codex) -> None:
- response = client.projects.entries.with_raw_response.unpublish_answer(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- entry = response.parse()
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- def test_streaming_response_unpublish_answer(self, client: Codex) -> None:
- with client.projects.entries.with_streaming_response.unpublish_answer(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- entry = response.parse()
- assert_matches_type(Entry, entry, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip()
- @parametrize
- def test_path_params_unpublish_answer(self, client: Codex) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
- client.projects.entries.with_raw_response.unpublish_answer(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `entry_id` but received ''"):
- client.projects.entries.with_raw_response.unpublish_answer(
- entry_id="",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
-
-class TestAsyncEntries:
- parametrize = pytest.mark.parametrize(
- "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
- )
-
- @pytest.mark.skip()
- @parametrize
- async def test_method_create(self, async_client: AsyncCodex) -> None:
- entry = await async_client.projects.entries.create(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- question="question",
- )
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- async def test_method_create_with_all_params(self, async_client: AsyncCodex) -> None:
- entry = await async_client.projects.entries.create(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- question="question",
- answer="answer",
- client_query_metadata=[{}],
- draft_answer="draft_answer",
- x_client_library_version="x-client-library-version",
- x_integration_type="x-integration-type",
- x_source="x-source",
- x_stainless_package_version="x-stainless-package-version",
- )
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- async def test_raw_response_create(self, async_client: AsyncCodex) -> None:
- response = await async_client.projects.entries.with_raw_response.create(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- question="question",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- entry = await response.parse()
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- async def test_streaming_response_create(self, async_client: AsyncCodex) -> None:
- async with async_client.projects.entries.with_streaming_response.create(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- question="question",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- entry = await response.parse()
- assert_matches_type(Entry, entry, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip()
- @parametrize
- async def test_path_params_create(self, async_client: AsyncCodex) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
- await async_client.projects.entries.with_raw_response.create(
- project_id="",
- question="question",
- )
-
- @pytest.mark.skip()
- @parametrize
- async def test_method_retrieve(self, async_client: AsyncCodex) -> None:
- entry = await async_client.projects.entries.retrieve(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- async def test_raw_response_retrieve(self, async_client: AsyncCodex) -> None:
- response = await async_client.projects.entries.with_raw_response.retrieve(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- entry = await response.parse()
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- async def test_streaming_response_retrieve(self, async_client: AsyncCodex) -> None:
- async with async_client.projects.entries.with_streaming_response.retrieve(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- entry = await response.parse()
- assert_matches_type(Entry, entry, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip()
- @parametrize
- async def test_path_params_retrieve(self, async_client: AsyncCodex) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
- await async_client.projects.entries.with_raw_response.retrieve(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `entry_id` but received ''"):
- await async_client.projects.entries.with_raw_response.retrieve(
- entry_id="",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- @pytest.mark.skip()
- @parametrize
- async def test_method_update(self, async_client: AsyncCodex) -> None:
- entry = await async_client.projects.entries.update(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- async def test_method_update_with_all_params(self, async_client: AsyncCodex) -> None:
- entry = await async_client.projects.entries.update(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- answer="answer",
- draft_answer="draft_answer",
- question="question",
- )
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- async def test_raw_response_update(self, async_client: AsyncCodex) -> None:
- response = await async_client.projects.entries.with_raw_response.update(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- entry = await response.parse()
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- async def test_streaming_response_update(self, async_client: AsyncCodex) -> None:
- async with async_client.projects.entries.with_streaming_response.update(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- entry = await response.parse()
- assert_matches_type(Entry, entry, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip()
- @parametrize
- async def test_path_params_update(self, async_client: AsyncCodex) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
- await async_client.projects.entries.with_raw_response.update(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `entry_id` but received ''"):
- await async_client.projects.entries.with_raw_response.update(
- entry_id="",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- @pytest.mark.skip()
- @parametrize
- async def test_method_delete(self, async_client: AsyncCodex) -> None:
- entry = await async_client.projects.entries.delete(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
- assert entry is None
-
- @pytest.mark.skip()
- @parametrize
- async def test_raw_response_delete(self, async_client: AsyncCodex) -> None:
- response = await async_client.projects.entries.with_raw_response.delete(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- entry = await response.parse()
- assert entry is None
-
- @pytest.mark.skip()
- @parametrize
- async def test_streaming_response_delete(self, async_client: AsyncCodex) -> None:
- async with async_client.projects.entries.with_streaming_response.delete(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- entry = await response.parse()
- assert entry is None
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip()
- @parametrize
- async def test_path_params_delete(self, async_client: AsyncCodex) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
- await async_client.projects.entries.with_raw_response.delete(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `entry_id` but received ''"):
- await async_client.projects.entries.with_raw_response.delete(
- entry_id="",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- @pytest.mark.skip()
- @parametrize
- async def test_method_notify_sme(self, async_client: AsyncCodex) -> None:
- entry = await async_client.projects.entries.notify_sme(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- email="email",
- view_context={"page": 0},
- )
- assert_matches_type(EntryNotifySmeResponse, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- async def test_method_notify_sme_with_all_params(self, async_client: AsyncCodex) -> None:
- entry = await async_client.projects.entries.notify_sme(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- email="email",
- view_context={
- "page": 0,
- "filter": "unanswered",
- },
- )
- assert_matches_type(EntryNotifySmeResponse, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- async def test_raw_response_notify_sme(self, async_client: AsyncCodex) -> None:
- response = await async_client.projects.entries.with_raw_response.notify_sme(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- email="email",
- view_context={"page": 0},
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- entry = await response.parse()
- assert_matches_type(EntryNotifySmeResponse, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- async def test_streaming_response_notify_sme(self, async_client: AsyncCodex) -> None:
- async with async_client.projects.entries.with_streaming_response.notify_sme(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- email="email",
- view_context={"page": 0},
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- entry = await response.parse()
- assert_matches_type(EntryNotifySmeResponse, entry, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip()
- @parametrize
- async def test_path_params_notify_sme(self, async_client: AsyncCodex) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
- await async_client.projects.entries.with_raw_response.notify_sme(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="",
- email="email",
- view_context={"page": 0},
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `entry_id` but received ''"):
- await async_client.projects.entries.with_raw_response.notify_sme(
- entry_id="",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- email="email",
- view_context={"page": 0},
- )
-
- @pytest.mark.skip()
- @parametrize
- async def test_method_publish_draft_answer(self, async_client: AsyncCodex) -> None:
- entry = await async_client.projects.entries.publish_draft_answer(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- async def test_raw_response_publish_draft_answer(self, async_client: AsyncCodex) -> None:
- response = await async_client.projects.entries.with_raw_response.publish_draft_answer(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- entry = await response.parse()
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- async def test_streaming_response_publish_draft_answer(self, async_client: AsyncCodex) -> None:
- async with async_client.projects.entries.with_streaming_response.publish_draft_answer(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- entry = await response.parse()
- assert_matches_type(Entry, entry, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip()
- @parametrize
- async def test_path_params_publish_draft_answer(self, async_client: AsyncCodex) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
- await async_client.projects.entries.with_raw_response.publish_draft_answer(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `entry_id` but received ''"):
- await async_client.projects.entries.with_raw_response.publish_draft_answer(
- entry_id="",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- @pytest.mark.skip()
- @parametrize
- async def test_method_query(self, async_client: AsyncCodex) -> None:
- with pytest.warns(DeprecationWarning):
- entry = await async_client.projects.entries.query(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- question="question",
- )
-
- assert_matches_type(EntryQueryResponse, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- async def test_method_query_with_all_params(self, async_client: AsyncCodex) -> None:
- with pytest.warns(DeprecationWarning):
- entry = await async_client.projects.entries.query(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- question="question",
- use_llm_matching=True,
- client_metadata={},
- query_metadata={
- "context": "string",
- "custom_metadata": {},
- "eval_scores": {"foo": 0},
- "evaluated_response": "evaluated_response",
- "messages": [
- {
- "content": "string",
- "role": "developer",
- "name": "name",
- }
- ],
- "original_question": "original_question",
- },
- x_client_library_version="x-client-library-version",
- x_integration_type="x-integration-type",
- x_source="x-source",
- x_stainless_package_version="x-stainless-package-version",
- )
-
- assert_matches_type(EntryQueryResponse, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- async def test_raw_response_query(self, async_client: AsyncCodex) -> None:
- with pytest.warns(DeprecationWarning):
- response = await async_client.projects.entries.with_raw_response.query(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- question="question",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- entry = await response.parse()
- assert_matches_type(EntryQueryResponse, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- async def test_streaming_response_query(self, async_client: AsyncCodex) -> None:
- with pytest.warns(DeprecationWarning):
- async with async_client.projects.entries.with_streaming_response.query(
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- question="question",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- entry = await response.parse()
- assert_matches_type(EntryQueryResponse, entry, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip()
- @parametrize
- async def test_path_params_query(self, async_client: AsyncCodex) -> None:
- with pytest.warns(DeprecationWarning):
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
- await async_client.projects.entries.with_raw_response.query(
- project_id="",
- question="question",
- )
-
- @pytest.mark.skip()
- @parametrize
- async def test_method_unpublish_answer(self, async_client: AsyncCodex) -> None:
- entry = await async_client.projects.entries.unpublish_answer(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- async def test_raw_response_unpublish_answer(self, async_client: AsyncCodex) -> None:
- response = await async_client.projects.entries.with_raw_response.unpublish_answer(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- entry = await response.parse()
- assert_matches_type(Entry, entry, path=["response"])
-
- @pytest.mark.skip()
- @parametrize
- async def test_streaming_response_unpublish_answer(self, async_client: AsyncCodex) -> None:
- async with async_client.projects.entries.with_streaming_response.unpublish_answer(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- entry = await response.parse()
- assert_matches_type(Entry, entry, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip()
- @parametrize
- async def test_path_params_unpublish_answer(self, async_client: AsyncCodex) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
- await async_client.projects.entries.with_raw_response.unpublish_answer(
- entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- project_id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `entry_id` but received ''"):
- await async_client.projects.entries.with_raw_response.unpublish_answer(
- entry_id="",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
From 023823bace71bdc65ce1ff432373a26731ec43d4 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 2 Jul 2025 05:00:55 +0000
Subject: [PATCH 09/18] chore(ci): change upload type
---
.github/workflows/ci.yml | 18 ++++++++++++++++--
scripts/utils/upload-artifact.sh | 12 +++++++-----
2 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index bbb722b..a6979eb 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -35,10 +35,10 @@ jobs:
- name: Run lints
run: ./scripts/lint
- upload:
+ build:
if: github.repository == 'stainless-sdks/codex-python' && (github.event_name == 'push' || github.event.pull_request.head.repo.fork)
timeout-minutes: 10
- name: upload
+ name: build
permissions:
contents: read
id-token: write
@@ -46,6 +46,20 @@ jobs:
steps:
- uses: actions/checkout@v4
+ - name: Install Rye
+ run: |
+ curl -sSf https://rye.astral.sh/get | bash
+ echo "$HOME/.rye/shims" >> $GITHUB_PATH
+ env:
+ RYE_VERSION: '0.44.0'
+ RYE_INSTALL_OPTION: '--yes'
+
+ - name: Install dependencies
+ run: rye sync --all-features
+
+ - name: Run build
+ run: rye build
+
- name: Get GitHub OIDC Token
id: github-oidc
uses: actions/github-script@v6
diff --git a/scripts/utils/upload-artifact.sh b/scripts/utils/upload-artifact.sh
index 62d150a..aac0384 100755
--- a/scripts/utils/upload-artifact.sh
+++ b/scripts/utils/upload-artifact.sh
@@ -1,7 +1,9 @@
#!/usr/bin/env bash
set -exuo pipefail
-RESPONSE=$(curl -X POST "$URL" \
+FILENAME=$(basename dist/*.whl)
+
+RESPONSE=$(curl -X POST "$URL?filename=$FILENAME" \
-H "Authorization: Bearer $AUTH" \
-H "Content-Type: application/json")
@@ -12,13 +14,13 @@ if [[ "$SIGNED_URL" == "null" ]]; then
exit 1
fi
-UPLOAD_RESPONSE=$(tar -cz . | curl -v -X PUT \
- -H "Content-Type: application/gzip" \
- --data-binary @- "$SIGNED_URL" 2>&1)
+UPLOAD_RESPONSE=$(curl -v -X PUT \
+ -H "Content-Type: binary/octet-stream" \
+ --data-binary "@dist/$FILENAME" "$SIGNED_URL" 2>&1)
if echo "$UPLOAD_RESPONSE" | grep -q "HTTP/[0-9.]* 200"; then
echo -e "\033[32mUploaded build to Stainless storage.\033[0m"
- echo -e "\033[32mInstallation: pip install --pre 'https://pkg.stainless.com/s/codex-python/$SHA'\033[0m"
+ echo -e "\033[32mInstallation: pip install 'https://pkg.stainless.com/s/codex-python/$SHA/$FILENAME'\033[0m"
else
echo -e "\033[31mFailed to upload artifact.\033[0m"
exit 1
From ab93d9d3990f52924b92518d6249f30783591a42 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 2 Jul 2025 19:17:27 +0000
Subject: [PATCH 10/18] feat(api): api update
---
.stats.yml | 2 +-
.../projects/query_log_list_by_group_response.py | 11 +++++++++++
.../types/projects/query_log_list_groups_response.py | 9 +++++++++
src/codex/types/projects/query_log_list_response.py | 9 +++++++++
.../types/projects/query_log_retrieve_response.py | 9 +++++++++
.../remediation_list_resolved_logs_response.py | 9 +++++++++
6 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/.stats.yml b/.stats.yml
index cc72a8a..08bc5f7 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,3 +1,3 @@
configured_endpoints: 55
-openapi_spec_hash: b2b026661b19d060e5eac490807fe445
+openapi_spec_hash: 06bae836118b9c7ac2cf1b5e1a576296
config_hash: 14b2643a0ec60cf326dfed00939644ff
diff --git a/src/codex/types/projects/query_log_list_by_group_response.py b/src/codex/types/projects/query_log_list_by_group_response.py
index c294d93..eeb4b63 100644
--- a/src/codex/types/projects/query_log_list_by_group_response.py
+++ b/src/codex/types/projects/query_log_list_by_group_response.py
@@ -13,6 +13,7 @@
"QueryLogsByGroupQueryLogFormattedEscalationEvalScores",
"QueryLogsByGroupQueryLogFormattedEvalScores",
"QueryLogsByGroupQueryLogFormattedGuardrailEvalScores",
+ "QueryLogsByGroupQueryLogFormattedNonGuardrailEvalScores",
"QueryLogsByGroupQueryLogContext",
]
@@ -35,6 +36,12 @@ class QueryLogsByGroupQueryLogFormattedGuardrailEvalScores(BaseModel):
status: Literal["pass", "fail"]
+class QueryLogsByGroupQueryLogFormattedNonGuardrailEvalScores(BaseModel):
+ score: float
+
+ status: Literal["pass", "fail"]
+
+
class QueryLogsByGroupQueryLogContext(BaseModel):
content: str
"""The actual content/text of the document."""
@@ -69,6 +76,10 @@ class QueryLogsByGroupQueryLog(BaseModel):
formatted_guardrail_eval_scores: Optional[Dict[str, QueryLogsByGroupQueryLogFormattedGuardrailEvalScores]] = None
+ formatted_non_guardrail_eval_scores: Optional[
+ Dict[str, QueryLogsByGroupQueryLogFormattedNonGuardrailEvalScores]
+ ] = None
+
is_bad_response: bool
needs_review: bool
diff --git a/src/codex/types/projects/query_log_list_groups_response.py b/src/codex/types/projects/query_log_list_groups_response.py
index ce5806b..074dfac 100644
--- a/src/codex/types/projects/query_log_list_groups_response.py
+++ b/src/codex/types/projects/query_log_list_groups_response.py
@@ -12,6 +12,7 @@
"QueryLogGroupFormattedEscalationEvalScores",
"QueryLogGroupFormattedEvalScores",
"QueryLogGroupFormattedGuardrailEvalScores",
+ "QueryLogGroupFormattedNonGuardrailEvalScores",
"QueryLogGroupContext",
]
@@ -34,6 +35,12 @@ class QueryLogGroupFormattedGuardrailEvalScores(BaseModel):
status: Literal["pass", "fail"]
+class QueryLogGroupFormattedNonGuardrailEvalScores(BaseModel):
+ score: float
+
+ status: Literal["pass", "fail"]
+
+
class QueryLogGroupContext(BaseModel):
content: str
"""The actual content/text of the document."""
@@ -68,6 +75,8 @@ class QueryLogGroup(BaseModel):
formatted_guardrail_eval_scores: Optional[Dict[str, QueryLogGroupFormattedGuardrailEvalScores]] = None
+ formatted_non_guardrail_eval_scores: Optional[Dict[str, QueryLogGroupFormattedNonGuardrailEvalScores]] = None
+
is_bad_response: bool
needs_review: bool
diff --git a/src/codex/types/projects/query_log_list_response.py b/src/codex/types/projects/query_log_list_response.py
index fa04904..09a9067 100644
--- a/src/codex/types/projects/query_log_list_response.py
+++ b/src/codex/types/projects/query_log_list_response.py
@@ -12,6 +12,7 @@
"QueryLogFormattedEscalationEvalScores",
"QueryLogFormattedEvalScores",
"QueryLogFormattedGuardrailEvalScores",
+ "QueryLogFormattedNonGuardrailEvalScores",
"QueryLogContext",
]
@@ -34,6 +35,12 @@ class QueryLogFormattedGuardrailEvalScores(BaseModel):
status: Literal["pass", "fail"]
+class QueryLogFormattedNonGuardrailEvalScores(BaseModel):
+ score: float
+
+ status: Literal["pass", "fail"]
+
+
class QueryLogContext(BaseModel):
content: str
"""The actual content/text of the document."""
@@ -68,6 +75,8 @@ class QueryLog(BaseModel):
formatted_guardrail_eval_scores: Optional[Dict[str, QueryLogFormattedGuardrailEvalScores]] = None
+ formatted_non_guardrail_eval_scores: Optional[Dict[str, QueryLogFormattedNonGuardrailEvalScores]] = None
+
is_bad_response: bool
project_id: str
diff --git a/src/codex/types/projects/query_log_retrieve_response.py b/src/codex/types/projects/query_log_retrieve_response.py
index 5214cff..3b2277d 100644
--- a/src/codex/types/projects/query_log_retrieve_response.py
+++ b/src/codex/types/projects/query_log_retrieve_response.py
@@ -11,6 +11,7 @@
"FormattedEscalationEvalScores",
"FormattedEvalScores",
"FormattedGuardrailEvalScores",
+ "FormattedNonGuardrailEvalScores",
"Context",
]
@@ -33,6 +34,12 @@ class FormattedGuardrailEvalScores(BaseModel):
status: Literal["pass", "fail"]
+class FormattedNonGuardrailEvalScores(BaseModel):
+ score: float
+
+ status: Literal["pass", "fail"]
+
+
class Context(BaseModel):
content: str
"""The actual content/text of the document."""
@@ -67,6 +74,8 @@ class QueryLogRetrieveResponse(BaseModel):
formatted_guardrail_eval_scores: Optional[Dict[str, FormattedGuardrailEvalScores]] = None
+ formatted_non_guardrail_eval_scores: Optional[Dict[str, FormattedNonGuardrailEvalScores]] = None
+
is_bad_response: bool
needs_review: bool
diff --git a/src/codex/types/projects/remediation_list_resolved_logs_response.py b/src/codex/types/projects/remediation_list_resolved_logs_response.py
index b2315aa..7e40fb4 100644
--- a/src/codex/types/projects/remediation_list_resolved_logs_response.py
+++ b/src/codex/types/projects/remediation_list_resolved_logs_response.py
@@ -12,6 +12,7 @@
"QueryLogFormattedEscalationEvalScores",
"QueryLogFormattedEvalScores",
"QueryLogFormattedGuardrailEvalScores",
+ "QueryLogFormattedNonGuardrailEvalScores",
"QueryLogContext",
]
@@ -34,6 +35,12 @@ class QueryLogFormattedGuardrailEvalScores(BaseModel):
status: Literal["pass", "fail"]
+class QueryLogFormattedNonGuardrailEvalScores(BaseModel):
+ score: float
+
+ status: Literal["pass", "fail"]
+
+
class QueryLogContext(BaseModel):
content: str
"""The actual content/text of the document."""
@@ -68,6 +75,8 @@ class QueryLog(BaseModel):
formatted_guardrail_eval_scores: Optional[Dict[str, QueryLogFormattedGuardrailEvalScores]] = None
+ formatted_non_guardrail_eval_scores: Optional[Dict[str, QueryLogFormattedNonGuardrailEvalScores]] = None
+
is_bad_response: bool
project_id: str
From 75b1e81e199ff4721ff21b3920bc82a48006df21 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 7 Jul 2025 17:17:40 +0000
Subject: [PATCH 11/18] feat(api): api update
---
.stats.yml | 2 +-
requirements-dev.lock | 2 +-
requirements.lock | 2 +-
src/codex/resources/projects/query_logs.py | 12 ++++++------
src/codex/types/project_validate_response.py | 15 +++++++++++++--
.../projects/query_log_list_by_group_params.py | 2 +-
.../projects/query_log_list_by_group_response.py | 12 ++++++++++++
.../projects/query_log_list_groups_params.py | 2 +-
.../projects/query_log_list_groups_response.py | 12 ++++++++++++
src/codex/types/projects/query_log_list_params.py | 2 +-
.../types/projects/query_log_list_response.py | 12 ++++++++++++
.../types/projects/query_log_retrieve_response.py | 12 ++++++++++++
.../remediation_list_resolved_logs_response.py | 12 ++++++++++++
13 files changed, 85 insertions(+), 14 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 08bc5f7..371ed3d 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,3 +1,3 @@
configured_endpoints: 55
-openapi_spec_hash: 06bae836118b9c7ac2cf1b5e1a576296
+openapi_spec_hash: f17890d85522687a4c68702da9ad2efb
config_hash: 14b2643a0ec60cf326dfed00939644ff
diff --git a/requirements-dev.lock b/requirements-dev.lock
index 11a2703..a84b5f4 100644
--- a/requirements-dev.lock
+++ b/requirements-dev.lock
@@ -56,7 +56,7 @@ httpx==0.28.1
# via codex-sdk
# via httpx-aiohttp
# via respx
-httpx-aiohttp==0.1.6
+httpx-aiohttp==0.1.8
# via codex-sdk
idna==3.4
# via anyio
diff --git a/requirements.lock b/requirements.lock
index 5eda9d9..a0807d8 100644
--- a/requirements.lock
+++ b/requirements.lock
@@ -43,7 +43,7 @@ httpcore==1.0.2
httpx==0.28.1
# via codex-sdk
# via httpx-aiohttp
-httpx-aiohttp==0.1.6
+httpx-aiohttp==0.1.8
# via codex-sdk
idna==3.4
# via anyio
diff --git a/src/codex/resources/projects/query_logs.py b/src/codex/resources/projects/query_logs.py
index e97243e..148df9f 100644
--- a/src/codex/resources/projects/query_logs.py
+++ b/src/codex/resources/projects/query_logs.py
@@ -99,7 +99,7 @@ def list(
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
passed_evals: Optional[List[str]] | NotGiven = NOT_GIVEN,
primary_eval_issue: Optional[
- List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "unsupported"]]
+ List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "ungrounded"]]
]
| NotGiven = NOT_GIVEN,
sort: Optional[Literal["created_at", "primary_eval_issue_score"]] | NotGiven = NOT_GIVEN,
@@ -184,7 +184,7 @@ def list_by_group(
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
passed_evals: Optional[List[str]] | NotGiven = NOT_GIVEN,
primary_eval_issue: Optional[
- List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "unsupported"]]
+ List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "ungrounded"]]
]
| NotGiven = NOT_GIVEN,
remediation_ids: List[str] | NotGiven = NOT_GIVEN,
@@ -276,7 +276,7 @@ def list_groups(
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
passed_evals: Optional[List[str]] | NotGiven = NOT_GIVEN,
primary_eval_issue: Optional[
- List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "unsupported"]]
+ List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "ungrounded"]]
]
| NotGiven = NOT_GIVEN,
sort: Optional[Literal["created_at", "primary_eval_issue_score", "total_count", "custom_rank"]]
@@ -457,7 +457,7 @@ async def list(
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
passed_evals: Optional[List[str]] | NotGiven = NOT_GIVEN,
primary_eval_issue: Optional[
- List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "unsupported"]]
+ List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "ungrounded"]]
]
| NotGiven = NOT_GIVEN,
sort: Optional[Literal["created_at", "primary_eval_issue_score"]] | NotGiven = NOT_GIVEN,
@@ -542,7 +542,7 @@ async def list_by_group(
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
passed_evals: Optional[List[str]] | NotGiven = NOT_GIVEN,
primary_eval_issue: Optional[
- List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "unsupported"]]
+ List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "ungrounded"]]
]
| NotGiven = NOT_GIVEN,
remediation_ids: List[str] | NotGiven = NOT_GIVEN,
@@ -634,7 +634,7 @@ async def list_groups(
order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
passed_evals: Optional[List[str]] | NotGiven = NOT_GIVEN,
primary_eval_issue: Optional[
- List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "unsupported"]]
+ List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "ungrounded"]]
]
| NotGiven = NOT_GIVEN,
sort: Optional[Literal["created_at", "primary_eval_issue_score", "total_count", "custom_rank"]]
diff --git a/src/codex/types/project_validate_response.py b/src/codex/types/project_validate_response.py
index db65f67..3b06db2 100644
--- a/src/codex/types/project_validate_response.py
+++ b/src/codex/types/project_validate_response.py
@@ -1,10 +1,18 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, Optional
+from typing import Dict, List, Optional
from .._models import BaseModel
-__all__ = ["ProjectValidateResponse", "EvalScores"]
+__all__ = ["ProjectValidateResponse", "DeterministicGuardrailsResults", "EvalScores"]
+
+
+class DeterministicGuardrailsResults(BaseModel):
+ guardrail_name: str
+
+ should_guardrail: bool
+
+ matches: Optional[List[str]] = None
class EvalScores(BaseModel):
@@ -22,6 +30,9 @@ class EvalScores(BaseModel):
class ProjectValidateResponse(BaseModel):
+ deterministic_guardrails_results: Optional[Dict[str, DeterministicGuardrailsResults]] = None
+ """Results from deterministic guardrails applied to the response."""
+
escalated_to_sme: bool
"""
True if the question should be escalated to Codex for an SME to review, False
diff --git a/src/codex/types/projects/query_log_list_by_group_params.py b/src/codex/types/projects/query_log_list_by_group_params.py
index b44970a..90bd386 100644
--- a/src/codex/types/projects/query_log_list_by_group_params.py
+++ b/src/codex/types/projects/query_log_list_by_group_params.py
@@ -40,7 +40,7 @@ class QueryLogListByGroupParams(TypedDict, total=False):
"""Filter by evals that passed"""
primary_eval_issue: Optional[
- List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "unsupported"]]
+ List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "ungrounded"]]
]
"""Filter logs that have ANY of these primary evaluation issues (OR operation)"""
diff --git a/src/codex/types/projects/query_log_list_by_group_response.py b/src/codex/types/projects/query_log_list_by_group_response.py
index eeb4b63..1685073 100644
--- a/src/codex/types/projects/query_log_list_by_group_response.py
+++ b/src/codex/types/projects/query_log_list_by_group_response.py
@@ -15,6 +15,7 @@
"QueryLogsByGroupQueryLogFormattedGuardrailEvalScores",
"QueryLogsByGroupQueryLogFormattedNonGuardrailEvalScores",
"QueryLogsByGroupQueryLogContext",
+ "QueryLogsByGroupQueryLogDeterministicGuardrailsResults",
]
@@ -59,6 +60,14 @@ class QueryLogsByGroupQueryLogContext(BaseModel):
"""Title or heading of the document. Useful for display and context."""
+class QueryLogsByGroupQueryLogDeterministicGuardrailsResults(BaseModel):
+ guardrail_name: str
+
+ should_guardrail: bool
+
+ matches: Optional[List[str]] = None
+
+
class QueryLogsByGroupQueryLog(BaseModel):
id: str
@@ -104,6 +113,9 @@ class QueryLogsByGroupQueryLog(BaseModel):
custom_metadata_keys: Optional[List[str]] = None
"""Keys of the custom metadata"""
+ deterministic_guardrails_results: Optional[Dict[str, QueryLogsByGroupQueryLogDeterministicGuardrailsResults]] = None
+ """Results of deterministic guardrails applied to the query"""
+
escalated: Optional[bool] = None
"""If true, the question was escalated to Codex for an SME to review"""
diff --git a/src/codex/types/projects/query_log_list_groups_params.py b/src/codex/types/projects/query_log_list_groups_params.py
index 94d549f..cd82d9a 100644
--- a/src/codex/types/projects/query_log_list_groups_params.py
+++ b/src/codex/types/projects/query_log_list_groups_params.py
@@ -40,7 +40,7 @@ class QueryLogListGroupsParams(TypedDict, total=False):
"""Filter by evals that passed"""
primary_eval_issue: Optional[
- List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "unsupported"]]
+ List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "ungrounded"]]
]
"""Filter logs that have ANY of these primary evaluation issues (OR operation)"""
diff --git a/src/codex/types/projects/query_log_list_groups_response.py b/src/codex/types/projects/query_log_list_groups_response.py
index 074dfac..e77dd87 100644
--- a/src/codex/types/projects/query_log_list_groups_response.py
+++ b/src/codex/types/projects/query_log_list_groups_response.py
@@ -14,6 +14,7 @@
"QueryLogGroupFormattedGuardrailEvalScores",
"QueryLogGroupFormattedNonGuardrailEvalScores",
"QueryLogGroupContext",
+ "QueryLogGroupDeterministicGuardrailsResults",
]
@@ -58,6 +59,14 @@ class QueryLogGroupContext(BaseModel):
"""Title or heading of the document. Useful for display and context."""
+class QueryLogGroupDeterministicGuardrailsResults(BaseModel):
+ guardrail_name: str
+
+ should_guardrail: bool
+
+ matches: Optional[List[str]] = None
+
+
class QueryLogGroup(BaseModel):
id: str
@@ -103,6 +112,9 @@ class QueryLogGroup(BaseModel):
custom_metadata_keys: Optional[List[str]] = None
"""Keys of the custom metadata"""
+ deterministic_guardrails_results: Optional[Dict[str, QueryLogGroupDeterministicGuardrailsResults]] = None
+ """Results of deterministic guardrails applied to the query"""
+
escalated: Optional[bool] = None
"""If true, the question was escalated to Codex for an SME to review"""
diff --git a/src/codex/types/projects/query_log_list_params.py b/src/codex/types/projects/query_log_list_params.py
index 0f72b24..5892d3c 100644
--- a/src/codex/types/projects/query_log_list_params.py
+++ b/src/codex/types/projects/query_log_list_params.py
@@ -37,7 +37,7 @@ class QueryLogListParams(TypedDict, total=False):
"""Filter by evals that passed"""
primary_eval_issue: Optional[
- List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "unsupported"]]
+ List[Literal["hallucination", "search_failure", "unhelpful", "difficult_query", "ungrounded"]]
]
"""Filter logs that have ANY of these primary evaluation issues (OR operation)"""
diff --git a/src/codex/types/projects/query_log_list_response.py b/src/codex/types/projects/query_log_list_response.py
index 09a9067..147478c 100644
--- a/src/codex/types/projects/query_log_list_response.py
+++ b/src/codex/types/projects/query_log_list_response.py
@@ -14,6 +14,7 @@
"QueryLogFormattedGuardrailEvalScores",
"QueryLogFormattedNonGuardrailEvalScores",
"QueryLogContext",
+ "QueryLogDeterministicGuardrailsResults",
]
@@ -58,6 +59,14 @@ class QueryLogContext(BaseModel):
"""Title or heading of the document. Useful for display and context."""
+class QueryLogDeterministicGuardrailsResults(BaseModel):
+ guardrail_name: str
+
+ should_guardrail: bool
+
+ matches: Optional[List[str]] = None
+
+
class QueryLog(BaseModel):
id: str
@@ -97,6 +106,9 @@ class QueryLog(BaseModel):
custom_metadata_keys: Optional[List[str]] = None
"""Keys of the custom metadata"""
+ deterministic_guardrails_results: Optional[Dict[str, QueryLogDeterministicGuardrailsResults]] = None
+ """Results of deterministic guardrails applied to the query"""
+
escalated: Optional[bool] = None
"""If true, the question was escalated to Codex for an SME to review"""
diff --git a/src/codex/types/projects/query_log_retrieve_response.py b/src/codex/types/projects/query_log_retrieve_response.py
index 3b2277d..380bacb 100644
--- a/src/codex/types/projects/query_log_retrieve_response.py
+++ b/src/codex/types/projects/query_log_retrieve_response.py
@@ -13,6 +13,7 @@
"FormattedGuardrailEvalScores",
"FormattedNonGuardrailEvalScores",
"Context",
+ "DeterministicGuardrailsResults",
]
@@ -57,6 +58,14 @@ class Context(BaseModel):
"""Title or heading of the document. Useful for display and context."""
+class DeterministicGuardrailsResults(BaseModel):
+ guardrail_name: str
+
+ should_guardrail: bool
+
+ matches: Optional[List[str]] = None
+
+
class QueryLogRetrieveResponse(BaseModel):
id: str
@@ -100,6 +109,9 @@ class QueryLogRetrieveResponse(BaseModel):
custom_metadata_keys: Optional[List[str]] = None
"""Keys of the custom metadata"""
+ deterministic_guardrails_results: Optional[Dict[str, DeterministicGuardrailsResults]] = None
+ """Results of deterministic guardrails applied to the query"""
+
escalated: Optional[bool] = None
"""If true, the question was escalated to Codex for an SME to review"""
diff --git a/src/codex/types/projects/remediation_list_resolved_logs_response.py b/src/codex/types/projects/remediation_list_resolved_logs_response.py
index 7e40fb4..876e7ce 100644
--- a/src/codex/types/projects/remediation_list_resolved_logs_response.py
+++ b/src/codex/types/projects/remediation_list_resolved_logs_response.py
@@ -14,6 +14,7 @@
"QueryLogFormattedGuardrailEvalScores",
"QueryLogFormattedNonGuardrailEvalScores",
"QueryLogContext",
+ "QueryLogDeterministicGuardrailsResults",
]
@@ -58,6 +59,14 @@ class QueryLogContext(BaseModel):
"""Title or heading of the document. Useful for display and context."""
+class QueryLogDeterministicGuardrailsResults(BaseModel):
+ guardrail_name: str
+
+ should_guardrail: bool
+
+ matches: Optional[List[str]] = None
+
+
class QueryLog(BaseModel):
id: str
@@ -97,6 +106,9 @@ class QueryLog(BaseModel):
custom_metadata_keys: Optional[List[str]] = None
"""Keys of the custom metadata"""
+ deterministic_guardrails_results: Optional[Dict[str, QueryLogDeterministicGuardrailsResults]] = None
+ """Results of deterministic guardrails applied to the query"""
+
escalated: Optional[bool] = None
"""If true, the question was escalated to Codex for an SME to review"""
From bc15e9004a8f3a2b311ceeb851b5f6a666a2698b Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 7 Jul 2025 23:36:29 +0000
Subject: [PATCH 12/18] feat(api): api update
---
.stats.yml | 2 +-
src/codex/resources/projects/projects.py | 42 ++--
src/codex/types/project_validate_params.py | 279 ++++++++++++++++++++-
tests/api_resources/test_projects.py | 34 ++-
4 files changed, 315 insertions(+), 42 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 371ed3d..c8908e8 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,3 +1,3 @@
configured_endpoints: 55
-openapi_spec_hash: f17890d85522687a4c68702da9ad2efb
+openapi_spec_hash: 922886934580d0b2addcb6e26ada0e09
config_hash: 14b2643a0ec60cf326dfed00939644ff
diff --git a/src/codex/resources/projects/projects.py b/src/codex/resources/projects/projects.py
index 1314b7b..dc01b11 100644
--- a/src/codex/resources/projects/projects.py
+++ b/src/codex/resources/projects/projects.py
@@ -488,17 +488,18 @@ def validate(
project_id: str,
*,
context: str,
- prompt: str,
query: str,
- response: str,
+ response: project_validate_params.Response,
use_llm_matching: bool | NotGiven = NOT_GIVEN,
constrain_outputs: Optional[List[str]] | NotGiven = NOT_GIVEN,
custom_eval_thresholds: Optional[Dict[str, float]] | NotGiven = NOT_GIVEN,
custom_metadata: Optional[object] | NotGiven = NOT_GIVEN,
eval_scores: Optional[Dict[str, float]] | NotGiven = NOT_GIVEN,
- messages: Optional[Iterable[project_validate_params.Message]] | NotGiven = NOT_GIVEN,
+ messages: Iterable[project_validate_params.Message] | NotGiven = NOT_GIVEN,
options: Optional[project_validate_params.Options] | NotGiven = NOT_GIVEN,
+ prompt: Optional[str] | NotGiven = NOT_GIVEN,
quality_preset: Literal["best", "high", "medium", "low", "base"] | NotGiven = NOT_GIVEN,
+ rewritten_question: Optional[str] | NotGiven = NOT_GIVEN,
task: Optional[str] | NotGiven = NOT_GIVEN,
x_client_library_version: str | NotGiven = NOT_GIVEN,
x_integration_type: str | NotGiven = NOT_GIVEN,
@@ -526,9 +527,8 @@ def validate(
eval_scores: Scores assessing different aspects of the RAG system. If not provided, TLM will
be used to generate scores.
- messages: Optional message history to provide conversation context for the query. Used to
- rewrite query into a self-contained version of itself. If not provided, the
- query will be treated as self-contained.
+ messages: Message history to provide conversation context for the query. Messages contain
+ up to and including the latest user prompt to the LLM.
options: Typed dict of advanced configuration options for the Trustworthy Language Model.
Many of these configurations are determined by the quality preset selected
@@ -615,8 +615,14 @@ def validate(
- name: Name of the evaluation criteria.
- criteria: Instructions specifying the evaluation criteria.
+ prompt: The prompt to use for the TLM call. If not provided, the prompt will be
+ generated from the messages.
+
quality_preset: The quality preset to use for the TLM or Trustworthy RAG API.
+ rewritten_question: The re-written query if it was provided by the client to Codex from a user to be
+ used instead of the original query.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -643,7 +649,6 @@ def validate(
body=maybe_transform(
{
"context": context,
- "prompt": prompt,
"query": query,
"response": response,
"constrain_outputs": constrain_outputs,
@@ -652,7 +657,9 @@ def validate(
"eval_scores": eval_scores,
"messages": messages,
"options": options,
+ "prompt": prompt,
"quality_preset": quality_preset,
+ "rewritten_question": rewritten_question,
"task": task,
},
project_validate_params.ProjectValidateParams,
@@ -1090,17 +1097,18 @@ async def validate(
project_id: str,
*,
context: str,
- prompt: str,
query: str,
- response: str,
+ response: project_validate_params.Response,
use_llm_matching: bool | NotGiven = NOT_GIVEN,
constrain_outputs: Optional[List[str]] | NotGiven = NOT_GIVEN,
custom_eval_thresholds: Optional[Dict[str, float]] | NotGiven = NOT_GIVEN,
custom_metadata: Optional[object] | NotGiven = NOT_GIVEN,
eval_scores: Optional[Dict[str, float]] | NotGiven = NOT_GIVEN,
- messages: Optional[Iterable[project_validate_params.Message]] | NotGiven = NOT_GIVEN,
+ messages: Iterable[project_validate_params.Message] | NotGiven = NOT_GIVEN,
options: Optional[project_validate_params.Options] | NotGiven = NOT_GIVEN,
+ prompt: Optional[str] | NotGiven = NOT_GIVEN,
quality_preset: Literal["best", "high", "medium", "low", "base"] | NotGiven = NOT_GIVEN,
+ rewritten_question: Optional[str] | NotGiven = NOT_GIVEN,
task: Optional[str] | NotGiven = NOT_GIVEN,
x_client_library_version: str | NotGiven = NOT_GIVEN,
x_integration_type: str | NotGiven = NOT_GIVEN,
@@ -1128,9 +1136,8 @@ async def validate(
eval_scores: Scores assessing different aspects of the RAG system. If not provided, TLM will
be used to generate scores.
- messages: Optional message history to provide conversation context for the query. Used to
- rewrite query into a self-contained version of itself. If not provided, the
- query will be treated as self-contained.
+ messages: Message history to provide conversation context for the query. Messages contain
+ up to and including the latest user prompt to the LLM.
options: Typed dict of advanced configuration options for the Trustworthy Language Model.
Many of these configurations are determined by the quality preset selected
@@ -1217,8 +1224,14 @@ async def validate(
- name: Name of the evaluation criteria.
- criteria: Instructions specifying the evaluation criteria.
+ prompt: The prompt to use for the TLM call. If not provided, the prompt will be
+ generated from the messages.
+
quality_preset: The quality preset to use for the TLM or Trustworthy RAG API.
+ rewritten_question: The re-written query if it was provided by the client to Codex from a user to be
+ used instead of the original query.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1245,7 +1258,6 @@ async def validate(
body=await async_maybe_transform(
{
"context": context,
- "prompt": prompt,
"query": query,
"response": response,
"constrain_outputs": constrain_outputs,
@@ -1254,7 +1266,9 @@ async def validate(
"eval_scores": eval_scores,
"messages": messages,
"options": options,
+ "prompt": prompt,
"quality_preset": quality_preset,
+ "rewritten_question": rewritten_question,
"task": task,
},
project_validate_params.ProjectValidateParams,
diff --git a/src/codex/types/project_validate_params.py b/src/codex/types/project_validate_params.py
index 8b38ebf..0862cbc 100644
--- a/src/codex/types/project_validate_params.py
+++ b/src/codex/types/project_validate_params.py
@@ -2,6 +2,7 @@
from __future__ import annotations
+import builtins
from typing import Dict, List, Union, Iterable, Optional
from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict
@@ -9,6 +10,24 @@
__all__ = [
"ProjectValidateParams",
+ "Response",
+ "ResponseChatCompletion",
+ "ResponseChatCompletionChoice",
+ "ResponseChatCompletionChoiceMessage",
+ "ResponseChatCompletionChoiceMessageAnnotation",
+ "ResponseChatCompletionChoiceMessageAnnotationURLCitation",
+ "ResponseChatCompletionChoiceMessageAudio",
+ "ResponseChatCompletionChoiceMessageFunctionCall",
+ "ResponseChatCompletionChoiceMessageToolCall",
+ "ResponseChatCompletionChoiceMessageToolCallFunction",
+ "ResponseChatCompletionChoiceLogprobs",
+ "ResponseChatCompletionChoiceLogprobsContent",
+ "ResponseChatCompletionChoiceLogprobsContentTopLogprob",
+ "ResponseChatCompletionChoiceLogprobsRefusal",
+ "ResponseChatCompletionChoiceLogprobsRefusalTopLogprob",
+ "ResponseChatCompletionUsage",
+ "ResponseChatCompletionUsageCompletionTokensDetails",
+ "ResponseChatCompletionUsagePromptTokensDetails",
"Message",
"MessageChatCompletionDeveloperMessageParam",
"MessageChatCompletionDeveloperMessageParamContentUnionMember1",
@@ -41,11 +60,9 @@
class ProjectValidateParams(TypedDict, total=False):
context: Required[str]
- prompt: Required[str]
-
query: Required[str]
- response: Required[str]
+ response: Required[Response]
use_llm_matching: bool
@@ -66,11 +83,10 @@ class ProjectValidateParams(TypedDict, total=False):
If not provided, TLM will be used to generate scores.
"""
- messages: Optional[Iterable[Message]]
- """Optional message history to provide conversation context for the query.
+ messages: Iterable[Message]
+ """Message history to provide conversation context for the query.
- Used to rewrite query into a self-contained version of itself. If not provided,
- the query will be treated as self-contained.
+ Messages contain up to and including the latest user prompt to the LLM.
"""
options: Optional[Options]
@@ -161,9 +177,21 @@ class ProjectValidateParams(TypedDict, total=False):
- criteria: Instructions specifying the evaluation criteria.
"""
+ prompt: Optional[str]
+ """The prompt to use for the TLM call.
+
+ If not provided, the prompt will be generated from the messages.
+ """
+
quality_preset: Literal["best", "high", "medium", "low", "base"]
"""The quality preset to use for the TLM or Trustworthy RAG API."""
+ rewritten_question: Optional[str]
+ """
+ The re-written query if it was provided by the client to Codex from a user to be
+ used instead of the original query.
+ """
+
task: Optional[str]
x_client_library_version: Annotated[str, PropertyInfo(alias="x-client-library-version")]
@@ -175,6 +203,243 @@ class ProjectValidateParams(TypedDict, total=False):
x_stainless_package_version: Annotated[str, PropertyInfo(alias="x-stainless-package-version")]
+class ResponseChatCompletionChoiceMessageAnnotationURLCitationTyped(TypedDict, total=False):
+ end_index: Required[int]
+
+ start_index: Required[int]
+
+ title: Required[str]
+
+ url: Required[str]
+
+
+ResponseChatCompletionChoiceMessageAnnotationURLCitation: TypeAlias = Union[
+ ResponseChatCompletionChoiceMessageAnnotationURLCitationTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionChoiceMessageAnnotationTyped(TypedDict, total=False):
+ type: Required[Literal["url_citation"]]
+
+ url_citation: Required[ResponseChatCompletionChoiceMessageAnnotationURLCitation]
+
+
+ResponseChatCompletionChoiceMessageAnnotation: TypeAlias = Union[
+ ResponseChatCompletionChoiceMessageAnnotationTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionChoiceMessageAudioTyped(TypedDict, total=False):
+ id: Required[str]
+
+ data: Required[str]
+
+ expires_at: Required[int]
+
+ transcript: Required[str]
+
+
+ResponseChatCompletionChoiceMessageAudio: TypeAlias = Union[
+ ResponseChatCompletionChoiceMessageAudioTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionChoiceMessageFunctionCallTyped(TypedDict, total=False):
+ arguments: Required[str]
+
+ name: Required[str]
+
+
+ResponseChatCompletionChoiceMessageFunctionCall: TypeAlias = Union[
+ ResponseChatCompletionChoiceMessageFunctionCallTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionChoiceMessageToolCallFunctionTyped(TypedDict, total=False):
+ arguments: Required[str]
+
+ name: Required[str]
+
+
+ResponseChatCompletionChoiceMessageToolCallFunction: TypeAlias = Union[
+ ResponseChatCompletionChoiceMessageToolCallFunctionTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionChoiceMessageToolCallTyped(TypedDict, total=False):
+ id: Required[str]
+
+ function: Required[ResponseChatCompletionChoiceMessageToolCallFunction]
+
+ type: Required[Literal["function"]]
+
+
+ResponseChatCompletionChoiceMessageToolCall: TypeAlias = Union[
+ ResponseChatCompletionChoiceMessageToolCallTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionChoiceMessageTyped(TypedDict, total=False):
+ role: Required[Literal["assistant"]]
+
+ annotations: Optional[Iterable[ResponseChatCompletionChoiceMessageAnnotation]]
+
+ audio: Optional[ResponseChatCompletionChoiceMessageAudio]
+
+ content: Optional[str]
+
+ function_call: Optional[ResponseChatCompletionChoiceMessageFunctionCall]
+
+ refusal: Optional[str]
+
+ tool_calls: Optional[Iterable[ResponseChatCompletionChoiceMessageToolCall]]
+
+
+ResponseChatCompletionChoiceMessage: TypeAlias = Union[ResponseChatCompletionChoiceMessageTyped, Dict[str, object]]
+
+
+class ResponseChatCompletionChoiceLogprobsContentTopLogprobTyped(TypedDict, total=False):
+ token: Required[str]
+
+ logprob: Required[float]
+
+ bytes: Optional[Iterable[int]]
+
+
+ResponseChatCompletionChoiceLogprobsContentTopLogprob: TypeAlias = Union[
+ ResponseChatCompletionChoiceLogprobsContentTopLogprobTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionChoiceLogprobsContentTyped(TypedDict, total=False):
+ token: Required[str]
+
+ logprob: Required[float]
+
+ top_logprobs: Required[Iterable[ResponseChatCompletionChoiceLogprobsContentTopLogprob]]
+
+ bytes: Optional[Iterable[int]]
+
+
+ResponseChatCompletionChoiceLogprobsContent: TypeAlias = Union[
+ ResponseChatCompletionChoiceLogprobsContentTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionChoiceLogprobsRefusalTopLogprobTyped(TypedDict, total=False):
+ token: Required[str]
+
+ logprob: Required[float]
+
+ bytes: Optional[Iterable[int]]
+
+
+ResponseChatCompletionChoiceLogprobsRefusalTopLogprob: TypeAlias = Union[
+ ResponseChatCompletionChoiceLogprobsRefusalTopLogprobTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionChoiceLogprobsRefusalTyped(TypedDict, total=False):
+ token: Required[str]
+
+ logprob: Required[float]
+
+ top_logprobs: Required[Iterable[ResponseChatCompletionChoiceLogprobsRefusalTopLogprob]]
+
+ bytes: Optional[Iterable[int]]
+
+
+ResponseChatCompletionChoiceLogprobsRefusal: TypeAlias = Union[
+ ResponseChatCompletionChoiceLogprobsRefusalTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionChoiceLogprobsTyped(TypedDict, total=False):
+ content: Optional[Iterable[ResponseChatCompletionChoiceLogprobsContent]]
+
+ refusal: Optional[Iterable[ResponseChatCompletionChoiceLogprobsRefusal]]
+
+
+ResponseChatCompletionChoiceLogprobs: TypeAlias = Union[ResponseChatCompletionChoiceLogprobsTyped, Dict[str, object]]
+
+
+class ResponseChatCompletionChoiceTyped(TypedDict, total=False):
+ finish_reason: Required[Literal["stop", "length", "tool_calls", "content_filter", "function_call"]]
+
+ index: Required[int]
+
+ message: Required[ResponseChatCompletionChoiceMessage]
+
+ logprobs: Optional[ResponseChatCompletionChoiceLogprobs]
+
+
+ResponseChatCompletionChoice: TypeAlias = Union[ResponseChatCompletionChoiceTyped, Dict[str, object]]
+
+
+class ResponseChatCompletionUsageCompletionTokensDetailsTyped(TypedDict, total=False):
+ accepted_prediction_tokens: Optional[int]
+
+ audio_tokens: Optional[int]
+
+ reasoning_tokens: Optional[int]
+
+ rejected_prediction_tokens: Optional[int]
+
+
+ResponseChatCompletionUsageCompletionTokensDetails: TypeAlias = Union[
+ ResponseChatCompletionUsageCompletionTokensDetailsTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionUsagePromptTokensDetailsTyped(TypedDict, total=False):
+ audio_tokens: Optional[int]
+
+ cached_tokens: Optional[int]
+
+
+ResponseChatCompletionUsagePromptTokensDetails: TypeAlias = Union[
+ ResponseChatCompletionUsagePromptTokensDetailsTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionUsageTyped(TypedDict, total=False):
+ completion_tokens: Required[int]
+
+ prompt_tokens: Required[int]
+
+ total_tokens: Required[int]
+
+ completion_tokens_details: Optional[ResponseChatCompletionUsageCompletionTokensDetails]
+
+ prompt_tokens_details: Optional[ResponseChatCompletionUsagePromptTokensDetails]
+
+
+ResponseChatCompletionUsage: TypeAlias = Union[ResponseChatCompletionUsageTyped, Dict[str, object]]
+
+
+class ResponseChatCompletionTyped(TypedDict, total=False):
+ id: Required[str]
+
+ choices: Required[Iterable[ResponseChatCompletionChoice]]
+
+ created: Required[int]
+
+ model: Required[str]
+
+ object: Required[Literal["chat.completion"]]
+
+ service_tier: Optional[Literal["scale", "default"]]
+
+ system_fingerprint: Optional[str]
+
+ usage: Optional[ResponseChatCompletionUsage]
+
+
+ResponseChatCompletion: TypeAlias = Union[ResponseChatCompletionTyped, Dict[str, builtins.object]]
+
+Response: TypeAlias = Union[str, ResponseChatCompletion]
+
+
class MessageChatCompletionDeveloperMessageParamContentUnionMember1(TypedDict, total=False):
text: Required[str]
diff --git a/tests/api_resources/test_projects.py b/tests/api_resources/test_projects.py
index 0764d9a..9ecffa0 100644
--- a/tests/api_resources/test_projects.py
+++ b/tests/api_resources/test_projects.py
@@ -632,9 +632,8 @@ def test_method_validate(self, client: Codex) -> None:
project = client.projects.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
- prompt="prompt",
query="query",
- response="response",
+ response="string",
)
assert_matches_type(ProjectValidateResponse, project, path=["response"])
@@ -644,9 +643,8 @@ def test_method_validate_with_all_params(self, client: Codex) -> None:
project = client.projects.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
- prompt="prompt",
query="query",
- response="response",
+ response="string",
use_llm_matching=True,
constrain_outputs=["string"],
custom_eval_thresholds={"foo": 0},
@@ -670,7 +668,9 @@ def test_method_validate_with_all_params(self, client: Codex) -> None:
"similarity_measure": "similarity_measure",
"use_self_reflection": True,
},
+ prompt="prompt",
quality_preset="best",
+ rewritten_question="rewritten_question",
task="task",
x_client_library_version="x-client-library-version",
x_integration_type="x-integration-type",
@@ -685,9 +685,8 @@ def test_raw_response_validate(self, client: Codex) -> None:
response = client.projects.with_raw_response.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
- prompt="prompt",
query="query",
- response="response",
+ response="string",
)
assert response.is_closed is True
@@ -701,9 +700,8 @@ def test_streaming_response_validate(self, client: Codex) -> None:
with client.projects.with_streaming_response.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
- prompt="prompt",
query="query",
- response="response",
+ response="string",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -720,9 +718,8 @@ def test_path_params_validate(self, client: Codex) -> None:
client.projects.with_raw_response.validate(
project_id="",
context="context",
- prompt="prompt",
query="query",
- response="response",
+ response="string",
)
@@ -1337,9 +1334,8 @@ async def test_method_validate(self, async_client: AsyncCodex) -> None:
project = await async_client.projects.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
- prompt="prompt",
query="query",
- response="response",
+ response="string",
)
assert_matches_type(ProjectValidateResponse, project, path=["response"])
@@ -1349,9 +1345,8 @@ async def test_method_validate_with_all_params(self, async_client: AsyncCodex) -
project = await async_client.projects.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
- prompt="prompt",
query="query",
- response="response",
+ response="string",
use_llm_matching=True,
constrain_outputs=["string"],
custom_eval_thresholds={"foo": 0},
@@ -1375,7 +1370,9 @@ async def test_method_validate_with_all_params(self, async_client: AsyncCodex) -
"similarity_measure": "similarity_measure",
"use_self_reflection": True,
},
+ prompt="prompt",
quality_preset="best",
+ rewritten_question="rewritten_question",
task="task",
x_client_library_version="x-client-library-version",
x_integration_type="x-integration-type",
@@ -1390,9 +1387,8 @@ async def test_raw_response_validate(self, async_client: AsyncCodex) -> None:
response = await async_client.projects.with_raw_response.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
- prompt="prompt",
query="query",
- response="response",
+ response="string",
)
assert response.is_closed is True
@@ -1406,9 +1402,8 @@ async def test_streaming_response_validate(self, async_client: AsyncCodex) -> No
async with async_client.projects.with_streaming_response.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
- prompt="prompt",
query="query",
- response="response",
+ response="string",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -1425,7 +1420,6 @@ async def test_path_params_validate(self, async_client: AsyncCodex) -> None:
await async_client.projects.with_raw_response.validate(
project_id="",
context="context",
- prompt="prompt",
query="query",
- response="response",
+ response="string",
)
From e80bee98b4f91ca7c0c19509d1f6a4f9f6bfd2c7 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 7 Jul 2025 23:38:16 +0000
Subject: [PATCH 13/18] feat(api): remove entries routes
---
.stats.yml | 4 +-
src/codex/pagination.py | 62 -----
src/codex/resources/projects/projects.py | 42 ++--
src/codex/types/project_validate_params.py | 279 +--------------------
tests/api_resources/test_projects.py | 34 +--
5 files changed, 43 insertions(+), 378 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index c8908e8..d7fdc0e 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,3 +1,3 @@
configured_endpoints: 55
-openapi_spec_hash: 922886934580d0b2addcb6e26ada0e09
-config_hash: 14b2643a0ec60cf326dfed00939644ff
+openapi_spec_hash: f17890d85522687a4c68702da9ad2efb
+config_hash: e62d723b4a5c564dc05390753a876f31
diff --git a/src/codex/pagination.py b/src/codex/pagination.py
index 1f590df..8057f2e 100644
--- a/src/codex/pagination.py
+++ b/src/codex/pagination.py
@@ -14,8 +14,6 @@
"AsyncMyOffsetPageTopLevelArray",
"SyncOffsetPageClusters",
"AsyncOffsetPageClusters",
- "SyncOffsetPageEntries",
- "AsyncOffsetPageEntries",
]
_BaseModelT = TypeVar("_BaseModelT", bound=BaseModel)
@@ -143,63 +141,3 @@ def next_page_info(self) -> Optional[PageInfo]:
return PageInfo(params={"offset": current_count})
return None
-
-
-class SyncOffsetPageEntries(BaseSyncPage[_T], BasePage[_T], Generic[_T]):
- entries: List[_T]
- total_count: Optional[int] = None
-
- @override
- def _get_page_items(self) -> List[_T]:
- entries = self.entries
- if not entries:
- return []
- return entries
-
- @override
- def next_page_info(self) -> Optional[PageInfo]:
- offset = self._options.params.get("offset") or 0
- if not isinstance(offset, int):
- raise ValueError(f'Expected "offset" param to be an integer but got {offset}')
-
- length = len(self._get_page_items())
- current_count = offset + length
-
- total_count = self.total_count
- if total_count is None:
- return None
-
- if current_count < total_count:
- return PageInfo(params={"offset": current_count})
-
- return None
-
-
-class AsyncOffsetPageEntries(BaseAsyncPage[_T], BasePage[_T], Generic[_T]):
- entries: List[_T]
- total_count: Optional[int] = None
-
- @override
- def _get_page_items(self) -> List[_T]:
- entries = self.entries
- if not entries:
- return []
- return entries
-
- @override
- def next_page_info(self) -> Optional[PageInfo]:
- offset = self._options.params.get("offset") or 0
- if not isinstance(offset, int):
- raise ValueError(f'Expected "offset" param to be an integer but got {offset}')
-
- length = len(self._get_page_items())
- current_count = offset + length
-
- total_count = self.total_count
- if total_count is None:
- return None
-
- if current_count < total_count:
- return PageInfo(params={"offset": current_count})
-
- return None
diff --git a/src/codex/resources/projects/projects.py b/src/codex/resources/projects/projects.py
index dc01b11..1314b7b 100644
--- a/src/codex/resources/projects/projects.py
+++ b/src/codex/resources/projects/projects.py
@@ -488,18 +488,17 @@ def validate(
project_id: str,
*,
context: str,
+ prompt: str,
query: str,
- response: project_validate_params.Response,
+ response: str,
use_llm_matching: bool | NotGiven = NOT_GIVEN,
constrain_outputs: Optional[List[str]] | NotGiven = NOT_GIVEN,
custom_eval_thresholds: Optional[Dict[str, float]] | NotGiven = NOT_GIVEN,
custom_metadata: Optional[object] | NotGiven = NOT_GIVEN,
eval_scores: Optional[Dict[str, float]] | NotGiven = NOT_GIVEN,
- messages: Iterable[project_validate_params.Message] | NotGiven = NOT_GIVEN,
+ messages: Optional[Iterable[project_validate_params.Message]] | NotGiven = NOT_GIVEN,
options: Optional[project_validate_params.Options] | NotGiven = NOT_GIVEN,
- prompt: Optional[str] | NotGiven = NOT_GIVEN,
quality_preset: Literal["best", "high", "medium", "low", "base"] | NotGiven = NOT_GIVEN,
- rewritten_question: Optional[str] | NotGiven = NOT_GIVEN,
task: Optional[str] | NotGiven = NOT_GIVEN,
x_client_library_version: str | NotGiven = NOT_GIVEN,
x_integration_type: str | NotGiven = NOT_GIVEN,
@@ -527,8 +526,9 @@ def validate(
eval_scores: Scores assessing different aspects of the RAG system. If not provided, TLM will
be used to generate scores.
- messages: Message history to provide conversation context for the query. Messages contain
- up to and including the latest user prompt to the LLM.
+ messages: Optional message history to provide conversation context for the query. Used to
+ rewrite query into a self-contained version of itself. If not provided, the
+ query will be treated as self-contained.
options: Typed dict of advanced configuration options for the Trustworthy Language Model.
Many of these configurations are determined by the quality preset selected
@@ -615,14 +615,8 @@ def validate(
- name: Name of the evaluation criteria.
- criteria: Instructions specifying the evaluation criteria.
- prompt: The prompt to use for the TLM call. If not provided, the prompt will be
- generated from the messages.
-
quality_preset: The quality preset to use for the TLM or Trustworthy RAG API.
- rewritten_question: The re-written query if it was provided by the client to Codex from a user to be
- used instead of the original query.
-
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -649,6 +643,7 @@ def validate(
body=maybe_transform(
{
"context": context,
+ "prompt": prompt,
"query": query,
"response": response,
"constrain_outputs": constrain_outputs,
@@ -657,9 +652,7 @@ def validate(
"eval_scores": eval_scores,
"messages": messages,
"options": options,
- "prompt": prompt,
"quality_preset": quality_preset,
- "rewritten_question": rewritten_question,
"task": task,
},
project_validate_params.ProjectValidateParams,
@@ -1097,18 +1090,17 @@ async def validate(
project_id: str,
*,
context: str,
+ prompt: str,
query: str,
- response: project_validate_params.Response,
+ response: str,
use_llm_matching: bool | NotGiven = NOT_GIVEN,
constrain_outputs: Optional[List[str]] | NotGiven = NOT_GIVEN,
custom_eval_thresholds: Optional[Dict[str, float]] | NotGiven = NOT_GIVEN,
custom_metadata: Optional[object] | NotGiven = NOT_GIVEN,
eval_scores: Optional[Dict[str, float]] | NotGiven = NOT_GIVEN,
- messages: Iterable[project_validate_params.Message] | NotGiven = NOT_GIVEN,
+ messages: Optional[Iterable[project_validate_params.Message]] | NotGiven = NOT_GIVEN,
options: Optional[project_validate_params.Options] | NotGiven = NOT_GIVEN,
- prompt: Optional[str] | NotGiven = NOT_GIVEN,
quality_preset: Literal["best", "high", "medium", "low", "base"] | NotGiven = NOT_GIVEN,
- rewritten_question: Optional[str] | NotGiven = NOT_GIVEN,
task: Optional[str] | NotGiven = NOT_GIVEN,
x_client_library_version: str | NotGiven = NOT_GIVEN,
x_integration_type: str | NotGiven = NOT_GIVEN,
@@ -1136,8 +1128,9 @@ async def validate(
eval_scores: Scores assessing different aspects of the RAG system. If not provided, TLM will
be used to generate scores.
- messages: Message history to provide conversation context for the query. Messages contain
- up to and including the latest user prompt to the LLM.
+ messages: Optional message history to provide conversation context for the query. Used to
+ rewrite query into a self-contained version of itself. If not provided, the
+ query will be treated as self-contained.
options: Typed dict of advanced configuration options for the Trustworthy Language Model.
Many of these configurations are determined by the quality preset selected
@@ -1224,14 +1217,8 @@ async def validate(
- name: Name of the evaluation criteria.
- criteria: Instructions specifying the evaluation criteria.
- prompt: The prompt to use for the TLM call. If not provided, the prompt will be
- generated from the messages.
-
quality_preset: The quality preset to use for the TLM or Trustworthy RAG API.
- rewritten_question: The re-written query if it was provided by the client to Codex from a user to be
- used instead of the original query.
-
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1258,6 +1245,7 @@ async def validate(
body=await async_maybe_transform(
{
"context": context,
+ "prompt": prompt,
"query": query,
"response": response,
"constrain_outputs": constrain_outputs,
@@ -1266,9 +1254,7 @@ async def validate(
"eval_scores": eval_scores,
"messages": messages,
"options": options,
- "prompt": prompt,
"quality_preset": quality_preset,
- "rewritten_question": rewritten_question,
"task": task,
},
project_validate_params.ProjectValidateParams,
diff --git a/src/codex/types/project_validate_params.py b/src/codex/types/project_validate_params.py
index 0862cbc..8b38ebf 100644
--- a/src/codex/types/project_validate_params.py
+++ b/src/codex/types/project_validate_params.py
@@ -2,7 +2,6 @@
from __future__ import annotations
-import builtins
from typing import Dict, List, Union, Iterable, Optional
from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict
@@ -10,24 +9,6 @@
__all__ = [
"ProjectValidateParams",
- "Response",
- "ResponseChatCompletion",
- "ResponseChatCompletionChoice",
- "ResponseChatCompletionChoiceMessage",
- "ResponseChatCompletionChoiceMessageAnnotation",
- "ResponseChatCompletionChoiceMessageAnnotationURLCitation",
- "ResponseChatCompletionChoiceMessageAudio",
- "ResponseChatCompletionChoiceMessageFunctionCall",
- "ResponseChatCompletionChoiceMessageToolCall",
- "ResponseChatCompletionChoiceMessageToolCallFunction",
- "ResponseChatCompletionChoiceLogprobs",
- "ResponseChatCompletionChoiceLogprobsContent",
- "ResponseChatCompletionChoiceLogprobsContentTopLogprob",
- "ResponseChatCompletionChoiceLogprobsRefusal",
- "ResponseChatCompletionChoiceLogprobsRefusalTopLogprob",
- "ResponseChatCompletionUsage",
- "ResponseChatCompletionUsageCompletionTokensDetails",
- "ResponseChatCompletionUsagePromptTokensDetails",
"Message",
"MessageChatCompletionDeveloperMessageParam",
"MessageChatCompletionDeveloperMessageParamContentUnionMember1",
@@ -60,9 +41,11 @@
class ProjectValidateParams(TypedDict, total=False):
context: Required[str]
+ prompt: Required[str]
+
query: Required[str]
- response: Required[Response]
+ response: Required[str]
use_llm_matching: bool
@@ -83,10 +66,11 @@ class ProjectValidateParams(TypedDict, total=False):
If not provided, TLM will be used to generate scores.
"""
- messages: Iterable[Message]
- """Message history to provide conversation context for the query.
+ messages: Optional[Iterable[Message]]
+ """Optional message history to provide conversation context for the query.
- Messages contain up to and including the latest user prompt to the LLM.
+ Used to rewrite query into a self-contained version of itself. If not provided,
+ the query will be treated as self-contained.
"""
options: Optional[Options]
@@ -177,21 +161,9 @@ class ProjectValidateParams(TypedDict, total=False):
- criteria: Instructions specifying the evaluation criteria.
"""
- prompt: Optional[str]
- """The prompt to use for the TLM call.
-
- If not provided, the prompt will be generated from the messages.
- """
-
quality_preset: Literal["best", "high", "medium", "low", "base"]
"""The quality preset to use for the TLM or Trustworthy RAG API."""
- rewritten_question: Optional[str]
- """
- The re-written query if it was provided by the client to Codex from a user to be
- used instead of the original query.
- """
-
task: Optional[str]
x_client_library_version: Annotated[str, PropertyInfo(alias="x-client-library-version")]
@@ -203,243 +175,6 @@ class ProjectValidateParams(TypedDict, total=False):
x_stainless_package_version: Annotated[str, PropertyInfo(alias="x-stainless-package-version")]
-class ResponseChatCompletionChoiceMessageAnnotationURLCitationTyped(TypedDict, total=False):
- end_index: Required[int]
-
- start_index: Required[int]
-
- title: Required[str]
-
- url: Required[str]
-
-
-ResponseChatCompletionChoiceMessageAnnotationURLCitation: TypeAlias = Union[
- ResponseChatCompletionChoiceMessageAnnotationURLCitationTyped, Dict[str, object]
-]
-
-
-class ResponseChatCompletionChoiceMessageAnnotationTyped(TypedDict, total=False):
- type: Required[Literal["url_citation"]]
-
- url_citation: Required[ResponseChatCompletionChoiceMessageAnnotationURLCitation]
-
-
-ResponseChatCompletionChoiceMessageAnnotation: TypeAlias = Union[
- ResponseChatCompletionChoiceMessageAnnotationTyped, Dict[str, object]
-]
-
-
-class ResponseChatCompletionChoiceMessageAudioTyped(TypedDict, total=False):
- id: Required[str]
-
- data: Required[str]
-
- expires_at: Required[int]
-
- transcript: Required[str]
-
-
-ResponseChatCompletionChoiceMessageAudio: TypeAlias = Union[
- ResponseChatCompletionChoiceMessageAudioTyped, Dict[str, object]
-]
-
-
-class ResponseChatCompletionChoiceMessageFunctionCallTyped(TypedDict, total=False):
- arguments: Required[str]
-
- name: Required[str]
-
-
-ResponseChatCompletionChoiceMessageFunctionCall: TypeAlias = Union[
- ResponseChatCompletionChoiceMessageFunctionCallTyped, Dict[str, object]
-]
-
-
-class ResponseChatCompletionChoiceMessageToolCallFunctionTyped(TypedDict, total=False):
- arguments: Required[str]
-
- name: Required[str]
-
-
-ResponseChatCompletionChoiceMessageToolCallFunction: TypeAlias = Union[
- ResponseChatCompletionChoiceMessageToolCallFunctionTyped, Dict[str, object]
-]
-
-
-class ResponseChatCompletionChoiceMessageToolCallTyped(TypedDict, total=False):
- id: Required[str]
-
- function: Required[ResponseChatCompletionChoiceMessageToolCallFunction]
-
- type: Required[Literal["function"]]
-
-
-ResponseChatCompletionChoiceMessageToolCall: TypeAlias = Union[
- ResponseChatCompletionChoiceMessageToolCallTyped, Dict[str, object]
-]
-
-
-class ResponseChatCompletionChoiceMessageTyped(TypedDict, total=False):
- role: Required[Literal["assistant"]]
-
- annotations: Optional[Iterable[ResponseChatCompletionChoiceMessageAnnotation]]
-
- audio: Optional[ResponseChatCompletionChoiceMessageAudio]
-
- content: Optional[str]
-
- function_call: Optional[ResponseChatCompletionChoiceMessageFunctionCall]
-
- refusal: Optional[str]
-
- tool_calls: Optional[Iterable[ResponseChatCompletionChoiceMessageToolCall]]
-
-
-ResponseChatCompletionChoiceMessage: TypeAlias = Union[ResponseChatCompletionChoiceMessageTyped, Dict[str, object]]
-
-
-class ResponseChatCompletionChoiceLogprobsContentTopLogprobTyped(TypedDict, total=False):
- token: Required[str]
-
- logprob: Required[float]
-
- bytes: Optional[Iterable[int]]
-
-
-ResponseChatCompletionChoiceLogprobsContentTopLogprob: TypeAlias = Union[
- ResponseChatCompletionChoiceLogprobsContentTopLogprobTyped, Dict[str, object]
-]
-
-
-class ResponseChatCompletionChoiceLogprobsContentTyped(TypedDict, total=False):
- token: Required[str]
-
- logprob: Required[float]
-
- top_logprobs: Required[Iterable[ResponseChatCompletionChoiceLogprobsContentTopLogprob]]
-
- bytes: Optional[Iterable[int]]
-
-
-ResponseChatCompletionChoiceLogprobsContent: TypeAlias = Union[
- ResponseChatCompletionChoiceLogprobsContentTyped, Dict[str, object]
-]
-
-
-class ResponseChatCompletionChoiceLogprobsRefusalTopLogprobTyped(TypedDict, total=False):
- token: Required[str]
-
- logprob: Required[float]
-
- bytes: Optional[Iterable[int]]
-
-
-ResponseChatCompletionChoiceLogprobsRefusalTopLogprob: TypeAlias = Union[
- ResponseChatCompletionChoiceLogprobsRefusalTopLogprobTyped, Dict[str, object]
-]
-
-
-class ResponseChatCompletionChoiceLogprobsRefusalTyped(TypedDict, total=False):
- token: Required[str]
-
- logprob: Required[float]
-
- top_logprobs: Required[Iterable[ResponseChatCompletionChoiceLogprobsRefusalTopLogprob]]
-
- bytes: Optional[Iterable[int]]
-
-
-ResponseChatCompletionChoiceLogprobsRefusal: TypeAlias = Union[
- ResponseChatCompletionChoiceLogprobsRefusalTyped, Dict[str, object]
-]
-
-
-class ResponseChatCompletionChoiceLogprobsTyped(TypedDict, total=False):
- content: Optional[Iterable[ResponseChatCompletionChoiceLogprobsContent]]
-
- refusal: Optional[Iterable[ResponseChatCompletionChoiceLogprobsRefusal]]
-
-
-ResponseChatCompletionChoiceLogprobs: TypeAlias = Union[ResponseChatCompletionChoiceLogprobsTyped, Dict[str, object]]
-
-
-class ResponseChatCompletionChoiceTyped(TypedDict, total=False):
- finish_reason: Required[Literal["stop", "length", "tool_calls", "content_filter", "function_call"]]
-
- index: Required[int]
-
- message: Required[ResponseChatCompletionChoiceMessage]
-
- logprobs: Optional[ResponseChatCompletionChoiceLogprobs]
-
-
-ResponseChatCompletionChoice: TypeAlias = Union[ResponseChatCompletionChoiceTyped, Dict[str, object]]
-
-
-class ResponseChatCompletionUsageCompletionTokensDetailsTyped(TypedDict, total=False):
- accepted_prediction_tokens: Optional[int]
-
- audio_tokens: Optional[int]
-
- reasoning_tokens: Optional[int]
-
- rejected_prediction_tokens: Optional[int]
-
-
-ResponseChatCompletionUsageCompletionTokensDetails: TypeAlias = Union[
- ResponseChatCompletionUsageCompletionTokensDetailsTyped, Dict[str, object]
-]
-
-
-class ResponseChatCompletionUsagePromptTokensDetailsTyped(TypedDict, total=False):
- audio_tokens: Optional[int]
-
- cached_tokens: Optional[int]
-
-
-ResponseChatCompletionUsagePromptTokensDetails: TypeAlias = Union[
- ResponseChatCompletionUsagePromptTokensDetailsTyped, Dict[str, object]
-]
-
-
-class ResponseChatCompletionUsageTyped(TypedDict, total=False):
- completion_tokens: Required[int]
-
- prompt_tokens: Required[int]
-
- total_tokens: Required[int]
-
- completion_tokens_details: Optional[ResponseChatCompletionUsageCompletionTokensDetails]
-
- prompt_tokens_details: Optional[ResponseChatCompletionUsagePromptTokensDetails]
-
-
-ResponseChatCompletionUsage: TypeAlias = Union[ResponseChatCompletionUsageTyped, Dict[str, object]]
-
-
-class ResponseChatCompletionTyped(TypedDict, total=False):
- id: Required[str]
-
- choices: Required[Iterable[ResponseChatCompletionChoice]]
-
- created: Required[int]
-
- model: Required[str]
-
- object: Required[Literal["chat.completion"]]
-
- service_tier: Optional[Literal["scale", "default"]]
-
- system_fingerprint: Optional[str]
-
- usage: Optional[ResponseChatCompletionUsage]
-
-
-ResponseChatCompletion: TypeAlias = Union[ResponseChatCompletionTyped, Dict[str, builtins.object]]
-
-Response: TypeAlias = Union[str, ResponseChatCompletion]
-
-
class MessageChatCompletionDeveloperMessageParamContentUnionMember1(TypedDict, total=False):
text: Required[str]
diff --git a/tests/api_resources/test_projects.py b/tests/api_resources/test_projects.py
index 9ecffa0..0764d9a 100644
--- a/tests/api_resources/test_projects.py
+++ b/tests/api_resources/test_projects.py
@@ -632,8 +632,9 @@ def test_method_validate(self, client: Codex) -> None:
project = client.projects.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
+ prompt="prompt",
query="query",
- response="string",
+ response="response",
)
assert_matches_type(ProjectValidateResponse, project, path=["response"])
@@ -643,8 +644,9 @@ def test_method_validate_with_all_params(self, client: Codex) -> None:
project = client.projects.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
+ prompt="prompt",
query="query",
- response="string",
+ response="response",
use_llm_matching=True,
constrain_outputs=["string"],
custom_eval_thresholds={"foo": 0},
@@ -668,9 +670,7 @@ def test_method_validate_with_all_params(self, client: Codex) -> None:
"similarity_measure": "similarity_measure",
"use_self_reflection": True,
},
- prompt="prompt",
quality_preset="best",
- rewritten_question="rewritten_question",
task="task",
x_client_library_version="x-client-library-version",
x_integration_type="x-integration-type",
@@ -685,8 +685,9 @@ def test_raw_response_validate(self, client: Codex) -> None:
response = client.projects.with_raw_response.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
+ prompt="prompt",
query="query",
- response="string",
+ response="response",
)
assert response.is_closed is True
@@ -700,8 +701,9 @@ def test_streaming_response_validate(self, client: Codex) -> None:
with client.projects.with_streaming_response.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
+ prompt="prompt",
query="query",
- response="string",
+ response="response",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -718,8 +720,9 @@ def test_path_params_validate(self, client: Codex) -> None:
client.projects.with_raw_response.validate(
project_id="",
context="context",
+ prompt="prompt",
query="query",
- response="string",
+ response="response",
)
@@ -1334,8 +1337,9 @@ async def test_method_validate(self, async_client: AsyncCodex) -> None:
project = await async_client.projects.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
+ prompt="prompt",
query="query",
- response="string",
+ response="response",
)
assert_matches_type(ProjectValidateResponse, project, path=["response"])
@@ -1345,8 +1349,9 @@ async def test_method_validate_with_all_params(self, async_client: AsyncCodex) -
project = await async_client.projects.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
+ prompt="prompt",
query="query",
- response="string",
+ response="response",
use_llm_matching=True,
constrain_outputs=["string"],
custom_eval_thresholds={"foo": 0},
@@ -1370,9 +1375,7 @@ async def test_method_validate_with_all_params(self, async_client: AsyncCodex) -
"similarity_measure": "similarity_measure",
"use_self_reflection": True,
},
- prompt="prompt",
quality_preset="best",
- rewritten_question="rewritten_question",
task="task",
x_client_library_version="x-client-library-version",
x_integration_type="x-integration-type",
@@ -1387,8 +1390,9 @@ async def test_raw_response_validate(self, async_client: AsyncCodex) -> None:
response = await async_client.projects.with_raw_response.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
+ prompt="prompt",
query="query",
- response="string",
+ response="response",
)
assert response.is_closed is True
@@ -1402,8 +1406,9 @@ async def test_streaming_response_validate(self, async_client: AsyncCodex) -> No
async with async_client.projects.with_streaming_response.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
+ prompt="prompt",
query="query",
- response="string",
+ response="response",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -1420,6 +1425,7 @@ async def test_path_params_validate(self, async_client: AsyncCodex) -> None:
await async_client.projects.with_raw_response.validate(
project_id="",
context="context",
+ prompt="prompt",
query="query",
- response="string",
+ response="response",
)
From c24afc38a28c6bce4d28e7313922d750e7854770 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 7 Jul 2025 23:39:41 +0000
Subject: [PATCH 14/18] codegen metadata
---
.stats.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.stats.yml b/.stats.yml
index d7fdc0e..429b3f8 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,3 +1,3 @@
configured_endpoints: 55
openapi_spec_hash: f17890d85522687a4c68702da9ad2efb
-config_hash: e62d723b4a5c564dc05390753a876f31
+config_hash: f44faee9ff5bdf66e9e38fc69f6e4daa
From d36c2c7ca7a9155dab71b1c82f2e163488d32086 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 7 Jul 2025 23:45:06 +0000
Subject: [PATCH 15/18] feat(api): define pagination schemes
---
.stats.yml | 2 +-
api.md | 4 +-
src/codex/pagination.py | 124 ++++++++++++++++++
src/codex/resources/projects/query_logs.py | 21 +--
src/codex/resources/projects/remediations.py | 21 +--
.../types/projects/query_log_list_response.py | 47 +++----
.../projects/remediation_list_response.py | 12 +-
.../api_resources/projects/test_query_logs.py | 17 +--
.../projects/test_remediations.py | 17 +--
9 files changed, 191 insertions(+), 74 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 429b3f8..ac24d56 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,3 +1,3 @@
configured_endpoints: 55
openapi_spec_hash: f17890d85522687a4c68702da9ad2efb
-config_hash: f44faee9ff5bdf66e9e38fc69f6e4daa
+config_hash: 86582a50eb22b2866777cbd4d94f4e8d
diff --git a/api.md b/api.md
index ba4dfd6..edc03cd 100644
--- a/api.md
+++ b/api.md
@@ -212,7 +212,7 @@ from codex.types.projects import (
Methods:
- client.projects.query_logs.retrieve(query_log_id, \*, project_id) -> QueryLogRetrieveResponse
-- client.projects.query_logs.list(project_id, \*\*params) -> QueryLogListResponse
+- client.projects.query_logs.list(project_id, \*\*params) -> SyncOffsetPageQueryLogs[QueryLogListResponse]
- client.projects.query_logs.list_by_group(project_id, \*\*params) -> QueryLogListByGroupResponse
- client.projects.query_logs.list_groups(project_id, \*\*params) -> QueryLogListGroupsResponse
- client.projects.query_logs.start_remediation(query_log_id, \*, project_id) -> QueryLogStartRemediationResponse
@@ -240,7 +240,7 @@ Methods:
- client.projects.remediations.create(project_id, \*\*params) -> RemediationCreateResponse
- client.projects.remediations.retrieve(remediation_id, \*, project_id) -> RemediationRetrieveResponse
-- client.projects.remediations.list(project_id, \*\*params) -> RemediationListResponse
+- client.projects.remediations.list(project_id, \*\*params) -> SyncOffsetPageRemediations[RemediationListResponse]
- client.projects.remediations.delete(remediation_id, \*, project_id) -> None
- client.projects.remediations.edit_answer(remediation_id, \*, project_id, \*\*params) -> RemediationEditAnswerResponse
- client.projects.remediations.edit_draft_answer(remediation_id, \*, project_id, \*\*params) -> RemediationEditDraftAnswerResponse
diff --git a/src/codex/pagination.py b/src/codex/pagination.py
index 8057f2e..89ed0cf 100644
--- a/src/codex/pagination.py
+++ b/src/codex/pagination.py
@@ -14,6 +14,10 @@
"AsyncMyOffsetPageTopLevelArray",
"SyncOffsetPageClusters",
"AsyncOffsetPageClusters",
+ "SyncOffsetPageQueryLogs",
+ "AsyncOffsetPageQueryLogs",
+ "SyncOffsetPageRemediations",
+ "AsyncOffsetPageRemediations",
]
_BaseModelT = TypeVar("_BaseModelT", bound=BaseModel)
@@ -141,3 +145,123 @@ def next_page_info(self) -> Optional[PageInfo]:
return PageInfo(params={"offset": current_count})
return None
+
+
+class SyncOffsetPageQueryLogs(BaseSyncPage[_T], BasePage[_T], Generic[_T]):
+ query_logs: List[_T]
+ total_count: Optional[int] = None
+
+ @override
+ def _get_page_items(self) -> List[_T]:
+ query_logs = self.query_logs
+ if not query_logs:
+ return []
+ return query_logs
+
+ @override
+ def next_page_info(self) -> Optional[PageInfo]:
+ offset = self._options.params.get("offset") or 0
+ if not isinstance(offset, int):
+ raise ValueError(f'Expected "offset" param to be an integer but got {offset}')
+
+ length = len(self._get_page_items())
+ current_count = offset + length
+
+ total_count = self.total_count
+ if total_count is None:
+ return None
+
+ if current_count < total_count:
+ return PageInfo(params={"offset": current_count})
+
+ return None
+
+
+class AsyncOffsetPageQueryLogs(BaseAsyncPage[_T], BasePage[_T], Generic[_T]):
+ query_logs: List[_T]
+ total_count: Optional[int] = None
+
+ @override
+ def _get_page_items(self) -> List[_T]:
+ query_logs = self.query_logs
+ if not query_logs:
+ return []
+ return query_logs
+
+ @override
+ def next_page_info(self) -> Optional[PageInfo]:
+ offset = self._options.params.get("offset") or 0
+ if not isinstance(offset, int):
+ raise ValueError(f'Expected "offset" param to be an integer but got {offset}')
+
+ length = len(self._get_page_items())
+ current_count = offset + length
+
+ total_count = self.total_count
+ if total_count is None:
+ return None
+
+ if current_count < total_count:
+ return PageInfo(params={"offset": current_count})
+
+ return None
+
+
+class SyncOffsetPageRemediations(BaseSyncPage[_T], BasePage[_T], Generic[_T]):
+ remediations: List[_T]
+ total_count: Optional[int] = None
+
+ @override
+ def _get_page_items(self) -> List[_T]:
+ remediations = self.remediations
+ if not remediations:
+ return []
+ return remediations
+
+ @override
+ def next_page_info(self) -> Optional[PageInfo]:
+ offset = self._options.params.get("offset") or 0
+ if not isinstance(offset, int):
+ raise ValueError(f'Expected "offset" param to be an integer but got {offset}')
+
+ length = len(self._get_page_items())
+ current_count = offset + length
+
+ total_count = self.total_count
+ if total_count is None:
+ return None
+
+ if current_count < total_count:
+ return PageInfo(params={"offset": current_count})
+
+ return None
+
+
+class AsyncOffsetPageRemediations(BaseAsyncPage[_T], BasePage[_T], Generic[_T]):
+ remediations: List[_T]
+ total_count: Optional[int] = None
+
+ @override
+ def _get_page_items(self) -> List[_T]:
+ remediations = self.remediations
+ if not remediations:
+ return []
+ return remediations
+
+ @override
+ def next_page_info(self) -> Optional[PageInfo]:
+ offset = self._options.params.get("offset") or 0
+ if not isinstance(offset, int):
+ raise ValueError(f'Expected "offset" param to be an integer but got {offset}')
+
+ length = len(self._get_page_items())
+ current_count = offset + length
+
+ total_count = self.total_count
+ if total_count is None:
+ return None
+
+ if current_count < total_count:
+ return PageInfo(params={"offset": current_count})
+
+ return None
diff --git a/src/codex/resources/projects/query_logs.py b/src/codex/resources/projects/query_logs.py
index 148df9f..24535d4 100644
--- a/src/codex/resources/projects/query_logs.py
+++ b/src/codex/resources/projects/query_logs.py
@@ -18,7 +18,8 @@
async_to_raw_response_wrapper,
async_to_streamed_response_wrapper,
)
-from ..._base_client import make_request_options
+from ...pagination import SyncOffsetPageQueryLogs, AsyncOffsetPageQueryLogs
+from ..._base_client import AsyncPaginator, make_request_options
from ...types.projects import query_log_list_params, query_log_list_groups_params, query_log_list_by_group_params
from ...types.projects.query_log_list_response import QueryLogListResponse
from ...types.projects.query_log_retrieve_response import QueryLogRetrieveResponse
@@ -110,7 +111,7 @@ def list(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> QueryLogListResponse:
+ ) -> SyncOffsetPageQueryLogs[QueryLogListResponse]:
"""
List query logs by project ID.
@@ -141,8 +142,9 @@ def list(
"""
if not project_id:
raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- return self._get(
+ return self._get_api_list(
f"/api/projects/{project_id}/query_logs/",
+ page=SyncOffsetPageQueryLogs[QueryLogListResponse],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -166,7 +168,7 @@ def list(
query_log_list_params.QueryLogListParams,
),
),
- cast_to=QueryLogListResponse,
+ model=QueryLogListResponse,
)
def list_by_group(
@@ -443,7 +445,7 @@ async def retrieve(
cast_to=QueryLogRetrieveResponse,
)
- async def list(
+ def list(
self,
project_id: str,
*,
@@ -468,7 +470,7 @@ async def list(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> QueryLogListResponse:
+ ) -> AsyncPaginator[QueryLogListResponse, AsyncOffsetPageQueryLogs[QueryLogListResponse]]:
"""
List query logs by project ID.
@@ -499,14 +501,15 @@ async def list(
"""
if not project_id:
raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- return await self._get(
+ return self._get_api_list(
f"/api/projects/{project_id}/query_logs/",
+ page=AsyncOffsetPageQueryLogs[QueryLogListResponse],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
- query=await async_maybe_transform(
+ query=maybe_transform(
{
"created_at_end": created_at_end,
"created_at_start": created_at_start,
@@ -524,7 +527,7 @@ async def list(
query_log_list_params.QueryLogListParams,
),
),
- cast_to=QueryLogListResponse,
+ model=QueryLogListResponse,
)
async def list_by_group(
diff --git a/src/codex/resources/projects/remediations.py b/src/codex/resources/projects/remediations.py
index 65015a1..ea0168c 100644
--- a/src/codex/resources/projects/remediations.py
+++ b/src/codex/resources/projects/remediations.py
@@ -18,7 +18,8 @@
async_to_raw_response_wrapper,
async_to_streamed_response_wrapper,
)
-from ..._base_client import make_request_options
+from ...pagination import SyncOffsetPageRemediations, AsyncOffsetPageRemediations
+from ..._base_client import AsyncPaginator, make_request_options
from ...types.projects import (
remediation_list_params,
remediation_create_params,
@@ -159,7 +160,7 @@ def list(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> RemediationListResponse:
+ ) -> SyncOffsetPageRemediations[RemediationListResponse]:
"""
List remediations by project ID.
@@ -186,8 +187,9 @@ def list(
"""
if not project_id:
raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- return self._get(
+ return self._get_api_list(
f"/api/projects/{project_id}/remediations/",
+ page=SyncOffsetPageRemediations[RemediationListResponse],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -209,7 +211,7 @@ def list(
remediation_list_params.RemediationListParams,
),
),
- cast_to=RemediationListResponse,
+ model=RemediationListResponse,
)
def delete(
@@ -608,7 +610,7 @@ async def retrieve(
cast_to=RemediationRetrieveResponse,
)
- async def list(
+ def list(
self,
project_id: str,
*,
@@ -628,7 +630,7 @@ async def list(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> RemediationListResponse:
+ ) -> AsyncPaginator[RemediationListResponse, AsyncOffsetPageRemediations[RemediationListResponse]]:
"""
List remediations by project ID.
@@ -655,14 +657,15 @@ async def list(
"""
if not project_id:
raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- return await self._get(
+ return self._get_api_list(
f"/api/projects/{project_id}/remediations/",
+ page=AsyncOffsetPageRemediations[RemediationListResponse],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
- query=await async_maybe_transform(
+ query=maybe_transform(
{
"created_at_end": created_at_end,
"created_at_start": created_at_start,
@@ -678,7 +681,7 @@ async def list(
remediation_list_params.RemediationListParams,
),
),
- cast_to=RemediationListResponse,
+ model=RemediationListResponse,
)
async def delete(
diff --git a/src/codex/types/projects/query_log_list_response.py b/src/codex/types/projects/query_log_list_response.py
index 147478c..ccdeb03 100644
--- a/src/codex/types/projects/query_log_list_response.py
+++ b/src/codex/types/projects/query_log_list_response.py
@@ -8,41 +8,40 @@
__all__ = [
"QueryLogListResponse",
- "QueryLog",
- "QueryLogFormattedEscalationEvalScores",
- "QueryLogFormattedEvalScores",
- "QueryLogFormattedGuardrailEvalScores",
- "QueryLogFormattedNonGuardrailEvalScores",
- "QueryLogContext",
- "QueryLogDeterministicGuardrailsResults",
+ "FormattedEscalationEvalScores",
+ "FormattedEvalScores",
+ "FormattedGuardrailEvalScores",
+ "FormattedNonGuardrailEvalScores",
+ "Context",
+ "DeterministicGuardrailsResults",
]
-class QueryLogFormattedEscalationEvalScores(BaseModel):
+class FormattedEscalationEvalScores(BaseModel):
score: float
status: Literal["pass", "fail"]
-class QueryLogFormattedEvalScores(BaseModel):
+class FormattedEvalScores(BaseModel):
score: float
status: Literal["pass", "fail"]
-class QueryLogFormattedGuardrailEvalScores(BaseModel):
+class FormattedGuardrailEvalScores(BaseModel):
score: float
status: Literal["pass", "fail"]
-class QueryLogFormattedNonGuardrailEvalScores(BaseModel):
+class FormattedNonGuardrailEvalScores(BaseModel):
score: float
status: Literal["pass", "fail"]
-class QueryLogContext(BaseModel):
+class Context(BaseModel):
content: str
"""The actual content/text of the document."""
@@ -59,7 +58,7 @@ class QueryLogContext(BaseModel):
"""Title or heading of the document. Useful for display and context."""
-class QueryLogDeterministicGuardrailsResults(BaseModel):
+class DeterministicGuardrailsResults(BaseModel):
guardrail_name: str
should_guardrail: bool
@@ -67,14 +66,14 @@ class QueryLogDeterministicGuardrailsResults(BaseModel):
matches: Optional[List[str]] = None
-class QueryLog(BaseModel):
+class QueryLogListResponse(BaseModel):
id: str
created_at: datetime
- formatted_escalation_eval_scores: Optional[Dict[str, QueryLogFormattedEscalationEvalScores]] = None
+ formatted_escalation_eval_scores: Optional[Dict[str, FormattedEscalationEvalScores]] = None
- formatted_eval_scores: Optional[Dict[str, QueryLogFormattedEvalScores]] = None
+ formatted_eval_scores: Optional[Dict[str, FormattedEvalScores]] = None
"""Format evaluation scores for frontend display with pass/fail status.
Returns: Dictionary mapping eval keys to their formatted representation: {
@@ -82,9 +81,9 @@ class QueryLog(BaseModel):
eval_scores is None.
"""
- formatted_guardrail_eval_scores: Optional[Dict[str, QueryLogFormattedGuardrailEvalScores]] = None
+ formatted_guardrail_eval_scores: Optional[Dict[str, FormattedGuardrailEvalScores]] = None
- formatted_non_guardrail_eval_scores: Optional[Dict[str, QueryLogFormattedNonGuardrailEvalScores]] = None
+ formatted_non_guardrail_eval_scores: Optional[Dict[str, FormattedNonGuardrailEvalScores]] = None
is_bad_response: bool
@@ -97,7 +96,7 @@ class QueryLog(BaseModel):
was_cache_hit: Optional[bool] = None
"""If similar query already answered, or None if cache was not checked"""
- context: Optional[List[QueryLogContext]] = None
+ context: Optional[List[Context]] = None
"""RAG context used for the query"""
custom_metadata: Optional[object] = None
@@ -106,7 +105,7 @@ class QueryLog(BaseModel):
custom_metadata_keys: Optional[List[str]] = None
"""Keys of the custom metadata"""
- deterministic_guardrails_results: Optional[Dict[str, QueryLogDeterministicGuardrailsResults]] = None
+ deterministic_guardrails_results: Optional[Dict[str, DeterministicGuardrailsResults]] = None
"""Results of deterministic guardrails applied to the query"""
escalated: Optional[bool] = None
@@ -138,11 +137,3 @@ class QueryLog(BaseModel):
primary_eval_issue_score: Optional[float] = None
"""Score of the primary eval issue"""
-
-
-class QueryLogListResponse(BaseModel):
- custom_metadata_columns: List[str]
-
- query_logs: List[QueryLog]
-
- total_count: int
diff --git a/src/codex/types/projects/remediation_list_response.py b/src/codex/types/projects/remediation_list_response.py
index 9d5cda8..8341053 100644
--- a/src/codex/types/projects/remediation_list_response.py
+++ b/src/codex/types/projects/remediation_list_response.py
@@ -1,15 +1,15 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List, Optional
+from typing import Optional
from datetime import datetime
from typing_extensions import Literal
from ..._models import BaseModel
-__all__ = ["RemediationListResponse", "Remediation"]
+__all__ = ["RemediationListResponse"]
-class Remediation(BaseModel):
+class RemediationListResponse(BaseModel):
id: str
answered_at: Optional[datetime] = None
@@ -35,9 +35,3 @@ class Remediation(BaseModel):
answer: Optional[str] = None
draft_answer: Optional[str] = None
-
-
-class RemediationListResponse(BaseModel):
- remediations: List[Remediation]
-
- total_count: int
diff --git a/tests/api_resources/projects/test_query_logs.py b/tests/api_resources/projects/test_query_logs.py
index 68d78ce..be867e2 100644
--- a/tests/api_resources/projects/test_query_logs.py
+++ b/tests/api_resources/projects/test_query_logs.py
@@ -10,6 +10,7 @@
from codex import Codex, AsyncCodex
from tests.utils import assert_matches_type
from codex._utils import parse_datetime
+from codex.pagination import SyncOffsetPageQueryLogs, AsyncOffsetPageQueryLogs
from codex.types.projects import (
QueryLogListResponse,
QueryLogRetrieveResponse,
@@ -82,7 +83,7 @@ def test_method_list(self, client: Codex) -> None:
query_log = client.projects.query_logs.list(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(QueryLogListResponse, query_log, path=["response"])
+ assert_matches_type(SyncOffsetPageQueryLogs[QueryLogListResponse], query_log, path=["response"])
@pytest.mark.skip()
@parametrize
@@ -102,7 +103,7 @@ def test_method_list_with_all_params(self, client: Codex) -> None:
sort="created_at",
was_cache_hit=True,
)
- assert_matches_type(QueryLogListResponse, query_log, path=["response"])
+ assert_matches_type(SyncOffsetPageQueryLogs[QueryLogListResponse], query_log, path=["response"])
@pytest.mark.skip()
@parametrize
@@ -114,7 +115,7 @@ def test_raw_response_list(self, client: Codex) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
query_log = response.parse()
- assert_matches_type(QueryLogListResponse, query_log, path=["response"])
+ assert_matches_type(SyncOffsetPageQueryLogs[QueryLogListResponse], query_log, path=["response"])
@pytest.mark.skip()
@parametrize
@@ -126,7 +127,7 @@ def test_streaming_response_list(self, client: Codex) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
query_log = response.parse()
- assert_matches_type(QueryLogListResponse, query_log, path=["response"])
+ assert_matches_type(SyncOffsetPageQueryLogs[QueryLogListResponse], query_log, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -381,7 +382,7 @@ async def test_method_list(self, async_client: AsyncCodex) -> None:
query_log = await async_client.projects.query_logs.list(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(QueryLogListResponse, query_log, path=["response"])
+ assert_matches_type(AsyncOffsetPageQueryLogs[QueryLogListResponse], query_log, path=["response"])
@pytest.mark.skip()
@parametrize
@@ -401,7 +402,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCodex) -> No
sort="created_at",
was_cache_hit=True,
)
- assert_matches_type(QueryLogListResponse, query_log, path=["response"])
+ assert_matches_type(AsyncOffsetPageQueryLogs[QueryLogListResponse], query_log, path=["response"])
@pytest.mark.skip()
@parametrize
@@ -413,7 +414,7 @@ async def test_raw_response_list(self, async_client: AsyncCodex) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
query_log = await response.parse()
- assert_matches_type(QueryLogListResponse, query_log, path=["response"])
+ assert_matches_type(AsyncOffsetPageQueryLogs[QueryLogListResponse], query_log, path=["response"])
@pytest.mark.skip()
@parametrize
@@ -425,7 +426,7 @@ async def test_streaming_response_list(self, async_client: AsyncCodex) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
query_log = await response.parse()
- assert_matches_type(QueryLogListResponse, query_log, path=["response"])
+ assert_matches_type(AsyncOffsetPageQueryLogs[QueryLogListResponse], query_log, path=["response"])
assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/projects/test_remediations.py b/tests/api_resources/projects/test_remediations.py
index c75a255..947850f 100644
--- a/tests/api_resources/projects/test_remediations.py
+++ b/tests/api_resources/projects/test_remediations.py
@@ -10,6 +10,7 @@
from codex import Codex, AsyncCodex
from tests.utils import assert_matches_type
from codex._utils import parse_datetime
+from codex.pagination import SyncOffsetPageRemediations, AsyncOffsetPageRemediations
from codex.types.projects import (
RemediationListResponse,
RemediationPauseResponse,
@@ -144,7 +145,7 @@ def test_method_list(self, client: Codex) -> None:
remediation = client.projects.remediations.list(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(RemediationListResponse, remediation, path=["response"])
+ assert_matches_type(SyncOffsetPageRemediations[RemediationListResponse], remediation, path=["response"])
@pytest.mark.skip()
@parametrize
@@ -162,7 +163,7 @@ def test_method_list_with_all_params(self, client: Codex) -> None:
sort="created_at",
status=["ACTIVE"],
)
- assert_matches_type(RemediationListResponse, remediation, path=["response"])
+ assert_matches_type(SyncOffsetPageRemediations[RemediationListResponse], remediation, path=["response"])
@pytest.mark.skip()
@parametrize
@@ -174,7 +175,7 @@ def test_raw_response_list(self, client: Codex) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
remediation = response.parse()
- assert_matches_type(RemediationListResponse, remediation, path=["response"])
+ assert_matches_type(SyncOffsetPageRemediations[RemediationListResponse], remediation, path=["response"])
@pytest.mark.skip()
@parametrize
@@ -186,7 +187,7 @@ def test_streaming_response_list(self, client: Codex) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
remediation = response.parse()
- assert_matches_type(RemediationListResponse, remediation, path=["response"])
+ assert_matches_type(SyncOffsetPageRemediations[RemediationListResponse], remediation, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -745,7 +746,7 @@ async def test_method_list(self, async_client: AsyncCodex) -> None:
remediation = await async_client.projects.remediations.list(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(RemediationListResponse, remediation, path=["response"])
+ assert_matches_type(AsyncOffsetPageRemediations[RemediationListResponse], remediation, path=["response"])
@pytest.mark.skip()
@parametrize
@@ -763,7 +764,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCodex) -> No
sort="created_at",
status=["ACTIVE"],
)
- assert_matches_type(RemediationListResponse, remediation, path=["response"])
+ assert_matches_type(AsyncOffsetPageRemediations[RemediationListResponse], remediation, path=["response"])
@pytest.mark.skip()
@parametrize
@@ -775,7 +776,7 @@ async def test_raw_response_list(self, async_client: AsyncCodex) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
remediation = await response.parse()
- assert_matches_type(RemediationListResponse, remediation, path=["response"])
+ assert_matches_type(AsyncOffsetPageRemediations[RemediationListResponse], remediation, path=["response"])
@pytest.mark.skip()
@parametrize
@@ -787,7 +788,7 @@ async def test_streaming_response_list(self, async_client: AsyncCodex) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
remediation = await response.parse()
- assert_matches_type(RemediationListResponse, remediation, path=["response"])
+ assert_matches_type(AsyncOffsetPageRemediations[RemediationListResponse], remediation, path=["response"])
assert cast(Any, response.is_closed) is True
From d4d82fe33422f460c83778dc0ca767361dce86a5 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 7 Jul 2025 23:43:46 +0000
Subject: [PATCH 16/18] feat(api): more pagination schemes
---
.stats.yml | 2 +-
api.md | 2 +-
src/codex/pagination.py | 124 ++++++++++++++++++
src/codex/resources/projects/query_logs.py | 25 ++--
.../query_log_list_groups_response.py | 47 +++----
.../api_resources/projects/test_query_logs.py | 23 ++--
6 files changed, 175 insertions(+), 48 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index ac24d56..01dc7b2 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,3 +1,3 @@
configured_endpoints: 55
openapi_spec_hash: f17890d85522687a4c68702da9ad2efb
-config_hash: 86582a50eb22b2866777cbd4d94f4e8d
+config_hash: 8f6e5c3b064cbb77569a6bf654954a56
diff --git a/api.md b/api.md
index edc03cd..0c02791 100644
--- a/api.md
+++ b/api.md
@@ -214,7 +214,7 @@ Methods:
- client.projects.query_logs.retrieve(query_log_id, \*, project_id) -> QueryLogRetrieveResponse
- client.projects.query_logs.list(project_id, \*\*params) -> SyncOffsetPageQueryLogs[QueryLogListResponse]
- client.projects.query_logs.list_by_group(project_id, \*\*params) -> QueryLogListByGroupResponse
-- client.projects.query_logs.list_groups(project_id, \*\*params) -> QueryLogListGroupsResponse
+- client.projects.query_logs.list_groups(project_id, \*\*params) -> SyncOffsetPageQueryLogGroups[QueryLogListGroupsResponse]
- client.projects.query_logs.start_remediation(query_log_id, \*, project_id) -> QueryLogStartRemediationResponse
## Remediations
diff --git a/src/codex/pagination.py b/src/codex/pagination.py
index 89ed0cf..36af0f6 100644
--- a/src/codex/pagination.py
+++ b/src/codex/pagination.py
@@ -18,6 +18,10 @@
"AsyncOffsetPageQueryLogs",
"SyncOffsetPageRemediations",
"AsyncOffsetPageRemediations",
+ "SyncOffsetPageQueryLogGroups",
+ "AsyncOffsetPageQueryLogGroups",
+ "SyncOffsetPageQueryLogsByGroup",
+ "AsyncOffsetPageQueryLogsByGroup",
]
_BaseModelT = TypeVar("_BaseModelT", bound=BaseModel)
@@ -265,3 +269,123 @@ def next_page_info(self) -> Optional[PageInfo]:
return PageInfo(params={"offset": current_count})
return None
+
+
+class SyncOffsetPageQueryLogGroups(BaseSyncPage[_T], BasePage[_T], Generic[_T]):
+ query_log_groups: List[_T]
+ total_count: Optional[int] = None
+
+ @override
+ def _get_page_items(self) -> List[_T]:
+ query_log_groups = self.query_log_groups
+ if not query_log_groups:
+ return []
+ return query_log_groups
+
+ @override
+ def next_page_info(self) -> Optional[PageInfo]:
+ offset = self._options.params.get("offset") or 0
+ if not isinstance(offset, int):
+ raise ValueError(f'Expected "offset" param to be an integer but got {offset}')
+
+ length = len(self._get_page_items())
+ current_count = offset + length
+
+ total_count = self.total_count
+ if total_count is None:
+ return None
+
+ if current_count < total_count:
+ return PageInfo(params={"offset": current_count})
+
+ return None
+
+
+class AsyncOffsetPageQueryLogGroups(BaseAsyncPage[_T], BasePage[_T], Generic[_T]):
+ query_log_groups: List[_T]
+ total_count: Optional[int] = None
+
+ @override
+ def _get_page_items(self) -> List[_T]:
+ query_log_groups = self.query_log_groups
+ if not query_log_groups:
+ return []
+ return query_log_groups
+
+ @override
+ def next_page_info(self) -> Optional[PageInfo]:
+ offset = self._options.params.get("offset") or 0
+ if not isinstance(offset, int):
+ raise ValueError(f'Expected "offset" param to be an integer but got {offset}')
+
+ length = len(self._get_page_items())
+ current_count = offset + length
+
+ total_count = self.total_count
+ if total_count is None:
+ return None
+
+ if current_count < total_count:
+ return PageInfo(params={"offset": current_count})
+
+ return None
+
+
+class SyncOffsetPageQueryLogsByGroup(BaseSyncPage[_T], BasePage[_T], Generic[_T]):
+ query_logs_by_group: List[_T]
+ total_count: Optional[int] = None
+
+ @override
+ def _get_page_items(self) -> List[_T]:
+ query_logs_by_group = self.query_logs_by_group
+ if not query_logs_by_group:
+ return []
+ return query_logs_by_group
+
+ @override
+ def next_page_info(self) -> Optional[PageInfo]:
+ offset = self._options.params.get("offset") or 0
+ if not isinstance(offset, int):
+ raise ValueError(f'Expected "offset" param to be an integer but got {offset}')
+
+ length = len(self._get_page_items())
+ current_count = offset + length
+
+ total_count = self.total_count
+ if total_count is None:
+ return None
+
+ if current_count < total_count:
+ return PageInfo(params={"offset": current_count})
+
+ return None
+
+
+class AsyncOffsetPageQueryLogsByGroup(BaseAsyncPage[_T], BasePage[_T], Generic[_T]):
+ query_logs_by_group: List[_T]
+ total_count: Optional[int] = None
+
+ @override
+ def _get_page_items(self) -> List[_T]:
+ query_logs_by_group = self.query_logs_by_group
+ if not query_logs_by_group:
+ return []
+ return query_logs_by_group
+
+ @override
+ def next_page_info(self) -> Optional[PageInfo]:
+ offset = self._options.params.get("offset") or 0
+ if not isinstance(offset, int):
+ raise ValueError(f'Expected "offset" param to be an integer but got {offset}')
+
+ length = len(self._get_page_items())
+ current_count = offset + length
+
+ total_count = self.total_count
+ if total_count is None:
+ return None
+
+ if current_count < total_count:
+ return PageInfo(params={"offset": current_count})
+
+ return None
diff --git a/src/codex/resources/projects/query_logs.py b/src/codex/resources/projects/query_logs.py
index 24535d4..9ccecbe 100644
--- a/src/codex/resources/projects/query_logs.py
+++ b/src/codex/resources/projects/query_logs.py
@@ -18,7 +18,12 @@
async_to_raw_response_wrapper,
async_to_streamed_response_wrapper,
)
-from ...pagination import SyncOffsetPageQueryLogs, AsyncOffsetPageQueryLogs
+from ...pagination import (
+ SyncOffsetPageQueryLogs,
+ AsyncOffsetPageQueryLogs,
+ SyncOffsetPageQueryLogGroups,
+ AsyncOffsetPageQueryLogGroups,
+)
from ..._base_client import AsyncPaginator, make_request_options
from ...types.projects import query_log_list_params, query_log_list_groups_params, query_log_list_by_group_params
from ...types.projects.query_log_list_response import QueryLogListResponse
@@ -290,7 +295,7 @@ def list_groups(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> QueryLogListGroupsResponse:
+ ) -> SyncOffsetPageQueryLogGroups[QueryLogListGroupsResponse]:
"""
List query log groups by project ID.
@@ -323,8 +328,9 @@ def list_groups(
"""
if not project_id:
raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- return self._get(
+ return self._get_api_list(
f"/api/projects/{project_id}/query_logs/groups",
+ page=SyncOffsetPageQueryLogGroups[QueryLogListGroupsResponse],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -349,7 +355,7 @@ def list_groups(
query_log_list_groups_params.QueryLogListGroupsParams,
),
),
- cast_to=QueryLogListGroupsResponse,
+ model=QueryLogListGroupsResponse,
)
def start_remediation(
@@ -622,7 +628,7 @@ async def list_by_group(
cast_to=QueryLogListByGroupResponse,
)
- async def list_groups(
+ def list_groups(
self,
project_id: str,
*,
@@ -649,7 +655,7 @@ async def list_groups(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> QueryLogListGroupsResponse:
+ ) -> AsyncPaginator[QueryLogListGroupsResponse, AsyncOffsetPageQueryLogGroups[QueryLogListGroupsResponse]]:
"""
List query log groups by project ID.
@@ -682,14 +688,15 @@ async def list_groups(
"""
if not project_id:
raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
- return await self._get(
+ return self._get_api_list(
f"/api/projects/{project_id}/query_logs/groups",
+ page=AsyncOffsetPageQueryLogGroups[QueryLogListGroupsResponse],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
- query=await async_maybe_transform(
+ query=maybe_transform(
{
"created_at_end": created_at_end,
"created_at_start": created_at_start,
@@ -708,7 +715,7 @@ async def list_groups(
query_log_list_groups_params.QueryLogListGroupsParams,
),
),
- cast_to=QueryLogListGroupsResponse,
+ model=QueryLogListGroupsResponse,
)
async def start_remediation(
diff --git a/src/codex/types/projects/query_log_list_groups_response.py b/src/codex/types/projects/query_log_list_groups_response.py
index e77dd87..5d9222b 100644
--- a/src/codex/types/projects/query_log_list_groups_response.py
+++ b/src/codex/types/projects/query_log_list_groups_response.py
@@ -8,41 +8,40 @@
__all__ = [
"QueryLogListGroupsResponse",
- "QueryLogGroup",
- "QueryLogGroupFormattedEscalationEvalScores",
- "QueryLogGroupFormattedEvalScores",
- "QueryLogGroupFormattedGuardrailEvalScores",
- "QueryLogGroupFormattedNonGuardrailEvalScores",
- "QueryLogGroupContext",
- "QueryLogGroupDeterministicGuardrailsResults",
+ "FormattedEscalationEvalScores",
+ "FormattedEvalScores",
+ "FormattedGuardrailEvalScores",
+ "FormattedNonGuardrailEvalScores",
+ "Context",
+ "DeterministicGuardrailsResults",
]
-class QueryLogGroupFormattedEscalationEvalScores(BaseModel):
+class FormattedEscalationEvalScores(BaseModel):
score: float
status: Literal["pass", "fail"]
-class QueryLogGroupFormattedEvalScores(BaseModel):
+class FormattedEvalScores(BaseModel):
score: float
status: Literal["pass", "fail"]
-class QueryLogGroupFormattedGuardrailEvalScores(BaseModel):
+class FormattedGuardrailEvalScores(BaseModel):
score: float
status: Literal["pass", "fail"]
-class QueryLogGroupFormattedNonGuardrailEvalScores(BaseModel):
+class FormattedNonGuardrailEvalScores(BaseModel):
score: float
status: Literal["pass", "fail"]
-class QueryLogGroupContext(BaseModel):
+class Context(BaseModel):
content: str
"""The actual content/text of the document."""
@@ -59,7 +58,7 @@ class QueryLogGroupContext(BaseModel):
"""Title or heading of the document. Useful for display and context."""
-class QueryLogGroupDeterministicGuardrailsResults(BaseModel):
+class DeterministicGuardrailsResults(BaseModel):
guardrail_name: str
should_guardrail: bool
@@ -67,14 +66,14 @@ class QueryLogGroupDeterministicGuardrailsResults(BaseModel):
matches: Optional[List[str]] = None
-class QueryLogGroup(BaseModel):
+class QueryLogListGroupsResponse(BaseModel):
id: str
created_at: datetime
- formatted_escalation_eval_scores: Optional[Dict[str, QueryLogGroupFormattedEscalationEvalScores]] = None
+ formatted_escalation_eval_scores: Optional[Dict[str, FormattedEscalationEvalScores]] = None
- formatted_eval_scores: Optional[Dict[str, QueryLogGroupFormattedEvalScores]] = None
+ formatted_eval_scores: Optional[Dict[str, FormattedEvalScores]] = None
"""Format evaluation scores for frontend display with pass/fail status.
Returns: Dictionary mapping eval keys to their formatted representation: {
@@ -82,9 +81,9 @@ class QueryLogGroup(BaseModel):
eval_scores is None.
"""
- formatted_guardrail_eval_scores: Optional[Dict[str, QueryLogGroupFormattedGuardrailEvalScores]] = None
+ formatted_guardrail_eval_scores: Optional[Dict[str, FormattedGuardrailEvalScores]] = None
- formatted_non_guardrail_eval_scores: Optional[Dict[str, QueryLogGroupFormattedNonGuardrailEvalScores]] = None
+ formatted_non_guardrail_eval_scores: Optional[Dict[str, FormattedNonGuardrailEvalScores]] = None
is_bad_response: bool
@@ -103,7 +102,7 @@ class QueryLogGroup(BaseModel):
was_cache_hit: Optional[bool] = None
"""If similar query already answered, or None if cache was not checked"""
- context: Optional[List[QueryLogGroupContext]] = None
+ context: Optional[List[Context]] = None
"""RAG context used for the query"""
custom_metadata: Optional[object] = None
@@ -112,7 +111,7 @@ class QueryLogGroup(BaseModel):
custom_metadata_keys: Optional[List[str]] = None
"""Keys of the custom metadata"""
- deterministic_guardrails_results: Optional[Dict[str, QueryLogGroupDeterministicGuardrailsResults]] = None
+ deterministic_guardrails_results: Optional[Dict[str, DeterministicGuardrailsResults]] = None
"""Results of deterministic guardrails applied to the query"""
escalated: Optional[bool] = None
@@ -144,11 +143,3 @@ class QueryLogGroup(BaseModel):
primary_eval_issue_score: Optional[float] = None
"""Score of the primary eval issue"""
-
-
-class QueryLogListGroupsResponse(BaseModel):
- custom_metadata_columns: List[str]
-
- query_log_groups: List[QueryLogGroup]
-
- total_count: int
diff --git a/tests/api_resources/projects/test_query_logs.py b/tests/api_resources/projects/test_query_logs.py
index be867e2..cd4cd7d 100644
--- a/tests/api_resources/projects/test_query_logs.py
+++ b/tests/api_resources/projects/test_query_logs.py
@@ -10,7 +10,12 @@
from codex import Codex, AsyncCodex
from tests.utils import assert_matches_type
from codex._utils import parse_datetime
-from codex.pagination import SyncOffsetPageQueryLogs, AsyncOffsetPageQueryLogs
+from codex.pagination import (
+ SyncOffsetPageQueryLogs,
+ AsyncOffsetPageQueryLogs,
+ SyncOffsetPageQueryLogGroups,
+ AsyncOffsetPageQueryLogGroups,
+)
from codex.types.projects import (
QueryLogListResponse,
QueryLogRetrieveResponse,
@@ -209,7 +214,7 @@ def test_method_list_groups(self, client: Codex) -> None:
query_log = client.projects.query_logs.list_groups(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(QueryLogListGroupsResponse, query_log, path=["response"])
+ assert_matches_type(SyncOffsetPageQueryLogGroups[QueryLogListGroupsResponse], query_log, path=["response"])
@pytest.mark.skip()
@parametrize
@@ -230,7 +235,7 @@ def test_method_list_groups_with_all_params(self, client: Codex) -> None:
sort="created_at",
was_cache_hit=True,
)
- assert_matches_type(QueryLogListGroupsResponse, query_log, path=["response"])
+ assert_matches_type(SyncOffsetPageQueryLogGroups[QueryLogListGroupsResponse], query_log, path=["response"])
@pytest.mark.skip()
@parametrize
@@ -242,7 +247,7 @@ def test_raw_response_list_groups(self, client: Codex) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
query_log = response.parse()
- assert_matches_type(QueryLogListGroupsResponse, query_log, path=["response"])
+ assert_matches_type(SyncOffsetPageQueryLogGroups[QueryLogListGroupsResponse], query_log, path=["response"])
@pytest.mark.skip()
@parametrize
@@ -254,7 +259,7 @@ def test_streaming_response_list_groups(self, client: Codex) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
query_log = response.parse()
- assert_matches_type(QueryLogListGroupsResponse, query_log, path=["response"])
+ assert_matches_type(SyncOffsetPageQueryLogGroups[QueryLogListGroupsResponse], query_log, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -508,7 +513,7 @@ async def test_method_list_groups(self, async_client: AsyncCodex) -> None:
query_log = await async_client.projects.query_logs.list_groups(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(QueryLogListGroupsResponse, query_log, path=["response"])
+ assert_matches_type(AsyncOffsetPageQueryLogGroups[QueryLogListGroupsResponse], query_log, path=["response"])
@pytest.mark.skip()
@parametrize
@@ -529,7 +534,7 @@ async def test_method_list_groups_with_all_params(self, async_client: AsyncCodex
sort="created_at",
was_cache_hit=True,
)
- assert_matches_type(QueryLogListGroupsResponse, query_log, path=["response"])
+ assert_matches_type(AsyncOffsetPageQueryLogGroups[QueryLogListGroupsResponse], query_log, path=["response"])
@pytest.mark.skip()
@parametrize
@@ -541,7 +546,7 @@ async def test_raw_response_list_groups(self, async_client: AsyncCodex) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
query_log = await response.parse()
- assert_matches_type(QueryLogListGroupsResponse, query_log, path=["response"])
+ assert_matches_type(AsyncOffsetPageQueryLogGroups[QueryLogListGroupsResponse], query_log, path=["response"])
@pytest.mark.skip()
@parametrize
@@ -553,7 +558,7 @@ async def test_streaming_response_list_groups(self, async_client: AsyncCodex) ->
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
query_log = await response.parse()
- assert_matches_type(QueryLogListGroupsResponse, query_log, path=["response"])
+ assert_matches_type(AsyncOffsetPageQueryLogGroups[QueryLogListGroupsResponse], query_log, path=["response"])
assert cast(Any, response.is_closed) is True
From 29f65d74a04a8424cc666669167c8ba56a56485b Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 7 Jul 2025 23:47:39 +0000
Subject: [PATCH 17/18] feat(api): api update
---
.stats.yml | 2 +-
src/codex/resources/projects/projects.py | 42 ++--
src/codex/types/project_validate_params.py | 279 ++++++++++++++++++++-
tests/api_resources/test_projects.py | 34 ++-
4 files changed, 315 insertions(+), 42 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 01dc7b2..889336e 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,3 +1,3 @@
configured_endpoints: 55
-openapi_spec_hash: f17890d85522687a4c68702da9ad2efb
+openapi_spec_hash: 922886934580d0b2addcb6e26ada0e09
config_hash: 8f6e5c3b064cbb77569a6bf654954a56
diff --git a/src/codex/resources/projects/projects.py b/src/codex/resources/projects/projects.py
index 1314b7b..dc01b11 100644
--- a/src/codex/resources/projects/projects.py
+++ b/src/codex/resources/projects/projects.py
@@ -488,17 +488,18 @@ def validate(
project_id: str,
*,
context: str,
- prompt: str,
query: str,
- response: str,
+ response: project_validate_params.Response,
use_llm_matching: bool | NotGiven = NOT_GIVEN,
constrain_outputs: Optional[List[str]] | NotGiven = NOT_GIVEN,
custom_eval_thresholds: Optional[Dict[str, float]] | NotGiven = NOT_GIVEN,
custom_metadata: Optional[object] | NotGiven = NOT_GIVEN,
eval_scores: Optional[Dict[str, float]] | NotGiven = NOT_GIVEN,
- messages: Optional[Iterable[project_validate_params.Message]] | NotGiven = NOT_GIVEN,
+ messages: Iterable[project_validate_params.Message] | NotGiven = NOT_GIVEN,
options: Optional[project_validate_params.Options] | NotGiven = NOT_GIVEN,
+ prompt: Optional[str] | NotGiven = NOT_GIVEN,
quality_preset: Literal["best", "high", "medium", "low", "base"] | NotGiven = NOT_GIVEN,
+ rewritten_question: Optional[str] | NotGiven = NOT_GIVEN,
task: Optional[str] | NotGiven = NOT_GIVEN,
x_client_library_version: str | NotGiven = NOT_GIVEN,
x_integration_type: str | NotGiven = NOT_GIVEN,
@@ -526,9 +527,8 @@ def validate(
eval_scores: Scores assessing different aspects of the RAG system. If not provided, TLM will
be used to generate scores.
- messages: Optional message history to provide conversation context for the query. Used to
- rewrite query into a self-contained version of itself. If not provided, the
- query will be treated as self-contained.
+ messages: Message history to provide conversation context for the query. Messages contain
+ up to and including the latest user prompt to the LLM.
options: Typed dict of advanced configuration options for the Trustworthy Language Model.
Many of these configurations are determined by the quality preset selected
@@ -615,8 +615,14 @@ def validate(
- name: Name of the evaluation criteria.
- criteria: Instructions specifying the evaluation criteria.
+ prompt: The prompt to use for the TLM call. If not provided, the prompt will be
+ generated from the messages.
+
quality_preset: The quality preset to use for the TLM or Trustworthy RAG API.
+ rewritten_question: The re-written query if it was provided by the client to Codex from a user to be
+ used instead of the original query.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -643,7 +649,6 @@ def validate(
body=maybe_transform(
{
"context": context,
- "prompt": prompt,
"query": query,
"response": response,
"constrain_outputs": constrain_outputs,
@@ -652,7 +657,9 @@ def validate(
"eval_scores": eval_scores,
"messages": messages,
"options": options,
+ "prompt": prompt,
"quality_preset": quality_preset,
+ "rewritten_question": rewritten_question,
"task": task,
},
project_validate_params.ProjectValidateParams,
@@ -1090,17 +1097,18 @@ async def validate(
project_id: str,
*,
context: str,
- prompt: str,
query: str,
- response: str,
+ response: project_validate_params.Response,
use_llm_matching: bool | NotGiven = NOT_GIVEN,
constrain_outputs: Optional[List[str]] | NotGiven = NOT_GIVEN,
custom_eval_thresholds: Optional[Dict[str, float]] | NotGiven = NOT_GIVEN,
custom_metadata: Optional[object] | NotGiven = NOT_GIVEN,
eval_scores: Optional[Dict[str, float]] | NotGiven = NOT_GIVEN,
- messages: Optional[Iterable[project_validate_params.Message]] | NotGiven = NOT_GIVEN,
+ messages: Iterable[project_validate_params.Message] | NotGiven = NOT_GIVEN,
options: Optional[project_validate_params.Options] | NotGiven = NOT_GIVEN,
+ prompt: Optional[str] | NotGiven = NOT_GIVEN,
quality_preset: Literal["best", "high", "medium", "low", "base"] | NotGiven = NOT_GIVEN,
+ rewritten_question: Optional[str] | NotGiven = NOT_GIVEN,
task: Optional[str] | NotGiven = NOT_GIVEN,
x_client_library_version: str | NotGiven = NOT_GIVEN,
x_integration_type: str | NotGiven = NOT_GIVEN,
@@ -1128,9 +1136,8 @@ async def validate(
eval_scores: Scores assessing different aspects of the RAG system. If not provided, TLM will
be used to generate scores.
- messages: Optional message history to provide conversation context for the query. Used to
- rewrite query into a self-contained version of itself. If not provided, the
- query will be treated as self-contained.
+ messages: Message history to provide conversation context for the query. Messages contain
+ up to and including the latest user prompt to the LLM.
options: Typed dict of advanced configuration options for the Trustworthy Language Model.
Many of these configurations are determined by the quality preset selected
@@ -1217,8 +1224,14 @@ async def validate(
- name: Name of the evaluation criteria.
- criteria: Instructions specifying the evaluation criteria.
+ prompt: The prompt to use for the TLM call. If not provided, the prompt will be
+ generated from the messages.
+
quality_preset: The quality preset to use for the TLM or Trustworthy RAG API.
+ rewritten_question: The re-written query if it was provided by the client to Codex from a user to be
+ used instead of the original query.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1245,7 +1258,6 @@ async def validate(
body=await async_maybe_transform(
{
"context": context,
- "prompt": prompt,
"query": query,
"response": response,
"constrain_outputs": constrain_outputs,
@@ -1254,7 +1266,9 @@ async def validate(
"eval_scores": eval_scores,
"messages": messages,
"options": options,
+ "prompt": prompt,
"quality_preset": quality_preset,
+ "rewritten_question": rewritten_question,
"task": task,
},
project_validate_params.ProjectValidateParams,
diff --git a/src/codex/types/project_validate_params.py b/src/codex/types/project_validate_params.py
index 8b38ebf..0862cbc 100644
--- a/src/codex/types/project_validate_params.py
+++ b/src/codex/types/project_validate_params.py
@@ -2,6 +2,7 @@
from __future__ import annotations
+import builtins
from typing import Dict, List, Union, Iterable, Optional
from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict
@@ -9,6 +10,24 @@
__all__ = [
"ProjectValidateParams",
+ "Response",
+ "ResponseChatCompletion",
+ "ResponseChatCompletionChoice",
+ "ResponseChatCompletionChoiceMessage",
+ "ResponseChatCompletionChoiceMessageAnnotation",
+ "ResponseChatCompletionChoiceMessageAnnotationURLCitation",
+ "ResponseChatCompletionChoiceMessageAudio",
+ "ResponseChatCompletionChoiceMessageFunctionCall",
+ "ResponseChatCompletionChoiceMessageToolCall",
+ "ResponseChatCompletionChoiceMessageToolCallFunction",
+ "ResponseChatCompletionChoiceLogprobs",
+ "ResponseChatCompletionChoiceLogprobsContent",
+ "ResponseChatCompletionChoiceLogprobsContentTopLogprob",
+ "ResponseChatCompletionChoiceLogprobsRefusal",
+ "ResponseChatCompletionChoiceLogprobsRefusalTopLogprob",
+ "ResponseChatCompletionUsage",
+ "ResponseChatCompletionUsageCompletionTokensDetails",
+ "ResponseChatCompletionUsagePromptTokensDetails",
"Message",
"MessageChatCompletionDeveloperMessageParam",
"MessageChatCompletionDeveloperMessageParamContentUnionMember1",
@@ -41,11 +60,9 @@
class ProjectValidateParams(TypedDict, total=False):
context: Required[str]
- prompt: Required[str]
-
query: Required[str]
- response: Required[str]
+ response: Required[Response]
use_llm_matching: bool
@@ -66,11 +83,10 @@ class ProjectValidateParams(TypedDict, total=False):
If not provided, TLM will be used to generate scores.
"""
- messages: Optional[Iterable[Message]]
- """Optional message history to provide conversation context for the query.
+ messages: Iterable[Message]
+ """Message history to provide conversation context for the query.
- Used to rewrite query into a self-contained version of itself. If not provided,
- the query will be treated as self-contained.
+ Messages contain up to and including the latest user prompt to the LLM.
"""
options: Optional[Options]
@@ -161,9 +177,21 @@ class ProjectValidateParams(TypedDict, total=False):
- criteria: Instructions specifying the evaluation criteria.
"""
+ prompt: Optional[str]
+ """The prompt to use for the TLM call.
+
+ If not provided, the prompt will be generated from the messages.
+ """
+
quality_preset: Literal["best", "high", "medium", "low", "base"]
"""The quality preset to use for the TLM or Trustworthy RAG API."""
+ rewritten_question: Optional[str]
+ """
+ The re-written query if it was provided by the client to Codex from a user to be
+ used instead of the original query.
+ """
+
task: Optional[str]
x_client_library_version: Annotated[str, PropertyInfo(alias="x-client-library-version")]
@@ -175,6 +203,243 @@ class ProjectValidateParams(TypedDict, total=False):
x_stainless_package_version: Annotated[str, PropertyInfo(alias="x-stainless-package-version")]
+class ResponseChatCompletionChoiceMessageAnnotationURLCitationTyped(TypedDict, total=False):
+ end_index: Required[int]
+
+ start_index: Required[int]
+
+ title: Required[str]
+
+ url: Required[str]
+
+
+ResponseChatCompletionChoiceMessageAnnotationURLCitation: TypeAlias = Union[
+ ResponseChatCompletionChoiceMessageAnnotationURLCitationTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionChoiceMessageAnnotationTyped(TypedDict, total=False):
+ type: Required[Literal["url_citation"]]
+
+ url_citation: Required[ResponseChatCompletionChoiceMessageAnnotationURLCitation]
+
+
+ResponseChatCompletionChoiceMessageAnnotation: TypeAlias = Union[
+ ResponseChatCompletionChoiceMessageAnnotationTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionChoiceMessageAudioTyped(TypedDict, total=False):
+ id: Required[str]
+
+ data: Required[str]
+
+ expires_at: Required[int]
+
+ transcript: Required[str]
+
+
+ResponseChatCompletionChoiceMessageAudio: TypeAlias = Union[
+ ResponseChatCompletionChoiceMessageAudioTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionChoiceMessageFunctionCallTyped(TypedDict, total=False):
+ arguments: Required[str]
+
+ name: Required[str]
+
+
+ResponseChatCompletionChoiceMessageFunctionCall: TypeAlias = Union[
+ ResponseChatCompletionChoiceMessageFunctionCallTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionChoiceMessageToolCallFunctionTyped(TypedDict, total=False):
+ arguments: Required[str]
+
+ name: Required[str]
+
+
+ResponseChatCompletionChoiceMessageToolCallFunction: TypeAlias = Union[
+ ResponseChatCompletionChoiceMessageToolCallFunctionTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionChoiceMessageToolCallTyped(TypedDict, total=False):
+ id: Required[str]
+
+ function: Required[ResponseChatCompletionChoiceMessageToolCallFunction]
+
+ type: Required[Literal["function"]]
+
+
+ResponseChatCompletionChoiceMessageToolCall: TypeAlias = Union[
+ ResponseChatCompletionChoiceMessageToolCallTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionChoiceMessageTyped(TypedDict, total=False):
+ role: Required[Literal["assistant"]]
+
+ annotations: Optional[Iterable[ResponseChatCompletionChoiceMessageAnnotation]]
+
+ audio: Optional[ResponseChatCompletionChoiceMessageAudio]
+
+ content: Optional[str]
+
+ function_call: Optional[ResponseChatCompletionChoiceMessageFunctionCall]
+
+ refusal: Optional[str]
+
+ tool_calls: Optional[Iterable[ResponseChatCompletionChoiceMessageToolCall]]
+
+
+ResponseChatCompletionChoiceMessage: TypeAlias = Union[ResponseChatCompletionChoiceMessageTyped, Dict[str, object]]
+
+
+class ResponseChatCompletionChoiceLogprobsContentTopLogprobTyped(TypedDict, total=False):
+ token: Required[str]
+
+ logprob: Required[float]
+
+ bytes: Optional[Iterable[int]]
+
+
+ResponseChatCompletionChoiceLogprobsContentTopLogprob: TypeAlias = Union[
+ ResponseChatCompletionChoiceLogprobsContentTopLogprobTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionChoiceLogprobsContentTyped(TypedDict, total=False):
+ token: Required[str]
+
+ logprob: Required[float]
+
+ top_logprobs: Required[Iterable[ResponseChatCompletionChoiceLogprobsContentTopLogprob]]
+
+ bytes: Optional[Iterable[int]]
+
+
+ResponseChatCompletionChoiceLogprobsContent: TypeAlias = Union[
+ ResponseChatCompletionChoiceLogprobsContentTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionChoiceLogprobsRefusalTopLogprobTyped(TypedDict, total=False):
+ token: Required[str]
+
+ logprob: Required[float]
+
+ bytes: Optional[Iterable[int]]
+
+
+ResponseChatCompletionChoiceLogprobsRefusalTopLogprob: TypeAlias = Union[
+ ResponseChatCompletionChoiceLogprobsRefusalTopLogprobTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionChoiceLogprobsRefusalTyped(TypedDict, total=False):
+ token: Required[str]
+
+ logprob: Required[float]
+
+ top_logprobs: Required[Iterable[ResponseChatCompletionChoiceLogprobsRefusalTopLogprob]]
+
+ bytes: Optional[Iterable[int]]
+
+
+ResponseChatCompletionChoiceLogprobsRefusal: TypeAlias = Union[
+ ResponseChatCompletionChoiceLogprobsRefusalTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionChoiceLogprobsTyped(TypedDict, total=False):
+ content: Optional[Iterable[ResponseChatCompletionChoiceLogprobsContent]]
+
+ refusal: Optional[Iterable[ResponseChatCompletionChoiceLogprobsRefusal]]
+
+
+ResponseChatCompletionChoiceLogprobs: TypeAlias = Union[ResponseChatCompletionChoiceLogprobsTyped, Dict[str, object]]
+
+
+class ResponseChatCompletionChoiceTyped(TypedDict, total=False):
+ finish_reason: Required[Literal["stop", "length", "tool_calls", "content_filter", "function_call"]]
+
+ index: Required[int]
+
+ message: Required[ResponseChatCompletionChoiceMessage]
+
+ logprobs: Optional[ResponseChatCompletionChoiceLogprobs]
+
+
+ResponseChatCompletionChoice: TypeAlias = Union[ResponseChatCompletionChoiceTyped, Dict[str, object]]
+
+
+class ResponseChatCompletionUsageCompletionTokensDetailsTyped(TypedDict, total=False):
+ accepted_prediction_tokens: Optional[int]
+
+ audio_tokens: Optional[int]
+
+ reasoning_tokens: Optional[int]
+
+ rejected_prediction_tokens: Optional[int]
+
+
+ResponseChatCompletionUsageCompletionTokensDetails: TypeAlias = Union[
+ ResponseChatCompletionUsageCompletionTokensDetailsTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionUsagePromptTokensDetailsTyped(TypedDict, total=False):
+ audio_tokens: Optional[int]
+
+ cached_tokens: Optional[int]
+
+
+ResponseChatCompletionUsagePromptTokensDetails: TypeAlias = Union[
+ ResponseChatCompletionUsagePromptTokensDetailsTyped, Dict[str, object]
+]
+
+
+class ResponseChatCompletionUsageTyped(TypedDict, total=False):
+ completion_tokens: Required[int]
+
+ prompt_tokens: Required[int]
+
+ total_tokens: Required[int]
+
+ completion_tokens_details: Optional[ResponseChatCompletionUsageCompletionTokensDetails]
+
+ prompt_tokens_details: Optional[ResponseChatCompletionUsagePromptTokensDetails]
+
+
+ResponseChatCompletionUsage: TypeAlias = Union[ResponseChatCompletionUsageTyped, Dict[str, object]]
+
+
+class ResponseChatCompletionTyped(TypedDict, total=False):
+ id: Required[str]
+
+ choices: Required[Iterable[ResponseChatCompletionChoice]]
+
+ created: Required[int]
+
+ model: Required[str]
+
+ object: Required[Literal["chat.completion"]]
+
+ service_tier: Optional[Literal["scale", "default"]]
+
+ system_fingerprint: Optional[str]
+
+ usage: Optional[ResponseChatCompletionUsage]
+
+
+ResponseChatCompletion: TypeAlias = Union[ResponseChatCompletionTyped, Dict[str, builtins.object]]
+
+Response: TypeAlias = Union[str, ResponseChatCompletion]
+
+
class MessageChatCompletionDeveloperMessageParamContentUnionMember1(TypedDict, total=False):
text: Required[str]
diff --git a/tests/api_resources/test_projects.py b/tests/api_resources/test_projects.py
index 0764d9a..9ecffa0 100644
--- a/tests/api_resources/test_projects.py
+++ b/tests/api_resources/test_projects.py
@@ -632,9 +632,8 @@ def test_method_validate(self, client: Codex) -> None:
project = client.projects.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
- prompt="prompt",
query="query",
- response="response",
+ response="string",
)
assert_matches_type(ProjectValidateResponse, project, path=["response"])
@@ -644,9 +643,8 @@ def test_method_validate_with_all_params(self, client: Codex) -> None:
project = client.projects.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
- prompt="prompt",
query="query",
- response="response",
+ response="string",
use_llm_matching=True,
constrain_outputs=["string"],
custom_eval_thresholds={"foo": 0},
@@ -670,7 +668,9 @@ def test_method_validate_with_all_params(self, client: Codex) -> None:
"similarity_measure": "similarity_measure",
"use_self_reflection": True,
},
+ prompt="prompt",
quality_preset="best",
+ rewritten_question="rewritten_question",
task="task",
x_client_library_version="x-client-library-version",
x_integration_type="x-integration-type",
@@ -685,9 +685,8 @@ def test_raw_response_validate(self, client: Codex) -> None:
response = client.projects.with_raw_response.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
- prompt="prompt",
query="query",
- response="response",
+ response="string",
)
assert response.is_closed is True
@@ -701,9 +700,8 @@ def test_streaming_response_validate(self, client: Codex) -> None:
with client.projects.with_streaming_response.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
- prompt="prompt",
query="query",
- response="response",
+ response="string",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -720,9 +718,8 @@ def test_path_params_validate(self, client: Codex) -> None:
client.projects.with_raw_response.validate(
project_id="",
context="context",
- prompt="prompt",
query="query",
- response="response",
+ response="string",
)
@@ -1337,9 +1334,8 @@ async def test_method_validate(self, async_client: AsyncCodex) -> None:
project = await async_client.projects.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
- prompt="prompt",
query="query",
- response="response",
+ response="string",
)
assert_matches_type(ProjectValidateResponse, project, path=["response"])
@@ -1349,9 +1345,8 @@ async def test_method_validate_with_all_params(self, async_client: AsyncCodex) -
project = await async_client.projects.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
- prompt="prompt",
query="query",
- response="response",
+ response="string",
use_llm_matching=True,
constrain_outputs=["string"],
custom_eval_thresholds={"foo": 0},
@@ -1375,7 +1370,9 @@ async def test_method_validate_with_all_params(self, async_client: AsyncCodex) -
"similarity_measure": "similarity_measure",
"use_self_reflection": True,
},
+ prompt="prompt",
quality_preset="best",
+ rewritten_question="rewritten_question",
task="task",
x_client_library_version="x-client-library-version",
x_integration_type="x-integration-type",
@@ -1390,9 +1387,8 @@ async def test_raw_response_validate(self, async_client: AsyncCodex) -> None:
response = await async_client.projects.with_raw_response.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
- prompt="prompt",
query="query",
- response="response",
+ response="string",
)
assert response.is_closed is True
@@ -1406,9 +1402,8 @@ async def test_streaming_response_validate(self, async_client: AsyncCodex) -> No
async with async_client.projects.with_streaming_response.validate(
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
context="context",
- prompt="prompt",
query="query",
- response="response",
+ response="string",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -1425,7 +1420,6 @@ async def test_path_params_validate(self, async_client: AsyncCodex) -> None:
await async_client.projects.with_raw_response.validate(
project_id="",
context="context",
- prompt="prompt",
query="query",
- response="response",
+ response="string",
)
From 257a8f68216001ac2b1d16165dfda532ac54e57e Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 7 Jul 2025 23:47:55 +0000
Subject: [PATCH 18/18] release: 0.1.0-alpha.23
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 30 ++++++++++++++++++++++++++++++
pyproject.toml | 2 +-
src/codex/_version.py | 2 +-
4 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index aa84875..1c0bb88 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.1.0-alpha.22"
+ ".": "0.1.0-alpha.23"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2b2988f..131d328 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,35 @@
# Changelog
+## 0.1.0-alpha.23 (2025-07-07)
+
+Full Changelog: [v0.1.0-alpha.22...v0.1.0-alpha.23](https://github.com/cleanlab/codex-python/compare/v0.1.0-alpha.22...v0.1.0-alpha.23)
+
+### Features
+
+* **api:** api update ([29f65d7](https://github.com/cleanlab/codex-python/commit/29f65d74a04a8424cc666669167c8ba56a56485b))
+* **api:** api update ([bc15e90](https://github.com/cleanlab/codex-python/commit/bc15e9004a8f3a2b311ceeb851b5f6a666a2698b))
+* **api:** api update ([75b1e81](https://github.com/cleanlab/codex-python/commit/75b1e81e199ff4721ff21b3920bc82a48006df21))
+* **api:** api update ([ab93d9d](https://github.com/cleanlab/codex-python/commit/ab93d9d3990f52924b92518d6249f30783591a42))
+* **api:** api update ([0207b98](https://github.com/cleanlab/codex-python/commit/0207b98b34d0a484c6701d04e32ef56190936201))
+* **api:** api update ([31096f4](https://github.com/cleanlab/codex-python/commit/31096f4820a7bfdd204b0a2d1d84ab1e36e32d0c))
+* **api:** api update ([be06884](https://github.com/cleanlab/codex-python/commit/be06884d321ca5009c9d82346c1b74c7429f82fa))
+* **api:** api update ([41b210d](https://github.com/cleanlab/codex-python/commit/41b210dc69c2b9c45eeab01a0afac6a4563d41f2))
+* **api:** define pagination schemes ([d36c2c7](https://github.com/cleanlab/codex-python/commit/d36c2c7ca7a9155dab71b1c82f2e163488d32086))
+* **api:** more pagination schemes ([d4d82fe](https://github.com/cleanlab/codex-python/commit/d4d82fe33422f460c83778dc0ca767361dce86a5))
+* **api:** remove entries routes ([e80bee9](https://github.com/cleanlab/codex-python/commit/e80bee98b4f91ca7c0c19509d1f6a4f9f6bfd2c7))
+
+
+### Bug Fixes
+
+* **ci:** correct conditional ([45d3bc0](https://github.com/cleanlab/codex-python/commit/45d3bc05ab56d3e67d036ce84b2c9a1f2d8cfd69))
+* **ci:** release-doctor — report correct token name ([1a5e444](https://github.com/cleanlab/codex-python/commit/1a5e444226c829392181d98bc06f8cfb8bf13bd9))
+
+
+### Chores
+
+* **ci:** change upload type ([023823b](https://github.com/cleanlab/codex-python/commit/023823bace71bdc65ce1ff432373a26731ec43d4))
+* **ci:** only run for pushes and fork pull requests ([6b590bd](https://github.com/cleanlab/codex-python/commit/6b590bd454e939b8453d95c239ee85be1a326909))
+
## 0.1.0-alpha.22 (2025-06-24)
Full Changelog: [v0.1.0-alpha.21...v0.1.0-alpha.22](https://github.com/cleanlab/codex-python/compare/v0.1.0-alpha.21...v0.1.0-alpha.22)
diff --git a/pyproject.toml b/pyproject.toml
index b71f9f0..16e362c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "codex-sdk"
-version = "0.1.0-alpha.22"
+version = "0.1.0-alpha.23"
description = "Internal SDK used within cleanlab-codex package. Refer to https://pypi.org/project/cleanlab-codex/ instead."
dynamic = ["readme"]
license = "MIT"
diff --git a/src/codex/_version.py b/src/codex/_version.py
index a88a1c3..18f2dcb 100644
--- a/src/codex/_version.py
+++ b/src/codex/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "codex"
-__version__ = "0.1.0-alpha.22" # x-release-please-version
+__version__ = "0.1.0-alpha.23" # x-release-please-version