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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.1.0-alpha.29"
".": "0.1.0-alpha.30"
}
2 changes: 1 addition & 1 deletion .stats.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
configured_endpoints: 55
openapi_spec_hash: b54b36ebcaf88c1ddb6d51d24da75420
openapi_spec_hash: c894ce3fb9db92c69816f06896e30067
config_hash: 48c3812186c899cdef23cc8de76bd2aa
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Changelog

## 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)

### Features

* **api:** api update ([5116aea](https://github.com/cleanlab/codex-python/commit/5116aea9d162458af9e46e3ace3d0d6c58d5ae2d))
* **api:** api update ([f62cb7c](https://github.com/cleanlab/codex-python/commit/f62cb7c8826d73bac8bbb047093bdaa41749e8da))
* **api:** api update ([cb2c6ed](https://github.com/cleanlab/codex-python/commit/cb2c6ed08eb4286ec580cc0e48c7954657d48df1))
* **api:** api update ([c515d78](https://github.com/cleanlab/codex-python/commit/c515d7888f17019a2307e47520a39790cd9d0209))


### Chores

* **internal:** detect missing future annotations with ruff ([8e2cc28](https://github.com/cleanlab/codex-python/commit/8e2cc28bac8208d5b0eaa39fcc03248188af076a))

## 0.1.0-alpha.29 (2025-10-06)

Full Changelog: [v0.1.0-alpha.28...v0.1.0-alpha.29](https://github.com/cleanlab/codex-python/compare/v0.1.0-alpha.28...v0.1.0-alpha.29)
Expand Down
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "codex-sdk"
version = "0.1.0-alpha.29"
version = "0.1.0-alpha.30"
description = "Internal SDK used within cleanlab-codex package. Refer to https://pypi.org/project/cleanlab-codex/ instead."
dynamic = ["readme"]
license = "MIT"
Expand Down Expand Up @@ -224,6 +224,8 @@ select = [
"B",
# remove unused imports
"F401",
# check for missing future annotations
"FA102",
# bare except statements
"E722",
# unused arguments
Expand All @@ -246,6 +248,8 @@ unfixable = [
"T203",
]

extend-safe-fixes = ["FA102"]

[tool.ruff.lint.flake8-tidy-imports.banned-api]
"functools.lru_cache".msg = "This function does not retain type information for the wrapped function's arguments; The `lru_cache` function from `_utils` should be used instead"

Expand Down
2 changes: 1 addition & 1 deletion src/codex/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

__title__ = "codex"
__version__ = "0.1.0-alpha.29" # x-release-please-version
__version__ = "0.1.0-alpha.30" # x-release-please-version
92 changes: 82 additions & 10 deletions src/codex/resources/projects/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -564,8 +564,9 @@ def retrieve_analytics(
self,
project_id: str,
*,
end: int | Omit = omit,
start: int | Omit = omit,
end: Optional[int] | Omit = omit,
metadata_filters: Optional[str] | Omit = omit,
start: Optional[int] | 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,
Expand All @@ -574,12 +575,46 @@ def retrieve_analytics(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ProjectRetrieveAnalyticsResponse:
"""
Get Project Analytics Route
Retrieve analytics data for a project including queries, bad responses, and
answers published.

**Metadata Filtering:**
- Filter by custom metadata fields using key-value pairs
- Supports single values: `{"department": "Engineering"}`
- Supports multiple values: `{"priority": ["high", "medium"]}`
- Supports null/missing values: `{"department": []}` or `{"department": [null]}`

**Available Metadata Fields:**
- Only metadata keys that exist on query logs are returned in `metadata_fields`
- Fields with ≤12 unique values show as "select" type with checkbox options
- Fields with >12 unique values show as "input" type for text search
- Fields with no data are excluded from the response entirely

**Null Value Behavior:**
- Empty arrays `[]` are automatically converted to `[null]` to filter for records where the metadata field is missing or null
- Use `[null]` explicitly to filter for records where the field is missing or null
- Use `["value1", null, "value2"]` to include both specific values and null values
- Records match if the metadata field is null, missing from custom_metadata, or custom_metadata itself is null

**Date Filtering:**
- Provide `start` only: filter logs created at or after this timestamp
- Provide `end` only: filter logs created at or before this timestamp
- Provide both: filter logs created within the time range
- Provide neither: include all logs regardless of creation time

Args:
end: End timestamp in seconds since epoch
end: Filter logs created at or before this timestamp (epoch seconds). Can be used
alone for upper-bound filtering.

start: Start timestamp in seconds since epoch
metadata_filters:
Metadata filters as JSON string. Examples:
- Single value: '{"department": "Engineering"}'
- Multiple values: '{"priority": ["high", "medium"]}'
- Null/missing values: '{"department": []}' or '{"department": [null]}'
- Mixed values: '{"status": ["active", null, "pending"]}'

start: Filter logs created at or after this timestamp (epoch seconds). Can be used
alone for lower-bound filtering.

extra_headers: Send extra headers

Expand All @@ -601,6 +636,7 @@ def retrieve_analytics(
query=maybe_transform(
{
"end": end,
"metadata_filters": metadata_filters,
"start": start,
},
project_retrieve_analytics_params.ProjectRetrieveAnalyticsParams,
Expand Down Expand Up @@ -1301,8 +1337,9 @@ async def retrieve_analytics(
self,
project_id: str,
*,
end: int | Omit = omit,
start: int | Omit = omit,
end: Optional[int] | Omit = omit,
metadata_filters: Optional[str] | Omit = omit,
start: Optional[int] | 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,
Expand All @@ -1311,12 +1348,46 @@ async def retrieve_analytics(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ProjectRetrieveAnalyticsResponse:
"""
Get Project Analytics Route
Retrieve analytics data for a project including queries, bad responses, and
answers published.

**Metadata Filtering:**
- Filter by custom metadata fields using key-value pairs
- Supports single values: `{"department": "Engineering"}`
- Supports multiple values: `{"priority": ["high", "medium"]}`
- Supports null/missing values: `{"department": []}` or `{"department": [null]}`

**Available Metadata Fields:**
- Only metadata keys that exist on query logs are returned in `metadata_fields`
- Fields with ≤12 unique values show as "select" type with checkbox options
- Fields with >12 unique values show as "input" type for text search
- Fields with no data are excluded from the response entirely

**Null Value Behavior:**
- Empty arrays `[]` are automatically converted to `[null]` to filter for records where the metadata field is missing or null
- Use `[null]` explicitly to filter for records where the field is missing or null
- Use `["value1", null, "value2"]` to include both specific values and null values
- Records match if the metadata field is null, missing from custom_metadata, or custom_metadata itself is null

**Date Filtering:**
- Provide `start` only: filter logs created at or after this timestamp
- Provide `end` only: filter logs created at or before this timestamp
- Provide both: filter logs created within the time range
- Provide neither: include all logs regardless of creation time

Args:
end: End timestamp in seconds since epoch
end: Filter logs created at or before this timestamp (epoch seconds). Can be used
alone for upper-bound filtering.

metadata_filters:
Metadata filters as JSON string. Examples:
- Single value: '{"department": "Engineering"}'
- Multiple values: '{"priority": ["high", "medium"]}'
- Null/missing values: '{"department": []}' or '{"department": [null]}'
- Mixed values: '{"status": ["active", null, "pending"]}'

start: Start timestamp in seconds since epoch
start: Filter logs created at or after this timestamp (epoch seconds). Can be used
alone for lower-bound filtering.

extra_headers: Send extra headers

Expand All @@ -1338,6 +1409,7 @@ async def retrieve_analytics(
query=await async_maybe_transform(
{
"end": end,
"metadata_filters": metadata_filters,
"start": start,
},
project_retrieve_analytics_params.ProjectRetrieveAnalyticsParams,
Expand Down
9 changes: 5 additions & 4 deletions src/codex/types/project_detect_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ class EvalScores(BaseModel):

triggered_guardrail: bool

failed: Optional[bool] = None

log: Optional[object] = None


Expand All @@ -56,8 +54,11 @@ class ProjectDetectResponse(BaseModel):
Codex Project, or None otherwise.
"""

expert_review_guardrail_explanation: Optional[str] = None
"""Explanation from a similar bad query log that caused this to be guardrailed"""
expert_guardrail_override_explanation: Optional[str] = None
"""
Explanation of why the response was either guardrailed or not guardrailed by
expert review. Expert review will override the original guardrail decision.
"""

should_guardrail: bool
"""
Expand Down
6 changes: 6 additions & 0 deletions src/codex/types/project_list_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ class ProjectConfigEvalConfigCustomEvalsEvals(BaseModel):
how
"""

display_name: str
"""Human-friendly name for display.

For default evals, prefer standardized labels; otherwise use configured name.
"""

eval_key: str
"""
Unique key for eval metric - currently maps to the TrustworthyRAG name property
Expand Down
24 changes: 20 additions & 4 deletions src/codex/types/project_retrieve_analytics_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,30 @@

from __future__ import annotations

from typing import Optional
from typing_extensions import TypedDict

__all__ = ["ProjectRetrieveAnalyticsParams"]


class ProjectRetrieveAnalyticsParams(TypedDict, total=False):
end: int
"""End timestamp in seconds since epoch"""
end: Optional[int]
"""Filter logs created at or before this timestamp (epoch seconds).

start: int
"""Start timestamp in seconds since epoch"""
Can be used alone for upper-bound filtering.
"""

metadata_filters: Optional[str]
"""Metadata filters as JSON string.

Examples: - Single value: '{"department": "Engineering"}' - Multiple values:
'{"priority": ["high", "medium"]}' - Null/missing values: '{"department": []}'
or '{"department": [null]}' - Mixed values: '{"status": ["active", null,
"pending"]}'
"""

start: Optional[int]
"""Filter logs created at or after this timestamp (epoch seconds).

Can be used alone for lower-bound filtering.
"""
22 changes: 21 additions & 1 deletion src/codex/types/project_retrieve_analytics_response.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

from typing import Dict, List
from typing import Dict, List, Optional
from typing_extensions import Literal

from .._models import BaseModel

Expand All @@ -11,6 +12,7 @@
"BadResponses",
"BadResponsesResponsesByType",
"Queries",
"MetadataField",
]


Expand Down Expand Up @@ -44,9 +46,27 @@ class Queries(BaseModel):
total: int


class MetadataField(BaseModel):
field_type: Literal["select", "input"]
"""Field type: 'select' for checkbox selection, 'input' for text input"""

key: str
"""Metadata field key"""

values: Optional[List[Optional[str]]] = None
"""Possible values for this metadata field (None if more than 12 values).

Array elements may include null to represent logs where the metadata key is
missing or null.
"""


class ProjectRetrieveAnalyticsResponse(BaseModel):
answers_published: AnswersPublished

bad_responses: BadResponses

queries: Queries

metadata_fields: Optional[List[MetadataField]] = None
"""Available metadata fields for filtering"""
6 changes: 6 additions & 0 deletions src/codex/types/project_retrieve_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ class ConfigEvalConfigCustomEvalsEvals(BaseModel):
how
"""

display_name: str
"""Human-friendly name for display.

For default evals, prefer standardized labels; otherwise use configured name.
"""

eval_key: str
"""
Unique key for eval metric - currently maps to the TrustworthyRAG name property
Expand Down
6 changes: 6 additions & 0 deletions src/codex/types/project_return_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ class ConfigEvalConfigCustomEvalsEvals(BaseModel):
how
"""

display_name: str
"""Human-friendly name for display.

For default evals, prefer standardized labels; otherwise use configured name.
"""

eval_key: str
"""
Unique key for eval metric - currently maps to the TrustworthyRAG name property
Expand Down
14 changes: 4 additions & 10 deletions src/codex/types/project_validate_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ class EvalScores(BaseModel):

triggered_guardrail: bool

failed: Optional[bool] = None

log: Optional[object] = None


Expand All @@ -56,14 +54,10 @@ class ProjectValidateResponse(BaseModel):
Codex Project, or None otherwise.
"""

expert_review_guardrail_explanation: Optional[str] = None
"""Explanation from a similar bad query log that caused this to be guardrailed"""

is_bad_response: bool
"""True if the response is flagged as potentially bad, False otherwise.

When True, a lookup is performed, which logs this query in the project for SMEs
to answer, if it does not already exist.
expert_guardrail_override_explanation: Optional[str] = None
"""
Explanation of why the response was either guardrailed or not guardrailed by
expert review. Expert review will override the original guardrail decision.
"""

log_id: str
Expand Down
6 changes: 6 additions & 0 deletions src/codex/types/projects/eval_list_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ class Eval(BaseModel):
how
"""

display_name: str
"""Human-friendly name for display.

For default evals, prefer standardized labels; otherwise use configured name.
"""

eval_key: str
"""
Unique key for eval metric - currently maps to the TrustworthyRAG name property
Expand Down
Loading