docent-python 0.1.0a1__tar.gz → 0.1.0a2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of docent-python might be problematic. Click here for more details.

Files changed (25) hide show
  1. {docent_python-0.1.0a1 → docent_python-0.1.0a2}/LICENSE.md +1 -1
  2. {docent_python-0.1.0a1 → docent_python-0.1.0a2}/PKG-INFO +2 -4
  3. docent_python-0.1.0a2/README.md +18 -0
  4. {docent_python-0.1.0a1 → docent_python-0.1.0a2}/docent/data_models/__init__.py +4 -4
  5. {docent_python-0.1.0a1 → docent_python-0.1.0a2}/docent/sdk/client.py +6 -2
  6. {docent_python-0.1.0a1 → docent_python-0.1.0a2}/pyproject.toml +2 -4
  7. {docent_python-0.1.0a1 → docent_python-0.1.0a2}/uv.lock +2 -102
  8. docent_python-0.1.0a1/docent/data_models/filters.py +0 -205
  9. {docent_python-0.1.0a1 → docent_python-0.1.0a2}/.gitignore +0 -0
  10. {docent_python-0.1.0a1 → docent_python-0.1.0a2}/docent/__init__.py +0 -0
  11. {docent_python-0.1.0a1 → docent_python-0.1.0a2}/docent/_log_util/__init__.py +0 -0
  12. {docent_python-0.1.0a1 → docent_python-0.1.0a2}/docent/_log_util/logger.py +0 -0
  13. {docent_python-0.1.0a1 → docent_python-0.1.0a2}/docent/data_models/_tiktoken_util.py +0 -0
  14. {docent_python-0.1.0a1 → docent_python-0.1.0a2}/docent/data_models/agent_run.py +0 -0
  15. {docent_python-0.1.0a1 → docent_python-0.1.0a2}/docent/data_models/chat/__init__.py +0 -0
  16. {docent_python-0.1.0a1 → docent_python-0.1.0a2}/docent/data_models/chat/content.py +0 -0
  17. {docent_python-0.1.0a1 → docent_python-0.1.0a2}/docent/data_models/chat/message.py +0 -0
  18. {docent_python-0.1.0a1 → docent_python-0.1.0a2}/docent/data_models/chat/tool.py +0 -0
  19. {docent_python-0.1.0a1 → docent_python-0.1.0a2}/docent/data_models/citation.py +0 -0
  20. {docent_python-0.1.0a1 → docent_python-0.1.0a2}/docent/data_models/metadata.py +0 -0
  21. {docent_python-0.1.0a1 → docent_python-0.1.0a2}/docent/data_models/regex.py +0 -0
  22. {docent_python-0.1.0a1 → docent_python-0.1.0a2}/docent/data_models/shared_types.py +0 -0
  23. {docent_python-0.1.0a1 → docent_python-0.1.0a2}/docent/data_models/transcript.py +0 -0
  24. {docent_python-0.1.0a1 → docent_python-0.1.0a2}/docent/py.typed +0 -0
  25. {docent_python-0.1.0a1 → docent_python-0.1.0a2}/docent/sdk/__init__.py +0 -0
@@ -4,4 +4,4 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
4
 
5
5
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
6
 
7
- THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,16 +1,14 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: docent-python
3
- Version: 0.1.0a1
3
+ Version: 0.1.0a2
4
4
  Summary: Docent SDK
5
5
  Project-URL: Homepage, https://github.com/TransluceAI/docent
6
6
  Project-URL: Issues, https://github.com/TransluceAI/docent/issues
7
7
  Project-URL: Docs, https://transluce-docent.readthedocs-hosted.com/en/latest
8
- Author-email: Transluce AI <info@transluce.org>
8
+ Author-email: Transluce <info@transluce.org>
9
9
  License-Expression: MIT
10
10
  License-File: LICENSE.md
11
11
  Requires-Python: >=3.11
12
- Requires-Dist: logging>=0.4.9.6
13
12
  Requires-Dist: pydantic>=2.11.7
14
13
  Requires-Dist: pyyaml>=6.0.2
15
- Requires-Dist: sqlalchemy>=2.0.41
16
14
  Requires-Dist: tiktoken>=0.7.0
