From 321392cfd9ac98fe1ad0b06d21f26441e70c90fc Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 16 Oct 2025 00:18:03 +0000
Subject: [PATCH 1/9] feat(api): api update
---
.stats.yml | 2 +-
src/codex/types/project_detect_response.py | 17 ++---------------
2 files changed, 3 insertions(+), 16 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 2e71139..f15ec6d 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,3 +1,3 @@
configured_endpoints: 55
-openapi_spec_hash: c894ce3fb9db92c69816f06896e30067
+openapi_spec_hash: 2a1aded6c0f311e6133ba9beadc08062
config_hash: 48c3812186c899cdef23cc8de76bd2aa
diff --git a/src/codex/types/project_detect_response.py b/src/codex/types/project_detect_response.py
index cdee7dc..4e4b74f 100644
--- a/src/codex/types/project_detect_response.py
+++ b/src/codex/types/project_detect_response.py
@@ -1,20 +1,10 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List, Optional
+from typing import Dict, Optional
from .._models import BaseModel
-__all__ = ["ProjectDetectResponse", "DeterministicGuardrailsResults", "EvalScores"]
-
-
-class DeterministicGuardrailsResults(BaseModel):
- guardrail_name: str
-
- should_guardrail: bool
-
- fallback_message: Optional[str] = None
-
- matches: Optional[List[str]] = None
+__all__ = ["ProjectDetectResponse", "EvalScores"]
class EvalScores(BaseModel):
@@ -32,9 +22,6 @@ class EvalScores(BaseModel):
class ProjectDetectResponse(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
From 377dc6b4dad3ba898b9fda4fe305d4c25b1ee781 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 16 Oct 2025 17:18:05 +0000
Subject: [PATCH 2/9] feat(api): api update
---
.stats.yml | 2 +-
src/codex/types/project_list_response.py | 30 ++++++++++++++++++++
src/codex/types/project_retrieve_response.py | 30 ++++++++++++++++++++
src/codex/types/project_return_schema.py | 30 ++++++++++++++++++++
4 files changed, 91 insertions(+), 1 deletion(-)
diff --git a/.stats.yml b/.stats.yml
index f15ec6d..0b4fc39 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,3 +1,3 @@
configured_endpoints: 55
-openapi_spec_hash: 2a1aded6c0f311e6133ba9beadc08062
+openapi_spec_hash: 26ac4152b9f12f890d1df1cf1a219f78
config_hash: 48c3812186c899cdef23cc8de76bd2aa
diff --git a/src/codex/types/project_list_response.py b/src/codex/types/project_list_response.py
index 5b2d692..567eff8 100644
--- a/src/codex/types/project_list_response.py
+++ b/src/codex/types/project_list_response.py
@@ -101,6 +101,12 @@ class ProjectConfigEvalConfigCustomEvals(BaseModel):
class ProjectConfigEvalConfigDefaultEvalsContextSufficiency(BaseModel):
+ display_name: str
+ """Human-friendly name for display.
+
+ For default evals, use standardized labels from DEFAULT_EVAL_ISSUE_TYPE_LABELS.
+ """
+
eval_key: str
"""
Unique key for eval metric - currently maps to the TrustworthyRAG name property
@@ -142,6 +148,12 @@ class ProjectConfigEvalConfigDefaultEvalsContextSufficiency(BaseModel):
class ProjectConfigEvalConfigDefaultEvalsQueryEase(BaseModel):
+ display_name: str
+ """Human-friendly name for display.
+
+ For default evals, use standardized labels from DEFAULT_EVAL_ISSUE_TYPE_LABELS.
+ """
+
eval_key: str
"""
Unique key for eval metric - currently maps to the TrustworthyRAG name property
@@ -183,6 +195,12 @@ class ProjectConfigEvalConfigDefaultEvalsQueryEase(BaseModel):
class ProjectConfigEvalConfigDefaultEvalsResponseGroundedness(BaseModel):
+ display_name: str
+ """Human-friendly name for display.
+
+ For default evals, use standardized labels from DEFAULT_EVAL_ISSUE_TYPE_LABELS.
+ """
+
eval_key: str
"""
Unique key for eval metric - currently maps to the TrustworthyRAG name property
@@ -224,6 +242,12 @@ class ProjectConfigEvalConfigDefaultEvalsResponseGroundedness(BaseModel):
class ProjectConfigEvalConfigDefaultEvalsResponseHelpfulness(BaseModel):
+ display_name: str
+ """Human-friendly name for display.
+
+ For default evals, use standardized labels from DEFAULT_EVAL_ISSUE_TYPE_LABELS.
+ """
+
eval_key: str
"""
Unique key for eval metric - currently maps to the TrustworthyRAG name property
@@ -265,6 +289,12 @@ class ProjectConfigEvalConfigDefaultEvalsResponseHelpfulness(BaseModel):
class ProjectConfigEvalConfigDefaultEvalsTrustworthiness(BaseModel):
+ display_name: str
+ """Human-friendly name for display.
+
+ For default evals, use standardized labels from DEFAULT_EVAL_ISSUE_TYPE_LABELS.
+ """
+
eval_key: str
"""
Unique key for eval metric - currently maps to the TrustworthyRAG name property
diff --git a/src/codex/types/project_retrieve_response.py b/src/codex/types/project_retrieve_response.py
index 399ddd9..40b4f18 100644
--- a/src/codex/types/project_retrieve_response.py
+++ b/src/codex/types/project_retrieve_response.py
@@ -99,6 +99,12 @@ class ConfigEvalConfigCustomEvals(BaseModel):
class ConfigEvalConfigDefaultEvalsContextSufficiency(BaseModel):
+ display_name: str
+ """Human-friendly name for display.
+
+ For default evals, use standardized labels from DEFAULT_EVAL_ISSUE_TYPE_LABELS.
+ """
+
eval_key: str
"""
Unique key for eval metric - currently maps to the TrustworthyRAG name property
@@ -140,6 +146,12 @@ class ConfigEvalConfigDefaultEvalsContextSufficiency(BaseModel):
class ConfigEvalConfigDefaultEvalsQueryEase(BaseModel):
+ display_name: str
+ """Human-friendly name for display.
+
+ For default evals, use standardized labels from DEFAULT_EVAL_ISSUE_TYPE_LABELS.
+ """
+
eval_key: str
"""
Unique key for eval metric - currently maps to the TrustworthyRAG name property
@@ -181,6 +193,12 @@ class ConfigEvalConfigDefaultEvalsQueryEase(BaseModel):
class ConfigEvalConfigDefaultEvalsResponseGroundedness(BaseModel):
+ display_name: str
+ """Human-friendly name for display.
+
+ For default evals, use standardized labels from DEFAULT_EVAL_ISSUE_TYPE_LABELS.
+ """
+
eval_key: str
"""
Unique key for eval metric - currently maps to the TrustworthyRAG name property
@@ -222,6 +240,12 @@ class ConfigEvalConfigDefaultEvalsResponseGroundedness(BaseModel):
class ConfigEvalConfigDefaultEvalsResponseHelpfulness(BaseModel):
+ display_name: str
+ """Human-friendly name for display.
+
+ For default evals, use standardized labels from DEFAULT_EVAL_ISSUE_TYPE_LABELS.
+ """
+
eval_key: str
"""
Unique key for eval metric - currently maps to the TrustworthyRAG name property
@@ -263,6 +287,12 @@ class ConfigEvalConfigDefaultEvalsResponseHelpfulness(BaseModel):
class ConfigEvalConfigDefaultEvalsTrustworthiness(BaseModel):
+ display_name: str
+ """Human-friendly name for display.
+
+ For default evals, use standardized labels from DEFAULT_EVAL_ISSUE_TYPE_LABELS.
+ """
+
eval_key: str
"""
Unique key for eval metric - currently maps to the TrustworthyRAG name property
diff --git a/src/codex/types/project_return_schema.py b/src/codex/types/project_return_schema.py
index 923de6b..4bab16f 100644
--- a/src/codex/types/project_return_schema.py
+++ b/src/codex/types/project_return_schema.py
@@ -99,6 +99,12 @@ class ConfigEvalConfigCustomEvals(BaseModel):
class ConfigEvalConfigDefaultEvalsContextSufficiency(BaseModel):
+ display_name: str
+ """Human-friendly name for display.
+
+ For default evals, use standardized labels from DEFAULT_EVAL_ISSUE_TYPE_LABELS.
+ """
+
eval_key: str
"""
Unique key for eval metric - currently maps to the TrustworthyRAG name property
@@ -140,6 +146,12 @@ class ConfigEvalConfigDefaultEvalsContextSufficiency(BaseModel):
class ConfigEvalConfigDefaultEvalsQueryEase(BaseModel):
+ display_name: str
+ """Human-friendly name for display.
+
+ For default evals, use standardized labels from DEFAULT_EVAL_ISSUE_TYPE_LABELS.
+ """
+
eval_key: str
"""
Unique key for eval metric - currently maps to the TrustworthyRAG name property
@@ -181,6 +193,12 @@ class ConfigEvalConfigDefaultEvalsQueryEase(BaseModel):
class ConfigEvalConfigDefaultEvalsResponseGroundedness(BaseModel):
+ display_name: str
+ """Human-friendly name for display.
+
+ For default evals, use standardized labels from DEFAULT_EVAL_ISSUE_TYPE_LABELS.
+ """
+
eval_key: str
"""
Unique key for eval metric - currently maps to the TrustworthyRAG name property
@@ -222,6 +240,12 @@ class ConfigEvalConfigDefaultEvalsResponseGroundedness(BaseModel):
class ConfigEvalConfigDefaultEvalsResponseHelpfulness(BaseModel):
+ display_name: str
+ """Human-friendly name for display.
+
+ For default evals, use standardized labels from DEFAULT_EVAL_ISSUE_TYPE_LABELS.
+ """
+
eval_key: str
"""
Unique key for eval metric - currently maps to the TrustworthyRAG name property
@@ -263,6 +287,12 @@ class ConfigEvalConfigDefaultEvalsResponseHelpfulness(BaseModel):
class ConfigEvalConfigDefaultEvalsTrustworthiness(BaseModel):
+ display_name: str
+ """Human-friendly name for display.
+
+ For default evals, use standardized labels from DEFAULT_EVAL_ISSUE_TYPE_LABELS.
+ """
+
eval_key: str
"""
Unique key for eval metric - currently maps to the TrustworthyRAG name property
From 666f855d5532589f5ffbe0b53a5de65355ec33aa Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 18 Oct 2025 02:06:43 +0000
Subject: [PATCH 3/9] chore: bump `httpx-aiohttp` version to 0.1.9
---
pyproject.toml | 2 +-
requirements-dev.lock | 2 +-
requirements.lock | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/pyproject.toml b/pyproject.toml
index 4e0140e..39ee576 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -39,7 +39,7 @@ Homepage = "https://github.com/cleanlab/codex-python"
Repository = "https://github.com/cleanlab/codex-python"
[project.optional-dependencies]
-aiohttp = ["aiohttp", "httpx_aiohttp>=0.1.8"]
+aiohttp = ["aiohttp", "httpx_aiohttp>=0.1.9"]
[tool.rye]
managed = true
diff --git a/requirements-dev.lock b/requirements-dev.lock
index 2aaac36..d728372 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.8
+httpx-aiohttp==0.1.9
# via codex-sdk
idna==3.4
# via anyio
diff --git a/requirements.lock b/requirements.lock
index a018274..4b916da 100644
--- a/requirements.lock
+++ b/requirements.lock
@@ -43,7 +43,7 @@ httpcore==1.0.9
httpx==0.28.1
# via codex-sdk
# via httpx-aiohttp
-httpx-aiohttp==0.1.8
+httpx-aiohttp==0.1.9
# via codex-sdk
idna==3.4
# via anyio
From 766e3314ad8a72522fa29804b3edc328bab3b4af Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 20 Oct 2025 18:18:07 +0000
Subject: [PATCH 4/9] feat(api): api update
---
.stats.yml | 2 +-
src/codex/types/projects/query_log_list_by_group_response.py | 3 +++
src/codex/types/projects/query_log_list_groups_response.py | 3 +++
src/codex/types/projects/query_log_list_response.py | 3 +++
src/codex/types/projects/query_log_retrieve_response.py | 3 +++
.../types/projects/remediation_list_resolved_logs_response.py | 3 +++
6 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/.stats.yml b/.stats.yml
index 0b4fc39..4b93f8a 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,3 +1,3 @@
configured_endpoints: 55
-openapi_spec_hash: 26ac4152b9f12f890d1df1cf1a219f78
+openapi_spec_hash: d555131ff52c78852f82acda3348224b
config_hash: 48c3812186c899cdef23cc8de76bd2aa
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 632a375..3b4544e 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
@@ -472,6 +472,9 @@ class QueryLogsByGroupQueryLog(BaseModel):
primary_eval_issue_score: Optional[float] = None
"""Score of the primary eval issue"""
+ served_remediation_id: Optional[str] = None
+ """ID of the remediation that was served if cache hit, otherwise None."""
+
tools: Optional[List[QueryLogsByGroupQueryLogTool]] = None
"""Tools to use for the LLM call.
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 3d894f1..01b2824 100644
--- a/src/codex/types/projects/query_log_list_groups_response.py
+++ b/src/codex/types/projects/query_log_list_groups_response.py
@@ -467,6 +467,9 @@ class QueryLogListGroupsResponse(BaseModel):
primary_eval_issue_score: Optional[float] = None
"""Score of the primary eval issue"""
+ served_remediation_id: Optional[str] = None
+ """ID of the remediation that was served if cache hit, otherwise None."""
+
tools: Optional[List[Tool]] = None
"""Tools to use for the LLM call.
diff --git a/src/codex/types/projects/query_log_list_response.py b/src/codex/types/projects/query_log_list_response.py
index 8e57871..d401dd6 100644
--- a/src/codex/types/projects/query_log_list_response.py
+++ b/src/codex/types/projects/query_log_list_response.py
@@ -452,6 +452,9 @@ class QueryLogListResponse(BaseModel):
primary_eval_issue_score: Optional[float] = None
"""Score of the primary eval issue"""
+ served_remediation_id: Optional[str] = None
+ """ID of the remediation that was served if cache hit, otherwise None."""
+
tools: Optional[List[Tool]] = None
"""Tools to use for the LLM call.
diff --git a/src/codex/types/projects/query_log_retrieve_response.py b/src/codex/types/projects/query_log_retrieve_response.py
index ef1aee6..5ca091f 100644
--- a/src/codex/types/projects/query_log_retrieve_response.py
+++ b/src/codex/types/projects/query_log_retrieve_response.py
@@ -459,6 +459,9 @@ class QueryLogRetrieveResponse(BaseModel):
primary_eval_issue_score: Optional[float] = None
"""Score of the primary eval issue"""
+ served_remediation_id: Optional[str] = None
+ """ID of the remediation that was served if cache hit, otherwise None."""
+
tools: Optional[List[Tool]] = None
"""Tools to use for the LLM call.
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 f85be78..3cb9131 100644
--- a/src/codex/types/projects/remediation_list_resolved_logs_response.py
+++ b/src/codex/types/projects/remediation_list_resolved_logs_response.py
@@ -459,6 +459,9 @@ class QueryLog(BaseModel):
primary_eval_issue_score: Optional[float] = None
"""Score of the primary eval issue"""
+ served_remediation_id: Optional[str] = None
+ """ID of the remediation that was served if cache hit, otherwise None."""
+
tools: Optional[List[QueryLogTool]] = None
"""Tools to use for the LLM call.
From 546858021affa494867222bf7e87fb55c867df41 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 25 Oct 2025 01:17:42 +0000
Subject: [PATCH 5/9] feat(api): api update
---
.stats.yml | 2 +-
src/codex/types/project_create_params.py | 2 ++
src/codex/types/project_list_response.py | 2 ++
src/codex/types/project_retrieve_response.py | 2 ++
src/codex/types/project_return_schema.py | 2 ++
src/codex/types/project_update_params.py | 2 ++
src/codex/types/projects/query_log_list_by_group_response.py | 3 +++
src/codex/types/projects/query_log_list_groups_response.py | 3 +++
src/codex/types/projects/query_log_list_response.py | 3 +++
src/codex/types/projects/query_log_retrieve_response.py | 3 +++
.../types/projects/remediation_list_resolved_logs_response.py | 3 +++
tests/api_resources/test_projects.py | 4 ++++
12 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/.stats.yml b/.stats.yml
index 4b93f8a..728c28d 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,3 +1,3 @@
configured_endpoints: 55
-openapi_spec_hash: d555131ff52c78852f82acda3348224b
+openapi_spec_hash: 218b257d101099fcf62b8afde2fc5d8c
config_hash: 48c3812186c899cdef23cc8de76bd2aa
diff --git a/src/codex/types/project_create_params.py b/src/codex/types/project_create_params.py
index c17be67..bd14d3d 100644
--- a/src/codex/types/project_create_params.py
+++ b/src/codex/types/project_create_params.py
@@ -354,6 +354,8 @@ class ConfigEvalConfig(TypedDict, total=False):
class Config(TypedDict, total=False):
+ ai_guidance_threshold: float
+
clustering_use_llm_matching: bool
eval_config: ConfigEvalConfig
diff --git a/src/codex/types/project_list_response.py b/src/codex/types/project_list_response.py
index 567eff8..209b1a3 100644
--- a/src/codex/types/project_list_response.py
+++ b/src/codex/types/project_list_response.py
@@ -381,6 +381,8 @@ class ProjectConfigEvalConfig(BaseModel):
class ProjectConfig(BaseModel):
+ ai_guidance_threshold: Optional[float] = None
+
clustering_use_llm_matching: Optional[bool] = None
eval_config: Optional[ProjectConfigEvalConfig] = None
diff --git a/src/codex/types/project_retrieve_response.py b/src/codex/types/project_retrieve_response.py
index 40b4f18..b26c9c1 100644
--- a/src/codex/types/project_retrieve_response.py
+++ b/src/codex/types/project_retrieve_response.py
@@ -379,6 +379,8 @@ class ConfigEvalConfig(BaseModel):
class Config(BaseModel):
+ ai_guidance_threshold: Optional[float] = None
+
clustering_use_llm_matching: Optional[bool] = None
eval_config: Optional[ConfigEvalConfig] = None
diff --git a/src/codex/types/project_return_schema.py b/src/codex/types/project_return_schema.py
index 4bab16f..10a8ea3 100644
--- a/src/codex/types/project_return_schema.py
+++ b/src/codex/types/project_return_schema.py
@@ -379,6 +379,8 @@ class ConfigEvalConfig(BaseModel):
class Config(BaseModel):
+ ai_guidance_threshold: Optional[float] = None
+
clustering_use_llm_matching: Optional[bool] = None
eval_config: Optional[ConfigEvalConfig] = None
diff --git a/src/codex/types/project_update_params.py b/src/codex/types/project_update_params.py
index 4b4de76..4ca5abf 100644
--- a/src/codex/types/project_update_params.py
+++ b/src/codex/types/project_update_params.py
@@ -352,6 +352,8 @@ class ConfigEvalConfig(TypedDict, total=False):
class Config(TypedDict, total=False):
+ ai_guidance_threshold: float
+
clustering_use_llm_matching: bool
eval_config: ConfigEvalConfig
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 3b4544e..5df928b 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
@@ -374,6 +374,9 @@ class QueryLogsByGroupQueryLog(BaseModel):
was_cache_hit: Optional[bool] = None
"""If similar query already answered, or None if cache was not checked"""
+ ai_guidance_id: Optional[str] = None
+ """ID of the AI guidance remediation that was created from this query log."""
+
context: Optional[List[QueryLogsByGroupQueryLogContext]] = None
"""RAG context used for the query"""
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 01b2824..727cac2 100644
--- a/src/codex/types/projects/query_log_list_groups_response.py
+++ b/src/codex/types/projects/query_log_list_groups_response.py
@@ -369,6 +369,9 @@ class QueryLogListGroupsResponse(BaseModel):
was_cache_hit: Optional[bool] = None
"""If similar query already answered, or None if cache was not checked"""
+ ai_guidance_id: Optional[str] = None
+ """ID of the AI guidance remediation that was created from this query log."""
+
context: Optional[List[Context]] = None
"""RAG context used for the query"""
diff --git a/src/codex/types/projects/query_log_list_response.py b/src/codex/types/projects/query_log_list_response.py
index d401dd6..0a8b427 100644
--- a/src/codex/types/projects/query_log_list_response.py
+++ b/src/codex/types/projects/query_log_list_response.py
@@ -357,6 +357,9 @@ class QueryLogListResponse(BaseModel):
was_cache_hit: Optional[bool] = None
"""If similar query already answered, or None if cache was not checked"""
+ ai_guidance_id: Optional[str] = None
+ """ID of the AI guidance remediation that was created from this query log."""
+
context: Optional[List[Context]] = None
"""RAG context used for the query"""
diff --git a/src/codex/types/projects/query_log_retrieve_response.py b/src/codex/types/projects/query_log_retrieve_response.py
index 5ca091f..13510f8 100644
--- a/src/codex/types/projects/query_log_retrieve_response.py
+++ b/src/codex/types/projects/query_log_retrieve_response.py
@@ -361,6 +361,9 @@ class QueryLogRetrieveResponse(BaseModel):
was_cache_hit: Optional[bool] = None
"""If similar query already answered, or None if cache was not checked"""
+ ai_guidance_id: Optional[str] = None
+ """ID of the AI guidance remediation that was created from this query log."""
+
context: Optional[List[Context]] = None
"""RAG context used for the query"""
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 3cb9131..16017b4 100644
--- a/src/codex/types/projects/remediation_list_resolved_logs_response.py
+++ b/src/codex/types/projects/remediation_list_resolved_logs_response.py
@@ -364,6 +364,9 @@ class QueryLog(BaseModel):
was_cache_hit: Optional[bool] = None
"""If similar query already answered, or None if cache was not checked"""
+ ai_guidance_id: Optional[str] = None
+ """ID of the AI guidance remediation that was created from this query log."""
+
context: Optional[List[QueryLogContext]] = None
"""RAG context used for the query"""
diff --git a/tests/api_resources/test_projects.py b/tests/api_resources/test_projects.py
index 564da9a..6b742b4 100644
--- a/tests/api_resources/test_projects.py
+++ b/tests/api_resources/test_projects.py
@@ -40,6 +40,7 @@ def test_method_create(self, client: Codex) -> None:
def test_method_create_with_all_params(self, client: Codex) -> None:
project = client.projects.create(
config={
+ "ai_guidance_threshold": 0,
"clustering_use_llm_matching": True,
"eval_config": {
"custom_evals": {
@@ -224,6 +225,7 @@ def test_method_update_with_all_params(self, client: Codex) -> None:
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
auto_clustering_enabled=True,
config={
+ "ai_guidance_threshold": 0,
"clustering_use_llm_matching": True,
"eval_config": {
"custom_evals": {
@@ -928,6 +930,7 @@ async def test_method_create(self, async_client: AsyncCodex) -> None:
async def test_method_create_with_all_params(self, async_client: AsyncCodex) -> None:
project = await async_client.projects.create(
config={
+ "ai_guidance_threshold": 0,
"clustering_use_llm_matching": True,
"eval_config": {
"custom_evals": {
@@ -1112,6 +1115,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCodex) ->
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
auto_clustering_enabled=True,
config={
+ "ai_guidance_threshold": 0,
"clustering_use_llm_matching": True,
"eval_config": {
"custom_evals": {
From 246c9b8474f7b9bc095418b6509c36530b59d971 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 25 Oct 2025 04:17:41 +0000
Subject: [PATCH 6/9] codegen metadata
---
.stats.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.stats.yml b/.stats.yml
index 728c28d..357f808 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,3 +1,3 @@
configured_endpoints: 55
-openapi_spec_hash: 218b257d101099fcf62b8afde2fc5d8c
+openapi_spec_hash: d719fa1f3cf8b6b5685d1c583e6d1a2a
config_hash: 48c3812186c899cdef23cc8de76bd2aa
From 1481cd895f093e9f044e438b7c26fc52f73ee791 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 28 Oct 2025 17:17:37 +0000
Subject: [PATCH 7/9] feat(api): api update
---
.stats.yml | 2 +-
src/codex/types/project_list_response.py | 2 ++
src/codex/types/project_retrieve_response.py | 2 ++
src/codex/types/project_return_schema.py | 2 ++
4 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/.stats.yml b/.stats.yml
index 357f808..3f2e10b 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,3 +1,3 @@
configured_endpoints: 55
-openapi_spec_hash: d719fa1f3cf8b6b5685d1c583e6d1a2a
+openapi_spec_hash: ef178c3ce0c31f0785212f1138ee8eee
config_hash: 48c3812186c899cdef23cc8de76bd2aa
diff --git a/src/codex/types/project_list_response.py b/src/codex/types/project_list_response.py
index 209b1a3..66d2037 100644
--- a/src/codex/types/project_list_response.py
+++ b/src/codex/types/project_list_response.py
@@ -416,6 +416,8 @@ class Project(BaseModel):
created_by_user_id: str
+ is_template: bool
+
name: str
organization_id: str
diff --git a/src/codex/types/project_retrieve_response.py b/src/codex/types/project_retrieve_response.py
index b26c9c1..694f590 100644
--- a/src/codex/types/project_retrieve_response.py
+++ b/src/codex/types/project_retrieve_response.py
@@ -414,6 +414,8 @@ class ProjectRetrieveResponse(BaseModel):
created_by_user_id: str
+ is_template: bool
+
name: str
organization_id: str
diff --git a/src/codex/types/project_return_schema.py b/src/codex/types/project_return_schema.py
index 10a8ea3..b8b5404 100644
--- a/src/codex/types/project_return_schema.py
+++ b/src/codex/types/project_return_schema.py
@@ -414,6 +414,8 @@ class ProjectReturnSchema(BaseModel):
created_by_user_id: str
+ is_template: bool
+
name: str
organization_id: str
From bb733b1122b9e52160acb3e3b92b00bf941efce5 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 28 Oct 2025 17:21:00 +0000
Subject: [PATCH 8/9] feat(api): add create from template
---
.stats.yml | 4 +-
api.md | 1 +
src/codex/resources/projects/projects.py | 111 ++++++++++++++++++
src/codex/types/__init__.py | 1 +
.../project_create_from_template_params.py | 18 +++
tests/api_resources/test_projects.py | 90 ++++++++++++++
6 files changed, 223 insertions(+), 2 deletions(-)
create mode 100644 src/codex/types/project_create_from_template_params.py
diff --git a/.stats.yml b/.stats.yml
index 3f2e10b..5add63e 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,3 +1,3 @@
-configured_endpoints: 55
+configured_endpoints: 56
openapi_spec_hash: ef178c3ce0c31f0785212f1138ee8eee
-config_hash: 48c3812186c899cdef23cc8de76bd2aa
+config_hash: 9e0ed146f9f6e6d1884a4c0589d6f1c2
diff --git a/api.md b/api.md
index 5d40e15..a288874 100644
--- a/api.md
+++ b/api.md
@@ -153,6 +153,7 @@ Methods:
- client.projects.update(project_id, \*\*params) -> ProjectReturnSchema
- client.projects.list(\*\*params) -> ProjectListResponse
- client.projects.delete(project_id) -> None
+- client.projects.create_from_template(\*\*params) -> ProjectReturnSchema
- client.projects.detect(project_id, \*\*params) -> ProjectDetectResponse
- client.projects.export(project_id) -> object
- client.projects.invite_sme(project_id, \*\*params) -> ProjectInviteSmeResponse
diff --git a/src/codex/resources/projects/projects.py b/src/codex/resources/projects/projects.py
index e94a6d3..8aa1da7 100644
--- a/src/codex/resources/projects/projects.py
+++ b/src/codex/resources/projects/projects.py
@@ -23,6 +23,7 @@
project_validate_params,
project_invite_sme_params,
project_retrieve_analytics_params,
+ project_create_from_template_params,
)
from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, SequenceNotStr, omit, not_given
from ..._utils import maybe_transform, strip_not_given, async_maybe_transform
@@ -316,6 +317,55 @@ def delete(
cast_to=NoneType,
)
+ def create_from_template(
+ self,
+ *,
+ organization_id: str,
+ template_project_id: str | Omit = omit,
+ description: Optional[str] | Omit = omit,
+ name: Optional[str] | Omit = omit,
+ # 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,
+ ) -> ProjectReturnSchema:
+ """
+ Create a new project from a template 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
+ """
+ return self._post(
+ "/api/projects/create-from-template",
+ body=maybe_transform(
+ {
+ "organization_id": organization_id,
+ "description": description,
+ "name": name,
+ },
+ project_create_from_template_params.ProjectCreateFromTemplateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {"template_project_id": template_project_id},
+ project_create_from_template_params.ProjectCreateFromTemplateParams,
+ ),
+ ),
+ cast_to=ProjectReturnSchema,
+ )
+
def detect(
self,
project_id: str,
@@ -1089,6 +1139,55 @@ async def delete(
cast_to=NoneType,
)
+ async def create_from_template(
+ self,
+ *,
+ organization_id: str,
+ template_project_id: str | Omit = omit,
+ description: Optional[str] | Omit = omit,
+ name: Optional[str] | Omit = omit,
+ # 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,
+ ) -> ProjectReturnSchema:
+ """
+ Create a new project from a template 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
+ """
+ return await self._post(
+ "/api/projects/create-from-template",
+ body=await async_maybe_transform(
+ {
+ "organization_id": organization_id,
+ "description": description,
+ "name": name,
+ },
+ project_create_from_template_params.ProjectCreateFromTemplateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {"template_project_id": template_project_id},
+ project_create_from_template_params.ProjectCreateFromTemplateParams,
+ ),
+ ),
+ cast_to=ProjectReturnSchema,
+ )
+
async def detect(
self,
project_id: str,
@@ -1635,6 +1734,9 @@ def __init__(self, projects: ProjectsResource) -> None:
self.delete = to_raw_response_wrapper(
projects.delete,
)
+ self.create_from_template = to_raw_response_wrapper(
+ projects.create_from_template,
+ )
self.detect = to_raw_response_wrapper(
projects.detect,
)
@@ -1687,6 +1789,9 @@ def __init__(self, projects: AsyncProjectsResource) -> None:
self.delete = async_to_raw_response_wrapper(
projects.delete,
)
+ self.create_from_template = async_to_raw_response_wrapper(
+ projects.create_from_template,
+ )
self.detect = async_to_raw_response_wrapper(
projects.detect,
)
@@ -1739,6 +1844,9 @@ def __init__(self, projects: ProjectsResource) -> None:
self.delete = to_streamed_response_wrapper(
projects.delete,
)
+ self.create_from_template = to_streamed_response_wrapper(
+ projects.create_from_template,
+ )
self.detect = to_streamed_response_wrapper(
projects.detect,
)
@@ -1791,6 +1899,9 @@ def __init__(self, projects: AsyncProjectsResource) -> None:
self.delete = async_to_streamed_response_wrapper(
projects.delete,
)
+ self.create_from_template = async_to_streamed_response_wrapper(
+ projects.create_from_template,
+ )
self.detect = async_to_streamed_response_wrapper(
projects.detect,
)
diff --git a/src/codex/types/__init__.py b/src/codex/types/__init__.py
index ca9129a..d1e2030 100644
--- a/src/codex/types/__init__.py
+++ b/src/codex/types/__init__.py
@@ -19,6 +19,7 @@
from .user_activate_account_params import UserActivateAccountParams as UserActivateAccountParams
from .project_retrieve_analytics_params import ProjectRetrieveAnalyticsParams as ProjectRetrieveAnalyticsParams
from .organization_list_members_response import OrganizationListMembersResponse as OrganizationListMembersResponse
+from .project_create_from_template_params import ProjectCreateFromTemplateParams as ProjectCreateFromTemplateParams
from .project_retrieve_analytics_response import ProjectRetrieveAnalyticsResponse as ProjectRetrieveAnalyticsResponse
from .organization_retrieve_permissions_response import (
OrganizationRetrievePermissionsResponse as OrganizationRetrievePermissionsResponse,
diff --git a/src/codex/types/project_create_from_template_params.py b/src/codex/types/project_create_from_template_params.py
new file mode 100644
index 0000000..fb1fa58
--- /dev/null
+++ b/src/codex/types/project_create_from_template_params.py
@@ -0,0 +1,18 @@
+# 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__ = ["ProjectCreateFromTemplateParams"]
+
+
+class ProjectCreateFromTemplateParams(TypedDict, total=False):
+ organization_id: Required[str]
+
+ template_project_id: str
+
+ description: Optional[str]
+
+ name: Optional[str]
diff --git a/tests/api_resources/test_projects.py b/tests/api_resources/test_projects.py
index 6b742b4..d83fdd1 100644
--- a/tests/api_resources/test_projects.py
+++ b/tests/api_resources/test_projects.py
@@ -439,6 +439,51 @@ def test_path_params_delete(self, client: Codex) -> None:
"",
)
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_create_from_template(self, client: Codex) -> None:
+ project = client.projects.create_from_template(
+ organization_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(ProjectReturnSchema, project, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_create_from_template_with_all_params(self, client: Codex) -> None:
+ project = client.projects.create_from_template(
+ organization_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ template_project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ description="description",
+ name="name",
+ )
+ assert_matches_type(ProjectReturnSchema, project, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_raw_response_create_from_template(self, client: Codex) -> None:
+ response = client.projects.with_raw_response.create_from_template(
+ organization_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ project = response.parse()
+ assert_matches_type(ProjectReturnSchema, project, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_streaming_response_create_from_template(self, client: Codex) -> None:
+ with client.projects.with_streaming_response.create_from_template(
+ organization_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ project = response.parse()
+ assert_matches_type(ProjectReturnSchema, project, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_detect(self, client: Codex) -> None:
@@ -1329,6 +1374,51 @@ async def test_path_params_delete(self, async_client: AsyncCodex) -> None:
"",
)
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_create_from_template(self, async_client: AsyncCodex) -> None:
+ project = await async_client.projects.create_from_template(
+ organization_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(ProjectReturnSchema, project, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_create_from_template_with_all_params(self, async_client: AsyncCodex) -> None:
+ project = await async_client.projects.create_from_template(
+ organization_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ template_project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ description="description",
+ name="name",
+ )
+ assert_matches_type(ProjectReturnSchema, project, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_raw_response_create_from_template(self, async_client: AsyncCodex) -> None:
+ response = await async_client.projects.with_raw_response.create_from_template(
+ organization_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ project = await response.parse()
+ assert_matches_type(ProjectReturnSchema, project, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_streaming_response_create_from_template(self, async_client: AsyncCodex) -> None:
+ async with async_client.projects.with_streaming_response.create_from_template(
+ organization_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ project = await response.parse()
+ assert_matches_type(ProjectReturnSchema, project, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_detect(self, async_client: AsyncCodex) -> None:
From f292f438e9fe8fea75a6005b4be482d2b8dba7db Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 28 Oct 2025 17:21:18 +0000
Subject: [PATCH 9/9] release: 0.1.0-alpha.31
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 18 ++++++++++++++++++
pyproject.toml | 2 +-
src/codex/_version.py | 2 +-
4 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 52b3e83..a899ac7 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.1.0-alpha.30"
+ ".": "0.1.0-alpha.31"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9cab6a3..35619b0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,23 @@
# Changelog
+## 0.1.0-alpha.31 (2025-10-28)
+
+Full Changelog: [v0.1.0-alpha.30...v0.1.0-alpha.31](https://github.com/cleanlab/codex-python/compare/v0.1.0-alpha.30...v0.1.0-alpha.31)
+
+### Features
+
+* **api:** add create from template ([bb733b1](https://github.com/cleanlab/codex-python/commit/bb733b1122b9e52160acb3e3b92b00bf941efce5))
+* **api:** api update ([1481cd8](https://github.com/cleanlab/codex-python/commit/1481cd895f093e9f044e438b7c26fc52f73ee791))
+* **api:** api update ([5468580](https://github.com/cleanlab/codex-python/commit/546858021affa494867222bf7e87fb55c867df41))
+* **api:** api update ([766e331](https://github.com/cleanlab/codex-python/commit/766e3314ad8a72522fa29804b3edc328bab3b4af))
+* **api:** api update ([377dc6b](https://github.com/cleanlab/codex-python/commit/377dc6b4dad3ba898b9fda4fe305d4c25b1ee781))
+* **api:** api update ([321392c](https://github.com/cleanlab/codex-python/commit/321392cfd9ac98fe1ad0b06d21f26441e70c90fc))
+
+
+### Chores
+
+* bump `httpx-aiohttp` version to 0.1.9 ([666f855](https://github.com/cleanlab/codex-python/commit/666f855d5532589f5ffbe0b53a5de65355ec33aa))
+
## 0.1.0-alpha.30 (2025-10-14)
Full Changelog: [v0.1.0-alpha.29...v0.1.0-alpha.30](https://github.com/cleanlab/codex-python/compare/v0.1.0-alpha.29...v0.1.0-alpha.30)
diff --git a/pyproject.toml b/pyproject.toml
index 39ee576..83b0c50 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "codex-sdk"
-version = "0.1.0-alpha.30"
+version = "0.1.0-alpha.31"
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 a008ac3..f48cd03 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.30" # x-release-please-version
+__version__ = "0.1.0-alpha.31" # x-release-please-version