@@ -0,0 +1,18 @@
1
+ # Docent Python SDK
2
+
3
+ The official Python SDK for [Docent](https://github.com/TransluceAI/docent) - a platform for analyzing and visualizing AI agent execution traces.
4
+
5
+ ## Overview
6
+
7
+ Docent helps you understand AI agent behavior by providing tools to collect, analyze, and visualize agent execution data. This SDK allows you to programmatically interact with the Docent platform to:
8
+
9
+ - Create and manage FrameGrids (collections of agent runs)
10
+ - Upload agent execution traces and transcripts
11
+ - Define custom dimensions and filters
12
+ - Perform searches and analyses on agent behavior
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ pip install docent-python
18
+ ```
@@ -1,14 +1,14 @@
1
1
  from docent.data_models.agent_run import AgentRun
2
2
  from docent.data_models.citation import Citation
3
- from docent.data_models.filters import (
3
+ from docent.data_models.metadata import BaseAgentRunMetadata, BaseMetadata, FrameDimension
4
+ from docent.data_models.regex import RegexSnippet
5
+ from docent.data_models.transcript import Transcript
6
+ from docent_core._db_service.filters import (
4
7
  AgentRunIdFilter,
5
8
  BaseFrameFilter,
6
9
  ComplexFilter,
7
10
  SearchResultPredicateFilter,
8
11
  )
9
- from docent.data_models.metadata import BaseAgentRunMetadata, BaseMetadata, FrameDimension
10
- from docent.data_models.regex import RegexSnippet
11
- from docent.data_models.transcript import Transcript
12
12
 
13
13
  __all__ = [
14
14
  "AgentRun",
@@ -5,7 +5,7 @@ import requests
5
5
 
6
6
  from docent._log_util.logger import get_logger
7
7
  from docent.data_models.agent_run import AgentRun
8
- from docent.data_models.filters import FrameFilter
8
+ from docent_core._db_service.filters import FrameFilter
9
9
 
10
10
  logger = get_logger(__name__)
11
11
 
@@ -24,7 +24,11 @@ class Docent:
24
24
  """
25
25
 
26
26
  def __init__(
27
- self, server_url: str, web_url: str, email: str | None = None, password: str | None = None
27
+ self,
28
+ server_url: str = "https://aws-docent-backend.transluce.org",
29
+ web_url: str = "https://aws-docent.transluce.org",
30
+ email: str | None = None,
31
+ password: str | None = None,
28
32
  ):
29
33
  self._server_url = server_url.rstrip("/") + "/rest"
30
34
  self._web_url = web_url.rstrip("/")
@@ -1,19 +1,17 @@
1
1
  [project]
2
2
  name = "docent-python"
3
3
  description = "Docent SDK"
4
- version = "0.1.0-alpha.1"
4
+ version = "0.1.0-alpha.2"
5
5
  authors = [
6
- { name="Transluce AI", email="info@transluce.org" },
6
+ { name="Transluce", email="info@transluce.org" },
7
7
  ]
8
8
  license = "MIT"
9
9
  license-files = ["LICENSE.md"]
10
10
 
11
11
  requires-python = ">=3.11"
12
12
  dependencies = [
13
- "logging>=0.4.9.6",
14
13
  "pydantic>=2.11.7",
15
14
  "pyyaml>=6.0.2",
16
- "sqlalchemy>=2.0.41",
17
15
  "tiktoken>=0.7.0",
18
16
  ]
19
17
 
@@ -69,70 +69,22 @@ wheels = [
69
69
  ]
70
70
 
71
71
  [[package]]
72
- name = "docent-sdk"
73
- version = "0.0.1"
72
+ name = "docent-python"
73
+ version = "0.1.0a1"
74
74
  source = { editable = "." }
75
75
  dependencies = [
76
- { name = "logging" },
77
76
  { name = "pydantic" },
78
- { name = "python-dotenv" },
79
77
  { name = "pyyaml" },
80
- { name = "sqlalchemy" },
81
78
  { name = "tiktoken" },
82
79
  ]
83
80
 
84
81
  [package.metadata]
85
82
  requires-dist = [
86
- { name = "logging", specifier = ">=0.4.9.6" },
87
83
  { name = "pydantic", specifier = ">=2.11.7" },
88
- { name = "python-dotenv", specifier = ">=1.1.1" },
89
84
  { name = "pyyaml", specifier = ">=6.0.2" },
90
- { name = "sqlalchemy", specifier = ">=2.0.41" },
91
85
  { name = "tiktoken", specifier = ">=0.7.0" },
92
86
  ]
93
87
 
94
- [[package]]
95
- name = "greenlet"
96
- version = "3.2.3"
97
- source = { registry = "https://pypi.org/simple" }
98
- sdist = { url = "https://files.pythonhosted.org/packages/c9/92/bb85bd6e80148a4d2e0c59f7c0c2891029f8fd510183afc7d8d2feeed9b6/greenlet-3.2.3.tar.gz", hash = "sha256:8b0dd8ae4c0d6f5e54ee55ba935eeb3d735a9b58a8a1e5b5cbab64e01a39f365", size = 185752, upload-time = "2025-06-05T16:16:09.955Z" }
99
- wheels = [
100
- { url = "https://files.pythonhosted.org/packages/fc/2e/d4fcb2978f826358b673f779f78fa8a32ee37df11920dc2bb5589cbeecef/greenlet-3.2.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:784ae58bba89fa1fa5733d170d42486580cab9decda3484779f4759345b29822", size = 270219, upload-time = "2025-06-05T16:10:10.414Z" },
101
- { url = "https://files.pythonhosted.org/packages/16/24/929f853e0202130e4fe163bc1d05a671ce8dcd604f790e14896adac43a52/greenlet-3.2.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0921ac4ea42a5315d3446120ad48f90c3a6b9bb93dd9b3cf4e4d84a66e42de83", size = 630383, upload-time = "2025-06-05T16:38:51.785Z" },
102
- { url = "https://files.pythonhosted.org/packages/d1/b2/0320715eb61ae70c25ceca2f1d5ae620477d246692d9cc284c13242ec31c/greenlet-3.2.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:d2971d93bb99e05f8c2c0c2f4aa9484a18d98c4c3bd3c62b65b7e6ae33dfcfaf", size = 642422, upload-time = "2025-06-05T16:41:35.259Z" },
103
- { url = "https://files.pythonhosted.org/packages/bd/49/445fd1a210f4747fedf77615d941444349c6a3a4a1135bba9701337cd966/greenlet-3.2.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c667c0bf9d406b77a15c924ef3285e1e05250948001220368e039b6aa5b5034b", size = 638375, upload-time = "2025-06-05T16:48:18.235Z" },
104
- { url = "https://files.pythonhosted.org/packages/7e/c8/ca19760cf6eae75fa8dc32b487e963d863b3ee04a7637da77b616703bc37/greenlet-3.2.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:592c12fb1165be74592f5de0d70f82bc5ba552ac44800d632214b76089945147", size = 637627, upload-time = "2025-06-05T16:13:02.858Z" },
105
- { url = "https://files.pythonhosted.org/packages/65/89/77acf9e3da38e9bcfca881e43b02ed467c1dedc387021fc4d9bd9928afb8/greenlet-3.2.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:29e184536ba333003540790ba29829ac14bb645514fbd7e32af331e8202a62a5", size = 585502, upload-time = "2025-06-05T16:12:49.642Z" },
106
- { url = "https://files.pythonhosted.org/packages/97/c6/ae244d7c95b23b7130136e07a9cc5aadd60d59b5951180dc7dc7e8edaba7/greenlet-3.2.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:93c0bb79844a367782ec4f429d07589417052e621aa39a5ac1fb99c5aa308edc", size = 1114498, upload-time = "2025-06-05T16:36:46.598Z" },
107
- { url = "https://files.pythonhosted.org/packages/89/5f/b16dec0cbfd3070658e0d744487919740c6d45eb90946f6787689a7efbce/greenlet-3.2.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:751261fc5ad7b6705f5f76726567375bb2104a059454e0226e1eef6c756748ba", size = 1139977, upload-time = "2025-06-05T16:12:38.262Z" },
108
- { url = "https://files.pythonhosted.org/packages/66/77/d48fb441b5a71125bcac042fc5b1494c806ccb9a1432ecaa421e72157f77/greenlet-3.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:83a8761c75312361aa2b5b903b79da97f13f556164a7dd2d5448655425bd4c34", size = 297017, upload-time = "2025-06-05T16:25:05.225Z" },
109
- { url = "https://files.pythonhosted.org/packages/f3/94/ad0d435f7c48debe960c53b8f60fb41c2026b1d0fa4a99a1cb17c3461e09/greenlet-3.2.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:25ad29caed5783d4bd7a85c9251c651696164622494c00802a139c00d639242d", size = 271992, upload-time = "2025-06-05T16:11:23.467Z" },
110
- { url = "https://files.pythonhosted.org/packages/93/5d/7c27cf4d003d6e77749d299c7c8f5fd50b4f251647b5c2e97e1f20da0ab5/greenlet-3.2.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:88cd97bf37fe24a6710ec6a3a7799f3f81d9cd33317dcf565ff9950c83f55e0b", size = 638820, upload-time = "2025-06-05T16:38:52.882Z" },
111
- { url = "https://files.pythonhosted.org/packages/c6/7e/807e1e9be07a125bb4c169144937910bf59b9d2f6d931578e57f0bce0ae2/greenlet-3.2.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:baeedccca94880d2f5666b4fa16fc20ef50ba1ee353ee2d7092b383a243b0b0d", size = 653046, upload-time = "2025-06-05T16:41:36.343Z" },
112
- { url = "https://files.pythonhosted.org/packages/9d/ab/158c1a4ea1068bdbc78dba5a3de57e4c7aeb4e7fa034320ea94c688bfb61/greenlet-3.2.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:be52af4b6292baecfa0f397f3edb3c6092ce071b499dd6fe292c9ac9f2c8f264", size = 647701, upload-time = "2025-06-05T16:48:19.604Z" },
113
- { url = "https://files.pythonhosted.org/packages/cc/0d/93729068259b550d6a0288da4ff72b86ed05626eaf1eb7c0d3466a2571de/greenlet-3.2.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0cc73378150b8b78b0c9fe2ce56e166695e67478550769536a6742dca3651688", size = 649747, upload-time = "2025-06-05T16:13:04.628Z" },
114
- { url = "https://files.pythonhosted.org/packages/f6/f6/c82ac1851c60851302d8581680573245c8fc300253fc1ff741ae74a6c24d/greenlet-3.2.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:706d016a03e78df129f68c4c9b4c4f963f7d73534e48a24f5f5a7101ed13dbbb", size = 605461, upload-time = "2025-06-05T16:12:50.792Z" },
115
- { url = "https://files.pythonhosted.org/packages/98/82/d022cf25ca39cf1200650fc58c52af32c90f80479c25d1cbf57980ec3065/greenlet-3.2.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:419e60f80709510c343c57b4bb5a339d8767bf9aef9b8ce43f4f143240f88b7c", size = 1121190, upload-time = "2025-06-05T16:36:48.59Z" },
116
- { url = "https://files.pythonhosted.org/packages/f5/e1/25297f70717abe8104c20ecf7af0a5b82d2f5a980eb1ac79f65654799f9f/greenlet-3.2.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:93d48533fade144203816783373f27a97e4193177ebaaf0fc396db19e5d61163", size = 1149055, upload-time = "2025-06-05T16:12:40.457Z" },
117
- { url = "https://files.pythonhosted.org/packages/1f/8f/8f9e56c5e82eb2c26e8cde787962e66494312dc8cb261c460e1f3a9c88bc/greenlet-3.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:7454d37c740bb27bdeddfc3f358f26956a07d5220818ceb467a483197d84f849", size = 297817, upload-time = "2025-06-05T16:29:49.244Z" },
118
- { url = "https://files.pythonhosted.org/packages/b1/cf/f5c0b23309070ae93de75c90d29300751a5aacefc0a3ed1b1d8edb28f08b/greenlet-3.2.3-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:500b8689aa9dd1ab26872a34084503aeddefcb438e2e7317b89b11eaea1901ad", size = 270732, upload-time = "2025-06-05T16:10:08.26Z" },
119
- { url = "https://files.pythonhosted.org/packages/48/ae/91a957ba60482d3fecf9be49bc3948f341d706b52ddb9d83a70d42abd498/greenlet-3.2.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a07d3472c2a93117af3b0136f246b2833fdc0b542d4a9799ae5f41c28323faef", size = 639033, upload-time = "2025-06-05T16:38:53.983Z" },
120
- { url = "https://files.pythonhosted.org/packages/6f/df/20ffa66dd5a7a7beffa6451bdb7400d66251374ab40b99981478c69a67a8/greenlet-3.2.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:8704b3768d2f51150626962f4b9a9e4a17d2e37c8a8d9867bbd9fa4eb938d3b3", size = 652999, upload-time = "2025-06-05T16:41:37.89Z" },
121
- { url = "https://files.pythonhosted.org/packages/51/b4/ebb2c8cb41e521f1d72bf0465f2f9a2fd803f674a88db228887e6847077e/greenlet-3.2.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:5035d77a27b7c62db6cf41cf786cfe2242644a7a337a0e155c80960598baab95", size = 647368, upload-time = "2025-06-05T16:48:21.467Z" },
122
- { url = "https://files.pythonhosted.org/packages/8e/6a/1e1b5aa10dced4ae876a322155705257748108b7fd2e4fae3f2a091fe81a/greenlet-3.2.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2d8aa5423cd4a396792f6d4580f88bdc6efcb9205891c9d40d20f6e670992efb", size = 650037, upload-time = "2025-06-05T16:13:06.402Z" },
123
- { url = "https://files.pythonhosted.org/packages/26/f2/ad51331a157c7015c675702e2d5230c243695c788f8f75feba1af32b3617/greenlet-3.2.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2c724620a101f8170065d7dded3f962a2aea7a7dae133a009cada42847e04a7b", size = 608402, upload-time = "2025-06-05T16:12:51.91Z" },
124
- { url = "https://files.pythonhosted.org/packages/26/bc/862bd2083e6b3aff23300900a956f4ea9a4059de337f5c8734346b9b34fc/greenlet-3.2.3-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:873abe55f134c48e1f2a6f53f7d1419192a3d1a4e873bace00499a4e45ea6af0", size = 1119577, upload-time = "2025-06-05T16:36:49.787Z" },
125
- { url = "https://files.pythonhosted.org/packages/86/94/1fc0cc068cfde885170e01de40a619b00eaa8f2916bf3541744730ffb4c3/greenlet-3.2.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:024571bbce5f2c1cfff08bf3fbaa43bbc7444f580ae13b0099e95d0e6e67ed36", size = 1147121, upload-time = "2025-06-05T16:12:42.527Z" },
126
- { url = "https://files.pythonhosted.org/packages/27/1a/199f9587e8cb08a0658f9c30f3799244307614148ffe8b1e3aa22f324dea/greenlet-3.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:5195fb1e75e592dd04ce79881c8a22becdfa3e6f500e7feb059b1e6fdd54d3e3", size = 297603, upload-time = "2025-06-05T16:20:12.651Z" },
127
- { url = "https://files.pythonhosted.org/packages/d8/ca/accd7aa5280eb92b70ed9e8f7fd79dc50a2c21d8c73b9a0856f5b564e222/greenlet-3.2.3-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:3d04332dddb10b4a211b68111dabaee2e1a073663d117dc10247b5b1642bac86", size = 271479, upload-time = "2025-06-05T16:10:47.525Z" },
128
- { url = "https://files.pythonhosted.org/packages/55/71/01ed9895d9eb49223280ecc98a557585edfa56b3d0e965b9fa9f7f06b6d9/greenlet-3.2.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8186162dffde068a465deab08fc72c767196895c39db26ab1c17c0b77a6d8b97", size = 683952, upload-time = "2025-06-05T16:38:55.125Z" },
129
- { url = "https://files.pythonhosted.org/packages/ea/61/638c4bdf460c3c678a0a1ef4c200f347dff80719597e53b5edb2fb27ab54/greenlet-3.2.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f4bfbaa6096b1b7a200024784217defedf46a07c2eee1a498e94a1b5f8ec5728", size = 696917, upload-time = "2025-06-05T16:41:38.959Z" },
130
- { url = "https://files.pythonhosted.org/packages/22/cc/0bd1a7eb759d1f3e3cc2d1bc0f0b487ad3cc9f34d74da4b80f226fde4ec3/greenlet-3.2.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:ed6cfa9200484d234d8394c70f5492f144b20d4533f69262d530a1a082f6ee9a", size = 692443, upload-time = "2025-06-05T16:48:23.113Z" },
131
- { url = "https://files.pythonhosted.org/packages/67/10/b2a4b63d3f08362662e89c103f7fe28894a51ae0bc890fabf37d1d780e52/greenlet-3.2.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:02b0df6f63cd15012bed5401b47829cfd2e97052dc89da3cfaf2c779124eb892", size = 692995, upload-time = "2025-06-05T16:13:07.972Z" },
132
- { url = "https://files.pythonhosted.org/packages/5a/c6/ad82f148a4e3ce9564056453a71529732baf5448ad53fc323e37efe34f66/greenlet-3.2.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:86c2d68e87107c1792e2e8d5399acec2487a4e993ab76c792408e59394d52141", size = 655320, upload-time = "2025-06-05T16:12:53.453Z" },
133
- { url = "https://files.pythonhosted.org/packages/5c/4f/aab73ecaa6b3086a4c89863d94cf26fa84cbff63f52ce9bc4342b3087a06/greenlet-3.2.3-cp314-cp314-win_amd64.whl", hash = "sha256:8c47aae8fbbfcf82cc13327ae802ba13c9c36753b67e760023fd116bc124a62a", size = 301236, upload-time = "2025-06-05T16:15:20.111Z" },
134
- ]
135
-
136
88
  [[package]]
137
89
  name = "idna"
138
90
  version = "3.10"
@@ -142,12 +94,6 @@ wheels = [
142
94
  { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" },
143
95
  ]
144
96
 
145
- [[package]]
146
- name = "logging"
147
- version = "0.4.9.6"
148
- source = { registry = "https://pypi.org/simple" }
149
- sdist = { url = "https://files.pythonhosted.org/packages/93/4b/979db9e44be09f71e85c9c8cfc42f258adfb7d93ce01deed2788b2948919/logging-0.4.9.6.tar.gz", hash = "sha256:26f6b50773f085042d301085bd1bf5d9f3735704db9f37c1ce6d8b85c38f2417", size = 96029, upload-time = "2013-06-04T23:43:22.086Z" }
150
-
151
97
  [[package]]
152
98
  name = "pydantic"
153
99
  version = "2.11.7"
@@ -228,15 +174,6 @@ wheels = [
228
174
  { url = "https://files.pythonhosted.org/packages/32/56/8a7ca5d2cd2cda1d245d34b1c9a942920a718082ae8e54e5f3e5a58b7add/pydantic_core-2.33.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1", size = 2066757, upload-time = "2025-04-23T18:33:30.645Z" },
229
175
  ]
230
176
 
231
- [[package]]
232
- name = "python-dotenv"
233
- version = "1.1.1"
234
- source = { registry = "https://pypi.org/simple" }
235
- sdist = { url = "https://files.pythonhosted.org/packages/f6/b0/4bc07ccd3572a2f9df7e6782f52b0c6c90dcbb803ac4a167702d7d0dfe1e/python_dotenv-1.1.1.tar.gz", hash = "sha256:a8a6399716257f45be6a007360200409fce5cda2661e3dec71d23dc15f6189ab", size = 41978, upload-time = "2025-06-24T04:21:07.341Z" }
236
- wheels = [
237
- { url = "https://files.pythonhosted.org/packages/5f/ed/539768cf28c661b5b068d66d96a2f155c4971a5d55684a514c1a0e0dec2f/python_dotenv-1.1.1-py3-none-any.whl", hash = "sha256:31f23644fe2602f88ff55e1f5c79ba497e01224ee7737937930c448e4d0e24dc", size = 20556, upload-time = "2025-06-24T04:21:06.073Z" },
238
- ]
239
-
240
177
  [[package]]
241
178
  name = "pyyaml"
242
179
  version = "6.0.2"
@@ -340,43 +277,6 @@ wheels = [
340
277
  { url = "https://files.pythonhosted.org/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c", size = 64847, upload-time = "2025-06-09T16:43:05.728Z" },
341
278
  ]
342
279
 
343
- [[package]]
344
- name = "sqlalchemy"
345
- version = "2.0.41"
346
- source = { registry = "https://pypi.org/simple" }
347
- dependencies = [
348
- { name = "greenlet", marker = "(python_full_version < '3.14' and platform_machine == 'AMD64') or (python_full_version < '3.14' and platform_machine == 'WIN32') or (python_full_version < '3.14' and platform_machine == 'aarch64') or (python_full_version < '3.14' and platform_machine == 'amd64') or (python_full_version < '3.14' and platform_machine == 'ppc64le') or (python_full_version < '3.14' and platform_machine == 'win32') or (python_full_version < '3.14' and platform_machine == 'x86_64')" },
349
- { name = "typing-extensions" },
350
- ]
351
- sdist = { url = "https://files.pythonhosted.org/packages/63/66/45b165c595ec89aa7dcc2c1cd222ab269bc753f1fc7a1e68f8481bd957bf/sqlalchemy-2.0.41.tar.gz", hash = "sha256:edba70118c4be3c2b1f90754d308d0b79c6fe2c0fdc52d8ddf603916f83f4db9", size = 9689424, upload-time = "2025-05-14T17:10:32.339Z" }
352
- wheels = [
353
- { url = "https://files.pythonhosted.org/packages/37/4e/b00e3ffae32b74b5180e15d2ab4040531ee1bef4c19755fe7926622dc958/sqlalchemy-2.0.41-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6375cd674fe82d7aa9816d1cb96ec592bac1726c11e0cafbf40eeee9a4516b5f", size = 2121232, upload-time = "2025-05-14T17:48:20.444Z" },
354
- { url = "https://files.pythonhosted.org/packages/ef/30/6547ebb10875302074a37e1970a5dce7985240665778cfdee2323709f749/sqlalchemy-2.0.41-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9f8c9fdd15a55d9465e590a402f42082705d66b05afc3ffd2d2eb3c6ba919560", size = 2110897, upload-time = "2025-05-14T17:48:21.634Z" },
355
- { url = "https://files.pythonhosted.org/packages/9e/21/59df2b41b0f6c62da55cd64798232d7349a9378befa7f1bb18cf1dfd510a/sqlalchemy-2.0.41-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32f9dc8c44acdee06c8fc6440db9eae8b4af8b01e4b1aee7bdd7241c22edff4f", size = 3273313, upload-time = "2025-05-14T17:51:56.205Z" },
356
- { url = "https://files.pythonhosted.org/packages/62/e4/b9a7a0e5c6f79d49bcd6efb6e90d7536dc604dab64582a9dec220dab54b6/sqlalchemy-2.0.41-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90c11ceb9a1f482c752a71f203a81858625d8df5746d787a4786bca4ffdf71c6", size = 3273807, upload-time = "2025-05-14T17:55:26.928Z" },
357
- { url = "https://files.pythonhosted.org/packages/39/d8/79f2427251b44ddee18676c04eab038d043cff0e764d2d8bb08261d6135d/sqlalchemy-2.0.41-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:911cc493ebd60de5f285bcae0491a60b4f2a9f0f5c270edd1c4dbaef7a38fc04", size = 3209632, upload-time = "2025-05-14T17:51:59.384Z" },
358
- { url = "https://files.pythonhosted.org/packages/d4/16/730a82dda30765f63e0454918c982fb7193f6b398b31d63c7c3bd3652ae5/sqlalchemy-2.0.41-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:03968a349db483936c249f4d9cd14ff2c296adfa1290b660ba6516f973139582", size = 3233642, upload-time = "2025-05-14T17:55:29.901Z" },
359
- { url = "https://files.pythonhosted.org/packages/04/61/c0d4607f7799efa8b8ea3c49b4621e861c8f5c41fd4b5b636c534fcb7d73/sqlalchemy-2.0.41-cp311-cp311-win32.whl", hash = "sha256:293cd444d82b18da48c9f71cd7005844dbbd06ca19be1ccf6779154439eec0b8", size = 2086475, upload-time = "2025-05-14T17:56:02.095Z" },
360
- { url = "https://files.pythonhosted.org/packages/9d/8e/8344f8ae1cb6a479d0741c02cd4f666925b2bf02e2468ddaf5ce44111f30/sqlalchemy-2.0.41-cp311-cp311-win_amd64.whl", hash = "sha256:3d3549fc3e40667ec7199033a4e40a2f669898a00a7b18a931d3efb4c7900504", size = 2110903, upload-time = "2025-05-14T17:56:03.499Z" },
361
- { url = "https://files.pythonhosted.org/packages/3e/2a/f1f4e068b371154740dd10fb81afb5240d5af4aa0087b88d8b308b5429c2/sqlalchemy-2.0.41-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:81f413674d85cfd0dfcd6512e10e0f33c19c21860342a4890c3a2b59479929f9", size = 2119645, upload-time = "2025-05-14T17:55:24.854Z" },
362
- { url = "https://files.pythonhosted.org/packages/9b/e8/c664a7e73d36fbfc4730f8cf2bf930444ea87270f2825efbe17bf808b998/sqlalchemy-2.0.41-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:598d9ebc1e796431bbd068e41e4de4dc34312b7aa3292571bb3674a0cb415dd1", size = 2107399, upload-time = "2025-05-14T17:55:28.097Z" },
363
- { url = "https://files.pythonhosted.org/packages/5c/78/8a9cf6c5e7135540cb682128d091d6afa1b9e48bd049b0d691bf54114f70/sqlalchemy-2.0.41-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a104c5694dfd2d864a6f91b0956eb5d5883234119cb40010115fd45a16da5e70", size = 3293269, upload-time = "2025-05-14T17:50:38.227Z" },
364
- { url = "https://files.pythonhosted.org/packages/3c/35/f74add3978c20de6323fb11cb5162702670cc7a9420033befb43d8d5b7a4/sqlalchemy-2.0.41-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6145afea51ff0af7f2564a05fa95eb46f542919e6523729663a5d285ecb3cf5e", size = 3303364, upload-time = "2025-05-14T17:51:49.829Z" },
365
- { url = "https://files.pythonhosted.org/packages/6a/d4/c990f37f52c3f7748ebe98883e2a0f7d038108c2c5a82468d1ff3eec50b7/sqlalchemy-2.0.41-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b46fa6eae1cd1c20e6e6f44e19984d438b6b2d8616d21d783d150df714f44078", size = 3229072, upload-time = "2025-05-14T17:50:39.774Z" },
366
- { url = "https://files.pythonhosted.org/packages/15/69/cab11fecc7eb64bc561011be2bd03d065b762d87add52a4ca0aca2e12904/sqlalchemy-2.0.41-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41836fe661cc98abfae476e14ba1906220f92c4e528771a8a3ae6a151242d2ae", size = 3268074, upload-time = "2025-05-14T17:51:51.736Z" },
367
- { url = "https://files.pythonhosted.org/packages/5c/ca/0c19ec16858585d37767b167fc9602593f98998a68a798450558239fb04a/sqlalchemy-2.0.41-cp312-cp312-win32.whl", hash = "sha256:a8808d5cf866c781150d36a3c8eb3adccfa41a8105d031bf27e92c251e3969d6", size = 2084514, upload-time = "2025-05-14T17:55:49.915Z" },
368
- { url = "https://files.pythonhosted.org/packages/7f/23/4c2833d78ff3010a4e17f984c734f52b531a8c9060a50429c9d4b0211be6/sqlalchemy-2.0.41-cp312-cp312-win_amd64.whl", hash = "sha256:5b14e97886199c1f52c14629c11d90c11fbb09e9334fa7bb5f6d068d9ced0ce0", size = 2111557, upload-time = "2025-05-14T17:55:51.349Z" },
369
- { url = "https://files.pythonhosted.org/packages/d3/ad/2e1c6d4f235a97eeef52d0200d8ddda16f6c4dd70ae5ad88c46963440480/sqlalchemy-2.0.41-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4eeb195cdedaf17aab6b247894ff2734dcead6c08f748e617bfe05bd5a218443", size = 2115491, upload-time = "2025-05-14T17:55:31.177Z" },
370
- { url = "https://files.pythonhosted.org/packages/cf/8d/be490e5db8400dacc89056f78a52d44b04fbf75e8439569d5b879623a53b/sqlalchemy-2.0.41-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d4ae769b9c1c7757e4ccce94b0641bc203bbdf43ba7a2413ab2523d8d047d8dc", size = 2102827, upload-time = "2025-05-14T17:55:34.921Z" },
371
- { url = "https://files.pythonhosted.org/packages/a0/72/c97ad430f0b0e78efaf2791342e13ffeafcbb3c06242f01a3bb8fe44f65d/sqlalchemy-2.0.41-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a62448526dd9ed3e3beedc93df9bb6b55a436ed1474db31a2af13b313a70a7e1", size = 3225224, upload-time = "2025-05-14T17:50:41.418Z" },
372
- { url = "https://files.pythonhosted.org/packages/5e/51/5ba9ea3246ea068630acf35a6ba0d181e99f1af1afd17e159eac7e8bc2b8/sqlalchemy-2.0.41-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc56c9788617b8964ad02e8fcfeed4001c1f8ba91a9e1f31483c0dffb207002a", size = 3230045, upload-time = "2025-05-14T17:51:54.722Z" },
373
- { url = "https://files.pythonhosted.org/packages/78/2f/8c14443b2acea700c62f9b4a8bad9e49fc1b65cfb260edead71fd38e9f19/sqlalchemy-2.0.41-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c153265408d18de4cc5ded1941dcd8315894572cddd3c58df5d5b5705b3fa28d", size = 3159357, upload-time = "2025-05-14T17:50:43.483Z" },
374
- { url = "https://files.pythonhosted.org/packages/fc/b2/43eacbf6ccc5276d76cea18cb7c3d73e294d6fb21f9ff8b4eef9b42bbfd5/sqlalchemy-2.0.41-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f67766965996e63bb46cfbf2ce5355fc32d9dd3b8ad7e536a920ff9ee422e23", size = 3197511, upload-time = "2025-05-14T17:51:57.308Z" },
375
- { url = "https://files.pythonhosted.org/packages/fa/2e/677c17c5d6a004c3c45334ab1dbe7b7deb834430b282b8a0f75ae220c8eb/sqlalchemy-2.0.41-cp313-cp313-win32.whl", hash = "sha256:bfc9064f6658a3d1cadeaa0ba07570b83ce6801a1314985bf98ec9b95d74e15f", size = 2082420, upload-time = "2025-05-14T17:55:52.69Z" },
376
- { url = "https://files.pythonhosted.org/packages/e9/61/e8c1b9b6307c57157d328dd8b8348ddc4c47ffdf1279365a13b2b98b8049/sqlalchemy-2.0.41-cp313-cp313-win_amd64.whl", hash = "sha256:82ca366a844eb551daff9d2e6e7a9e5e76d2612c8564f58db6c19a726869c1df", size = 2108329, upload-time = "2025-05-14T17:55:54.495Z" },
377
- { url = "https://files.pythonhosted.org/packages/1c/fc/9ba22f01b5cdacc8f5ed0d22304718d2c758fce3fd49a5372b886a86f37c/sqlalchemy-2.0.41-py3-none-any.whl", hash = "sha256:57df5dc6fdb5ed1a88a1ed2195fd31927e705cad62dedd86b46972752a80f576", size = 1911224, upload-time = "2025-05-14T17:39:42.154Z" },
378
- ]
379
-
380
280
  [[package]]
381
281
  name = "tiktoken"
382
282
  version = "0.9.0"
@@ -1,205 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from typing import TYPE_CHECKING, Annotated, Any, Literal, Type, Union
4
- from uuid import uuid4
5
-
6
- from pydantic import BaseModel, Discriminator, Field, field_validator
7
- from sqlalchemy import ColumnElement, and_, or_
8
-
9
- from docent._log_util import get_logger
10
-
11
- if TYPE_CHECKING:
12
- from docent_core._db_service.schemas.tables import SQLAAgentRun
13
-
14
- logger = get_logger(__name__)
15
-
16
-
17
- class BaseFrameFilter(BaseModel):
18
- """Base class for all frame filters."""
19
-
20
- id: str = Field(default_factory=lambda: str(uuid4()))
21
- name: str | None = None
22
- supports_sql: bool = True # All filters must support SQL
23
-
24
- def to_sqla_where_clause(self, table: Type["SQLAAgentRun"]) -> ColumnElement[bool] | None:
25
- """Convert this filter to a SQLAlchemy WHERE clause.
26
-
27
- All filters must implement this method to support SQL execution.
28
- """
29
- raise NotImplementedError(
30
- f"Filter {self.__class__.__name__} must implement to_sqla_where_clause"
31
- )
32
-
33
-
34
- class PrimitiveFilter(BaseFrameFilter):
35
- """Filter that applies a primitive operation to a metadata field."""
36
-
37
- type: Literal["primitive"] = "primitive"
38
- key_path: list[str]
39
- value: Any
40
- op: Literal[">", ">=", "<", "<=", "==", "!=", "~*", "!~*"]
41
-
42
- def to_sqla_where_clause(self, table: Type["SQLAAgentRun"]) -> ColumnElement[bool] | None:
43
- """Convert this filter to a SQLAlchemy WHERE clause."""
44
-
45
- mode = self.key_path[0]
46
-
47
- # Extract value from JSONB using the table parameter
48
- if mode == "text":
49
- sqla_value = table.text_for_search # type: ignore
50
- elif mode == "metadata":
51
- sqla_value = table.metadata_json # type: ignore
52
- else:
53
- raise ValueError(f"Unsupported mode: {mode}")
54
-
55
- for key in self.key_path[1:]:
56
- sqla_value = sqla_value[key]
57
-
58
- # Cast the extracted value to the correct type
59
- # This is only necessary for metadata which is JSONB
60
- if mode == "metadata":
61
- if isinstance(self.value, str):
62
- sqla_value = sqla_value.as_string()
63
- elif isinstance(self.value, bool):
64
- sqla_value = sqla_value.as_boolean()
65
- elif isinstance(self.value, float) or isinstance(self.value, int): # type: ignore warning about unnecessary comparison
66
- # if self.value is an int, we may still need to do sql comparisons with floats
67
- sqla_value = sqla_value.as_float()
68
- else:
69
- raise ValueError(f"Unsupported value type: {type(self.value)}")
70
-
71
- # Handle different operations using SQLAlchemy expressions
72
- if self.op == "==":
73
- return sqla_value == self.value
74
- elif self.op == "!=":
75
- return sqla_value != self.value
76
- elif self.op == ">":
77
- return sqla_value > self.value
78
- elif self.op == ">=":
79
- return sqla_value >= self.value
80
- elif self.op == "<":
81
- return sqla_value < self.value
82
- elif self.op == "<=":
83
- return sqla_value <= self.value
84
- elif self.op == "~*":
85
- return sqla_value.op("~*")(self.value)
86
- else:
87
- raise ValueError(f"Unsupported operation: {self.op}")
88
-
89
-
90
- class ComplexFilter(BaseFrameFilter):
91
- """Filter that combines multiple filters with AND/OR/NOT logic."""
92
-
93
- type: Literal["complex"] = "complex"
94
- filters: list[FrameFilter]
95
- op: Literal["and", "or"] = "and"
96
-
97
- @field_validator("filters")
98
- @classmethod
99
- def validate_filters(cls, v: list[FrameFilter]) -> list[FrameFilter]:
100
- if not v:
101
- raise ValueError("ComplexFilter must have at least one filter")
102
- return v
103
-
104
- def to_sqla_where_clause(self, table: Type["SQLAAgentRun"]) -> ColumnElement[bool] | None:
105
- """Convert this filter to a SQLAlchemy WHERE clause."""
106
-
107
- # Get WHERE clauses for all sub-filters
108
- where_clauses: list[ColumnElement[bool]] = []
109
- for filter_obj in self.filters:
110
- where_clause = filter_obj.to_sqla_where_clause(table)
111
- if where_clause is not None:
112
- where_clauses.append(where_clause)
113
-
114
- if not where_clauses:
115
- return None
116
-
117
- # Apply the operation
118
- if self.op == "and":
119
- result = and_(*where_clauses)
120
- elif self.op == "or":
121
- result = or_(*where_clauses)
122
- else:
123
- raise ValueError(f"Unsupported operation: {self.op}")
124
-
125
- return result
126
-
127
-
128
- class AgentRunIdFilter(BaseFrameFilter):
129
- """Filter that matches specific agent run IDs."""
130
-
131
- type: Literal["agent_run_id"] = "agent_run_id"
132
- agent_run_ids: list[str]
133
-
134
- @field_validator("agent_run_ids")
135
- @classmethod
136
- def validate_agent_run_ids(cls, v: list[str]) -> list[str]:
137
- if not v:
138
- raise ValueError("AgentRunIdFilter must have at least one agent run ID")
139
- return v
140
-
141
- def to_sqla_where_clause(self, table: Type["SQLAAgentRun"]) -> ColumnElement[bool] | None:
142
- """Convert to SQLAlchemy WHERE clause for agent run ID filtering."""
143
- return table.id.in_(self.agent_run_ids)
144
-
145
-
146
- class SearchResultPredicateFilter(BaseFrameFilter):
147
- """Filter that applies a predicate to search results."""
148
-
149
- type: Literal["search_result_predicate"] = "search_result_predicate"
150
- predicate: str
151
- search_query: str
152
-
153
- def to_sqla_where_clause(self, table: Type["SQLAAgentRun"]) -> ColumnElement[bool] | None:
154
- """Convert to SQLAlchemy WHERE clause for search result filtering."""
155
- # This filter requires joining with search results table
156
- # For now, we'll return None to indicate it needs special handling
157
- # In practice, this would join with the search_results table
158
- return None
159
-
160
-
161
- class SearchResultExistsFilter(BaseFrameFilter):
162
- """Filter that checks if search results exist."""
163
-
164
- type: Literal["search_result_exists"] = "search_result_exists"
165
- search_query: str
166
-
167
- def to_sqla_where_clause(self, table: Type["SQLAAgentRun"]) -> ColumnElement[bool] | None:
168
- """Convert to SQLAlchemy WHERE clause for search result existence filtering."""
169
- # This filter requires joining with search results table
170
- # For now, we'll return None to indicate it needs special handling
171
- # In practice, this would join with the search_results table
172
- return None
173
-
174
-
175
- FrameFilter = Annotated[
176
- Union[
177
- PrimitiveFilter,
178
- ComplexFilter,
179
- AgentRunIdFilter,
180
- SearchResultPredicateFilter,
181
- SearchResultExistsFilter,
182
- ],
183
- Discriminator("type"),
184
- ]
185
-
186
-
187
- def parse_filter_dict(filter_dict: dict[str, Any]) -> FrameFilter:
188
- """Parse a filter dictionary into a FrameFilter object."""
189
- filter_type = filter_dict.get("type")
190
-
191
- if filter_type == "primitive":
192
- return PrimitiveFilter(**filter_dict)
193
- elif filter_type == "complex":
194
- # Recursively parse nested filters
195
- nested_filters = [parse_filter_dict(f) for f in filter_dict.get("filters", [])]
196
- filter_dict["filters"] = nested_filters
197
- return ComplexFilter(**filter_dict)
198
- elif filter_type == "agent_run_id":
199
- return AgentRunIdFilter(**filter_dict)
200
- elif filter_type == "search_result_predicate":
201
- return SearchResultPredicateFilter(**filter_dict)
202
- elif filter_type == "search_result_exists":
203
- return SearchResultExistsFilter(**filter_dict)
204
- else:
205
- raise ValueError(f"Unknown filter type: {filter_type}")