diff --git a/.stats.yml b/.stats.yml
index 96d65ef5..83b7ea96 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1 +1 @@
-configured_endpoints: 199
+configured_endpoints: 183
diff --git a/README.md b/README.md
index fd26910b..6863a3ed 100644
--- a/README.md
+++ b/README.md
@@ -140,14 +140,33 @@ from casedev import Casedev
client = Casedev()
-agent = client.agent.v1.agents.create(
- instructions="instructions",
- name="name",
- sandbox={},
+response = client.connectors.v1.sync_link(
+ connection_id="connection_id",
+ direction="import",
+ remote={"folder_id": "folder_id"},
+ vault_id="vault_id",
)
-print(agent.sandbox)
+print(response.remote)
```
+## File uploads
+
+Request parameters that correspond to file uploads can be passed as `bytes`, or a [`PathLike`](https://docs.python.org/3/library/os.html#os.PathLike) instance or a tuple of `(filename, contents, media type)`.
+
+```python
+from pathlib import Path
+from casedev import Casedev
+
+client = Casedev()
+
+client.translate.v1.translate_document(
+ file=Path("/path/to/file"),
+ target="es",
+)
+```
+
+The async client uses the exact same interface. If you pass a [`PathLike`](https://docs.python.org/3/library/os.html#os.PathLike) instance, the file contents will be read asynchronously automatically.
+
## Handling errors
When the library is unable to connect to the API (for example, due to network connection problems or a timeout), a subclass of `casedev.APIConnectionError` is raised.
diff --git a/api.md b/api.md
index c078f6b0..fa2a630a 100644
--- a/api.md
+++ b/api.md
@@ -1,68 +1,62 @@
-# Agent
+# Connectors
## V1
-### Agents
-
Types:
```python
-from casedev.types.agent.v1 import (
- AgentCreateResponse,
- AgentRetrieveResponse,
- AgentUpdateResponse,
- AgentListResponse,
- AgentDeleteResponse,
-)
+from casedev.types.connectors import V1SyncLinkResponse, V1TransferResponse
```
Methods:
-- client.agent.v1.agents.create(\*\*params) -> AgentCreateResponse
-- client.agent.v1.agents.retrieve(id) -> AgentRetrieveResponse
-- client.agent.v1.agents.update(id, \*\*params) -> AgentUpdateResponse
-- client.agent.v1.agents.list(\*\*params) -> AgentListResponse
-- client.agent.v1.agents.delete(id) -> AgentDeleteResponse
+- client.connectors.v1.sync_link(\*\*params) -> V1SyncLinkResponse
+- client.connectors.v1.transfer(\*\*params) -> V1TransferResponse
-### Run
+### Installations
-Types:
+Methods:
-```python
-from casedev.types.agent.v1 import (
- RunCreateResponse,
- RunListResponse,
- RunCancelResponse,
- RunEventsResponse,
- RunExecResponse,
- RunGetDetailsResponse,
- RunGetStatusResponse,
- RunWatchResponse,
-)
-```
+- client.connectors.v1.installations.list(\*\*params) -> None
+- client.connectors.v1.installations.ensure(\*\*params) -> None
+
+#### Vaults
Methods:
-- client.agent.v1.run.create(\*\*params) -> RunCreateResponse
-- client.agent.v1.run.list(\*\*params) -> RunListResponse
-- client.agent.v1.run.cancel(id) -> RunCancelResponse
-- client.agent.v1.run.events(id, \*\*params) -> str
-- client.agent.v1.run.exec(id) -> RunExecResponse
-- client.agent.v1.run.get_details(id) -> RunGetDetailsResponse
-- client.agent.v1.run.get_status(id) -> RunGetStatusResponse
-- client.agent.v1.run.watch(id, \*\*params) -> RunWatchResponse
+- client.connectors.v1.installations.vaults.list(id) -> None
+- client.connectors.v1.installations.vaults.grant(vault_id, \*, id, \*\*params) -> None
+- client.connectors.v1.installations.vaults.revoke(vault_id, \*, id) -> None
-### Execute
+### Connections
Types:
```python
-from casedev.types.agent.v1 import ExecuteCreateResponse
+from casedev.types.connectors.v1 import (
+ ConnectionCreateResponse,
+ ConnectionListResponse,
+ ConnectionBrowseResponse,
+)
```
Methods:
-- client.agent.v1.execute.create(\*\*params) -> ExecuteCreateResponse
+- client.connectors.v1.connections.create(\*\*params) -> ConnectionCreateResponse
+- client.connectors.v1.connections.retrieve(id) -> None
+- client.connectors.v1.connections.list(\*\*params) -> ConnectionListResponse
+- client.connectors.v1.connections.delete(id, \*\*params) -> None
+- client.connectors.v1.connections.browse(id, \*\*params) -> ConnectionBrowseResponse
+
+### Links
+
+Methods:
+
+- client.connectors.v1.links.retrieve(id) -> None
+- client.connectors.v1.links.update(id, \*\*params) -> None
+- client.connectors.v1.links.list(\*\*params) -> None
+- client.connectors.v1.links.delete(id, \*\*params) -> None
+- client.connectors.v1.links.list_objects(id, \*\*params) -> None
# System
@@ -167,72 +161,6 @@ Methods:
- client.compute.v1.secrets.retrieve_group(group, \*\*params) -> SecretRetrieveGroupResponse
- client.compute.v1.secrets.update_group(group, \*\*params) -> SecretUpdateGroupResponse
-# Database
-
-## V1
-
-Types:
-
-```python
-from casedev.types.database import V1GetUsageResponse
-```
-
-Methods:
-
-- client.database.v1.get_usage() -> V1GetUsageResponse
-
-### Projects
-
-Types:
-
-```python
-from casedev.types.database.v1 import (
- ProjectCreateResponse,
- ProjectRetrieveResponse,
- ProjectListResponse,
- ProjectDeleteResponse,
- ProjectCreateBranchResponse,
- ProjectGetConnectionResponse,
- ProjectListBranchesResponse,
-)
-```
-
-Methods:
-
-- client.database.v1.projects.create(\*\*params) -> ProjectCreateResponse
-- client.database.v1.projects.retrieve(id) -> ProjectRetrieveResponse
-- client.database.v1.projects.list() -> ProjectListResponse
-- client.database.v1.projects.delete(id) -> ProjectDeleteResponse
-- client.database.v1.projects.create_branch(id, \*\*params) -> ProjectCreateBranchResponse
-- client.database.v1.projects.get_connection(id, \*\*params) -> ProjectGetConnectionResponse
-- client.database.v1.projects.list_branches(id) -> ProjectListBranchesResponse
-
-# Format
-
-## V1
-
-Methods:
-
-- client.format.v1.create_document(\*\*params) -> BinaryAPIResponse
-
-### Templates
-
-Types:
-
-```python
-from casedev.types.format.v1 import (
- TemplateCreateResponse,
- TemplateRetrieveResponse,
- TemplateListResponse,
-)
-```
-
-Methods:
-
-- client.format.v1.templates.create(\*\*params) -> TemplateCreateResponse
-- client.format.v1.templates.retrieve(id) -> TemplateRetrieveResponse
-- client.format.v1.templates.list(\*\*params) -> TemplateListResponse
-
# Legal
## V1
@@ -244,7 +172,6 @@ from casedev.types.legal import (
DocketDetail,
DocketSearchResult,
V1DocketResponse,
- V1DraftResponse,
V1FindResponse,
V1GetCitationsResponse,
V1GetCitationsFromURLResponse,
@@ -263,7 +190,6 @@ from casedev.types.legal import (
Methods:
- client.legal.v1.docket(\*\*params) -> V1DocketResponse
-- client.legal.v1.draft(\*\*params) -> V1DraftResponse
- client.legal.v1.find(\*\*params) -> V1FindResponse
- client.legal.v1.get_citations(\*\*params) -> V1GetCitationsResponse
- client.legal.v1.get_citations_from_url(\*\*params) -> V1GetCitationsFromURLResponse
@@ -277,6 +203,23 @@ Methods:
- client.legal.v1.trademark_search(\*\*params) -> V1TrademarkSearchResponse
- client.legal.v1.verify(\*\*params) -> V1VerifyResponse
+# Linc
+
+## V1
+
+### Sessions
+
+Methods:
+
+- client.linc.v1.sessions.create(\*\*params) -> None
+- client.linc.v1.sessions.delete(id) -> None
+- client.linc.v1.sessions.cancel(id, \*\*params) -> None
+- client.linc.v1.sessions.ingest_events(id, \*\*params) -> None
+- client.linc.v1.sessions.retrieve_events(id, \*\*params) -> None
+- client.linc.v1.sessions.retrieve_messages(id, \*\*params) -> None
+- client.linc.v1.sessions.retrieve_state(id) -> None
+- client.linc.v1.sessions.send_rpc(path_id, \*\*params) -> None
+
# Matters
## V1
@@ -361,7 +304,6 @@ Methods:
- client.matters.v1.work_items.update(work_item_id, \*, id, \*\*params) -> None
- client.matters.v1.work_items.list(id, \*\*params) -> None
- client.matters.v1.work_items.decide(work_item_id, \*, id, \*\*params) -> None
-- client.matters.v1.work_items.list_executions(work_item_id, \*, id) -> None
# Llm
@@ -445,6 +387,18 @@ Methods:
- client.media.v1.transcripts.search.create() -> None
+#### Retrieve
+
+Types:
+
+```python
+from casedev.types.media.v1.transcripts import RetrieveCreateResponse
+```
+
+Methods:
+
+- client.media.v1.transcripts.retrieve.create(\*\*params) -> RetrieveCreateResponse
+
# Ocr
## V1
@@ -475,26 +429,6 @@ Methods:
- client.privilege.v1.detect(\*\*params) -> V1DetectResponse
-# Mail
-
-## V1
-
-### Inboxes
-
-Methods:
-
-- client.mail.v1.inboxes.create(\*\*params) -> None
-- client.mail.v1.inboxes.retrieve(inbox_id) -> None
-- client.mail.v1.inboxes.list() -> None
-- client.mail.v1.inboxes.delete(inbox_id) -> None
-- client.mail.v1.inboxes.get_attachment(attachment_id, \*, inbox_id, message_id) -> None
-- client.mail.v1.inboxes.get_message(message_id, \*, inbox_id) -> None
-- client.mail.v1.inboxes.get_policy(inbox_id) -> None
-- client.mail.v1.inboxes.list_messages(inbox_id) -> None
-- client.mail.v1.inboxes.reply(message_id, \*, inbox_id) -> None
-- client.mail.v1.inboxes.send(inbox_id) -> None
-- client.mail.v1.inboxes.set_policy(inbox_id, \*\*params) -> None
-
# Skills
Types:
@@ -543,8 +477,6 @@ Types:
from casedev.types.search import (
V1AnswerResponse,
V1ContentsResponse,
- V1ResearchResponse,
- V1RetrieveResearchResponse,
V1SearchResponse,
V1SimilarResponse,
)
@@ -554,20 +486,9 @@ Methods:
- client.search.v1.answer(\*\*params) -> V1AnswerResponse
- client.search.v1.contents(\*\*params) -> V1ContentsResponse
-- client.search.v1.research(\*\*params) -> V1ResearchResponse
-- client.search.v1.retrieve_research(id, \*\*params) -> V1RetrieveResearchResponse
- client.search.v1.search(\*\*params) -> V1SearchResponse
- client.search.v1.similar(\*\*params) -> V1SimilarResponse
-# Superdoc
-
-## V1
-
-Methods:
-
-- client.superdoc.v1.annotate(\*\*params) -> BinaryAPIResponse
-- client.superdoc.v1.convert(\*\*params) -> BinaryAPIResponse
-
# Translate
## V1
@@ -583,6 +504,7 @@ Methods:
- client.translate.v1.detect(\*\*params) -> V1DetectResponse
- client.translate.v1.list_languages(\*\*params) -> V1ListLanguagesResponse
- client.translate.v1.translate(\*\*params) -> V1TranslateResponse
+- client.translate.v1.translate_document(\*\*params) -> BinaryAPIResponse
# Usage
@@ -644,24 +566,6 @@ Methods:
- client.vault.events.subscriptions.delete(subscription_id, \*, id) -> None
- client.vault.events.subscriptions.test(subscription_id, \*, id, \*\*params) -> None
-## Graphrag
-
-Types:
-
-```python
-from casedev.types.vault import (
- GraphragGetStatsResponse,
- GraphragInitResponse,
- GraphragProcessObjectResponse,
-)
-```
-
-Methods:
-
-- client.vault.graphrag.get_stats(id) -> GraphragGetStatsResponse
-- client.vault.graphrag.init(id) -> GraphragInitResponse
-- client.vault.graphrag.process_object(object_id, \*, id) -> GraphragProcessObjectResponse
-
## Groups
Methods:
@@ -676,13 +580,15 @@ Methods:
Types:
```python
-from casedev.types.vault import MultipartGetPartURLsResponse
+from casedev.types.vault import MultipartGetPartURLsResponse, MultipartInitResponse
```
Methods:
- client.vault.multipart.abort(id, \*\*params) -> None
+- client.vault.multipart.complete(id, \*\*params) -> None
- client.vault.multipart.get_part_urls(id, \*\*params) -> MultipartGetPartURLsResponse
+- client.vault.multipart.init(id, \*\*params) -> MultipartInitResponse
## Objects
@@ -694,12 +600,13 @@ from casedev.types.vault import (
ObjectUpdateResponse,
ObjectListResponse,
ObjectDeleteResponse,
+ ObjectAppendResponse,
ObjectCreatePresignedURLResponse,
ObjectGetChunksResponse,
ObjectGetOcrWordsResponse,
ObjectGetPagesResponse,
- ObjectGetSummarizeJobResponse,
ObjectGetTextResponse,
+ ObjectMergeResponse,
)
```
@@ -707,15 +614,16 @@ Methods:
- client.vault.objects.retrieve(object_id, \*, id) -> ObjectRetrieveResponse
- client.vault.objects.update(object_id, \*, id, \*\*params) -> ObjectUpdateResponse
-- client.vault.objects.list(id) -> ObjectListResponse
+- client.vault.objects.list(id, \*\*params) -> ObjectListResponse
- client.vault.objects.delete(object_id, \*, id, \*\*params) -> ObjectDeleteResponse
+- client.vault.objects.append(object_id, \*, id, \*\*params) -> ObjectAppendResponse
- client.vault.objects.create_presigned_url(object_id, \*, id, \*\*params) -> ObjectCreatePresignedURLResponse
- client.vault.objects.download(object_id, \*, id) -> BinaryAPIResponse
- client.vault.objects.get_chunks(object_id, \*, id, \*\*params) -> ObjectGetChunksResponse
- client.vault.objects.get_ocr_words(object_id, \*, id, \*\*params) -> ObjectGetOcrWordsResponse
- client.vault.objects.get_pages(object_id, \*, id, \*\*params) -> ObjectGetPagesResponse
-- client.vault.objects.get_summarize_job(job_id, \*, id, object_id) -> ObjectGetSummarizeJobResponse
- client.vault.objects.get_text(object_id, \*, id) -> ObjectGetTextResponse
+- client.vault.objects.merge(id, \*\*params) -> ObjectMergeResponse
## Memory
diff --git a/scripts/lint b/scripts/lint
index 6532679b..580a84ed 100755
--- a/scripts/lint
+++ b/scripts/lint
@@ -13,7 +13,7 @@ else
fi
echo "==> Running pyright"
-uv run pyright
+uv run pyright -p .
echo "==> Running mypy"
uv run mypy .
diff --git a/scripts/mock b/scripts/mock
index 8291c9ea..515631dc 100755
--- a/scripts/mock
+++ b/scripts/mock
@@ -11,7 +11,7 @@ elif [ -n "$STAINLESS_OPENAPI_SPEC_URL" ]; then
URL="$STAINLESS_OPENAPI_SPEC_URL"
else
# Embedded OpenAPI spec (base64-encoded, gzipped)
- EMBEDDED_SPEC="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"
+ EMBEDDED_SPEC="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"
SPEC_TMPFILE="$(mktemp)"
trap 'rm -f "$SPEC_TMPFILE"' EXIT
echo "$EMBEDDED_SPEC" | base64 --decode | gunzip > "$SPEC_TMPFILE"
diff --git a/src/casedev/_client.py b/src/casedev/_client.py
index 42aa532d..e418969f 100644
--- a/src/casedev/_client.py
+++ b/src/casedev/_client.py
@@ -38,47 +38,41 @@
from .resources import (
llm,
ocr,
- mail,
- agent,
+ linc,
legal,
media,
usage,
vault,
voice,
- format,
memory,
search,
skills,
system,
compute,
matters,
- database,
- superdoc,
webhooks,
privilege,
translate,
+ connectors,
)
from .resources.system import SystemResource, AsyncSystemResource
from .resources.llm.llm import LlmResource, AsyncLlmResource
from .resources.ocr.ocr import OcrResource, AsyncOcrResource
- from .resources.mail.mail import MailResource, AsyncMailResource
- from .resources.agent.agent import AgentResource, AsyncAgentResource
+ from .resources.linc.linc import LincResource, AsyncLincResource
from .resources.legal.legal import LegalResource, AsyncLegalResource
from .resources.media.media import MediaResource, AsyncMediaResource
from .resources.usage.usage import UsageResource, AsyncUsageResource
from .resources.vault.vault import VaultResource, AsyncVaultResource
from .resources.voice.voice import VoiceResource, AsyncVoiceResource
- from .resources.format.format import FormatResource, AsyncFormatResource
from .resources.memory.memory import MemoryResource, AsyncMemoryResource
from .resources.search.search import SearchResource, AsyncSearchResource
from .resources.skills.skills import SkillsResource, AsyncSkillsResource
from .resources.compute.compute import ComputeResource, AsyncComputeResource
from .resources.matters.matters import MattersResource, AsyncMattersResource
- from .resources.database.database import DatabaseResource, AsyncDatabaseResource
- from .resources.superdoc.superdoc import SuperdocResource, AsyncSuperdocResource
from .resources.webhooks.webhooks import WebhooksResource, AsyncWebhooksResource
from .resources.privilege.privilege import PrivilegeResource, AsyncPrivilegeResource
from .resources.translate.translate import TranslateResource, AsyncTranslateResource
+ from .resources.connectors.connectors import ConnectorsResource, AsyncConnectorsResource
__all__ = [
"ENVIRONMENTS",
@@ -187,10 +181,10 @@ def __init__(
)
@cached_property
- def agent(self) -> AgentResource:
- from .resources.agent import AgentResource
+ def connectors(self) -> ConnectorsResource:
+ from .resources.connectors import ConnectorsResource
- return AgentResource(self)
+ return ConnectorsResource(self)
@cached_property
def system(self) -> SystemResource:
@@ -205,24 +199,18 @@ def compute(self) -> ComputeResource:
return ComputeResource(self)
- @cached_property
- def database(self) -> DatabaseResource:
- from .resources.database import DatabaseResource
-
- return DatabaseResource(self)
-
- @cached_property
- def format(self) -> FormatResource:
- from .resources.format import FormatResource
-
- return FormatResource(self)
-
@cached_property
def legal(self) -> LegalResource:
from .resources.legal import LegalResource
return LegalResource(self)
+ @cached_property
+ def linc(self) -> LincResource:
+ from .resources.linc import LincResource
+
+ return LincResource(self)
+
@cached_property
def matters(self) -> MattersResource:
from .resources.matters import MattersResource
@@ -260,12 +248,6 @@ def privilege(self) -> PrivilegeResource:
return PrivilegeResource(self)
- @cached_property
- def mail(self) -> MailResource:
- from .resources.mail import MailResource
-
- return MailResource(self)
-
@cached_property
def skills(self) -> SkillsResource:
"""Search and read legal AI skills for agents"""
@@ -279,12 +261,6 @@ def search(self) -> SearchResource:
return SearchResource(self)
- @cached_property
- def superdoc(self) -> SuperdocResource:
- from .resources.superdoc import SuperdocResource
-
- return SuperdocResource(self)
-
@cached_property
def translate(self) -> TranslateResource:
from .resources.translate import TranslateResource
@@ -520,10 +496,10 @@ def __init__(
)
@cached_property
- def agent(self) -> AsyncAgentResource:
- from .resources.agent import AsyncAgentResource
+ def connectors(self) -> AsyncConnectorsResource:
+ from .resources.connectors import AsyncConnectorsResource
- return AsyncAgentResource(self)
+ return AsyncConnectorsResource(self)
@cached_property
def system(self) -> AsyncSystemResource:
@@ -538,24 +514,18 @@ def compute(self) -> AsyncComputeResource:
return AsyncComputeResource(self)
- @cached_property
- def database(self) -> AsyncDatabaseResource:
- from .resources.database import AsyncDatabaseResource
-
- return AsyncDatabaseResource(self)
-
- @cached_property
- def format(self) -> AsyncFormatResource:
- from .resources.format import AsyncFormatResource
-
- return AsyncFormatResource(self)
-
@cached_property
def legal(self) -> AsyncLegalResource:
from .resources.legal import AsyncLegalResource
return AsyncLegalResource(self)
+ @cached_property
+ def linc(self) -> AsyncLincResource:
+ from .resources.linc import AsyncLincResource
+
+ return AsyncLincResource(self)
+
@cached_property
def matters(self) -> AsyncMattersResource:
from .resources.matters import AsyncMattersResource
@@ -593,12 +563,6 @@ def privilege(self) -> AsyncPrivilegeResource:
return AsyncPrivilegeResource(self)
- @cached_property
- def mail(self) -> AsyncMailResource:
- from .resources.mail import AsyncMailResource
-
- return AsyncMailResource(self)
-
@cached_property
def skills(self) -> AsyncSkillsResource:
"""Search and read legal AI skills for agents"""
@@ -612,12 +576,6 @@ def search(self) -> AsyncSearchResource:
return AsyncSearchResource(self)
- @cached_property
- def superdoc(self) -> AsyncSuperdocResource:
- from .resources.superdoc import AsyncSuperdocResource
-
- return AsyncSuperdocResource(self)
-
@cached_property
def translate(self) -> AsyncTranslateResource:
from .resources.translate import AsyncTranslateResource
@@ -771,10 +729,10 @@ def __init__(self, client: Casedev) -> None:
self._client = client
@cached_property
- def agent(self) -> agent.AgentResourceWithRawResponse:
- from .resources.agent import AgentResourceWithRawResponse
+ def connectors(self) -> connectors.ConnectorsResourceWithRawResponse:
+ from .resources.connectors import ConnectorsResourceWithRawResponse
- return AgentResourceWithRawResponse(self._client.agent)
+ return ConnectorsResourceWithRawResponse(self._client.connectors)
@cached_property
def system(self) -> system.SystemResourceWithRawResponse:
@@ -789,24 +747,18 @@ def compute(self) -> compute.ComputeResourceWithRawResponse:
return ComputeResourceWithRawResponse(self._client.compute)
- @cached_property
- def database(self) -> database.DatabaseResourceWithRawResponse:
- from .resources.database import DatabaseResourceWithRawResponse
-
- return DatabaseResourceWithRawResponse(self._client.database)
-
- @cached_property
- def format(self) -> format.FormatResourceWithRawResponse:
- from .resources.format import FormatResourceWithRawResponse
-
- return FormatResourceWithRawResponse(self._client.format)
-
@cached_property
def legal(self) -> legal.LegalResourceWithRawResponse:
from .resources.legal import LegalResourceWithRawResponse
return LegalResourceWithRawResponse(self._client.legal)
+ @cached_property
+ def linc(self) -> linc.LincResourceWithRawResponse:
+ from .resources.linc import LincResourceWithRawResponse
+
+ return LincResourceWithRawResponse(self._client.linc)
+
@cached_property
def matters(self) -> matters.MattersResourceWithRawResponse:
from .resources.matters import MattersResourceWithRawResponse
@@ -844,12 +796,6 @@ def privilege(self) -> privilege.PrivilegeResourceWithRawResponse:
return PrivilegeResourceWithRawResponse(self._client.privilege)
- @cached_property
- def mail(self) -> mail.MailResourceWithRawResponse:
- from .resources.mail import MailResourceWithRawResponse
-
- return MailResourceWithRawResponse(self._client.mail)
-
@cached_property
def skills(self) -> skills.SkillsResourceWithRawResponse:
"""Search and read legal AI skills for agents"""
@@ -863,12 +809,6 @@ def search(self) -> search.SearchResourceWithRawResponse:
return SearchResourceWithRawResponse(self._client.search)
- @cached_property
- def superdoc(self) -> superdoc.SuperdocResourceWithRawResponse:
- from .resources.superdoc import SuperdocResourceWithRawResponse
-
- return SuperdocResourceWithRawResponse(self._client.superdoc)
-
@cached_property
def translate(self) -> translate.TranslateResourceWithRawResponse:
from .resources.translate import TranslateResourceWithRawResponse
@@ -908,10 +848,10 @@ def __init__(self, client: AsyncCasedev) -> None:
self._client = client
@cached_property
- def agent(self) -> agent.AsyncAgentResourceWithRawResponse:
- from .resources.agent import AsyncAgentResourceWithRawResponse
+ def connectors(self) -> connectors.AsyncConnectorsResourceWithRawResponse:
+ from .resources.connectors import AsyncConnectorsResourceWithRawResponse
- return AsyncAgentResourceWithRawResponse(self._client.agent)
+ return AsyncConnectorsResourceWithRawResponse(self._client.connectors)
@cached_property
def system(self) -> system.AsyncSystemResourceWithRawResponse:
@@ -926,24 +866,18 @@ def compute(self) -> compute.AsyncComputeResourceWithRawResponse:
return AsyncComputeResourceWithRawResponse(self._client.compute)
- @cached_property
- def database(self) -> database.AsyncDatabaseResourceWithRawResponse:
- from .resources.database import AsyncDatabaseResourceWithRawResponse
-
- return AsyncDatabaseResourceWithRawResponse(self._client.database)
-
- @cached_property
- def format(self) -> format.AsyncFormatResourceWithRawResponse:
- from .resources.format import AsyncFormatResourceWithRawResponse
-
- return AsyncFormatResourceWithRawResponse(self._client.format)
-
@cached_property
def legal(self) -> legal.AsyncLegalResourceWithRawResponse:
from .resources.legal import AsyncLegalResourceWithRawResponse
return AsyncLegalResourceWithRawResponse(self._client.legal)
+ @cached_property
+ def linc(self) -> linc.AsyncLincResourceWithRawResponse:
+ from .resources.linc import AsyncLincResourceWithRawResponse
+
+ return AsyncLincResourceWithRawResponse(self._client.linc)
+
@cached_property
def matters(self) -> matters.AsyncMattersResourceWithRawResponse:
from .resources.matters import AsyncMattersResourceWithRawResponse
@@ -981,12 +915,6 @@ def privilege(self) -> privilege.AsyncPrivilegeResourceWithRawResponse:
return AsyncPrivilegeResourceWithRawResponse(self._client.privilege)
- @cached_property
- def mail(self) -> mail.AsyncMailResourceWithRawResponse:
- from .resources.mail import AsyncMailResourceWithRawResponse
-
- return AsyncMailResourceWithRawResponse(self._client.mail)
-
@cached_property
def skills(self) -> skills.AsyncSkillsResourceWithRawResponse:
"""Search and read legal AI skills for agents"""
@@ -1000,12 +928,6 @@ def search(self) -> search.AsyncSearchResourceWithRawResponse:
return AsyncSearchResourceWithRawResponse(self._client.search)
- @cached_property
- def superdoc(self) -> superdoc.AsyncSuperdocResourceWithRawResponse:
- from .resources.superdoc import AsyncSuperdocResourceWithRawResponse
-
- return AsyncSuperdocResourceWithRawResponse(self._client.superdoc)
-
@cached_property
def translate(self) -> translate.AsyncTranslateResourceWithRawResponse:
from .resources.translate import AsyncTranslateResourceWithRawResponse
@@ -1045,10 +967,10 @@ def __init__(self, client: Casedev) -> None:
self._client = client
@cached_property
- def agent(self) -> agent.AgentResourceWithStreamingResponse:
- from .resources.agent import AgentResourceWithStreamingResponse
+ def connectors(self) -> connectors.ConnectorsResourceWithStreamingResponse:
+ from .resources.connectors import ConnectorsResourceWithStreamingResponse
- return AgentResourceWithStreamingResponse(self._client.agent)
+ return ConnectorsResourceWithStreamingResponse(self._client.connectors)
@cached_property
def system(self) -> system.SystemResourceWithStreamingResponse:
@@ -1063,24 +985,18 @@ def compute(self) -> compute.ComputeResourceWithStreamingResponse:
return ComputeResourceWithStreamingResponse(self._client.compute)
- @cached_property
- def database(self) -> database.DatabaseResourceWithStreamingResponse:
- from .resources.database import DatabaseResourceWithStreamingResponse
-
- return DatabaseResourceWithStreamingResponse(self._client.database)
-
- @cached_property
- def format(self) -> format.FormatResourceWithStreamingResponse:
- from .resources.format import FormatResourceWithStreamingResponse
-
- return FormatResourceWithStreamingResponse(self._client.format)
-
@cached_property
def legal(self) -> legal.LegalResourceWithStreamingResponse:
from .resources.legal import LegalResourceWithStreamingResponse
return LegalResourceWithStreamingResponse(self._client.legal)
+ @cached_property
+ def linc(self) -> linc.LincResourceWithStreamingResponse:
+ from .resources.linc import LincResourceWithStreamingResponse
+
+ return LincResourceWithStreamingResponse(self._client.linc)
+
@cached_property
def matters(self) -> matters.MattersResourceWithStreamingResponse:
from .resources.matters import MattersResourceWithStreamingResponse
@@ -1118,12 +1034,6 @@ def privilege(self) -> privilege.PrivilegeResourceWithStreamingResponse:
return PrivilegeResourceWithStreamingResponse(self._client.privilege)
- @cached_property
- def mail(self) -> mail.MailResourceWithStreamingResponse:
- from .resources.mail import MailResourceWithStreamingResponse
-
- return MailResourceWithStreamingResponse(self._client.mail)
-
@cached_property
def skills(self) -> skills.SkillsResourceWithStreamingResponse:
"""Search and read legal AI skills for agents"""
@@ -1137,12 +1047,6 @@ def search(self) -> search.SearchResourceWithStreamingResponse:
return SearchResourceWithStreamingResponse(self._client.search)
- @cached_property
- def superdoc(self) -> superdoc.SuperdocResourceWithStreamingResponse:
- from .resources.superdoc import SuperdocResourceWithStreamingResponse
-
- return SuperdocResourceWithStreamingResponse(self._client.superdoc)
-
@cached_property
def translate(self) -> translate.TranslateResourceWithStreamingResponse:
from .resources.translate import TranslateResourceWithStreamingResponse
@@ -1182,10 +1086,10 @@ def __init__(self, client: AsyncCasedev) -> None:
self._client = client
@cached_property
- def agent(self) -> agent.AsyncAgentResourceWithStreamingResponse:
- from .resources.agent import AsyncAgentResourceWithStreamingResponse
+ def connectors(self) -> connectors.AsyncConnectorsResourceWithStreamingResponse:
+ from .resources.connectors import AsyncConnectorsResourceWithStreamingResponse
- return AsyncAgentResourceWithStreamingResponse(self._client.agent)
+ return AsyncConnectorsResourceWithStreamingResponse(self._client.connectors)
@cached_property
def system(self) -> system.AsyncSystemResourceWithStreamingResponse:
@@ -1200,24 +1104,18 @@ def compute(self) -> compute.AsyncComputeResourceWithStreamingResponse:
return AsyncComputeResourceWithStreamingResponse(self._client.compute)
- @cached_property
- def database(self) -> database.AsyncDatabaseResourceWithStreamingResponse:
- from .resources.database import AsyncDatabaseResourceWithStreamingResponse
-
- return AsyncDatabaseResourceWithStreamingResponse(self._client.database)
-
- @cached_property
- def format(self) -> format.AsyncFormatResourceWithStreamingResponse:
- from .resources.format import AsyncFormatResourceWithStreamingResponse
-
- return AsyncFormatResourceWithStreamingResponse(self._client.format)
-
@cached_property
def legal(self) -> legal.AsyncLegalResourceWithStreamingResponse:
from .resources.legal import AsyncLegalResourceWithStreamingResponse
return AsyncLegalResourceWithStreamingResponse(self._client.legal)
+ @cached_property
+ def linc(self) -> linc.AsyncLincResourceWithStreamingResponse:
+ from .resources.linc import AsyncLincResourceWithStreamingResponse
+
+ return AsyncLincResourceWithStreamingResponse(self._client.linc)
+
@cached_property
def matters(self) -> matters.AsyncMattersResourceWithStreamingResponse:
from .resources.matters import AsyncMattersResourceWithStreamingResponse
@@ -1255,12 +1153,6 @@ def privilege(self) -> privilege.AsyncPrivilegeResourceWithStreamingResponse:
return AsyncPrivilegeResourceWithStreamingResponse(self._client.privilege)
- @cached_property
- def mail(self) -> mail.AsyncMailResourceWithStreamingResponse:
- from .resources.mail import AsyncMailResourceWithStreamingResponse
-
- return AsyncMailResourceWithStreamingResponse(self._client.mail)
-
@cached_property
def skills(self) -> skills.AsyncSkillsResourceWithStreamingResponse:
"""Search and read legal AI skills for agents"""
@@ -1274,12 +1166,6 @@ def search(self) -> search.AsyncSearchResourceWithStreamingResponse:
return AsyncSearchResourceWithStreamingResponse(self._client.search)
- @cached_property
- def superdoc(self) -> superdoc.AsyncSuperdocResourceWithStreamingResponse:
- from .resources.superdoc import AsyncSuperdocResourceWithStreamingResponse
-
- return AsyncSuperdocResourceWithStreamingResponse(self._client.superdoc)
-
@cached_property
def translate(self) -> translate.AsyncTranslateResourceWithStreamingResponse:
from .resources.translate import AsyncTranslateResourceWithStreamingResponse
diff --git a/src/casedev/_files.py b/src/casedev/_files.py
index 76da9e08..9aee1659 100644
--- a/src/casedev/_files.py
+++ b/src/casedev/_files.py
@@ -36,7 +36,7 @@ def assert_is_file_content(obj: object, *, key: str | None = None) -> None:
if not is_file_content(obj):
prefix = f"Expected entry at `{key}`" if key is not None else f"Expected file input `{obj!r}`"
raise RuntimeError(
- f"{prefix} to be bytes, an io.IOBase instance, PathLike or a tuple but received {type(obj)} instead."
+ f"{prefix} to be bytes, an io.IOBase instance, PathLike or a tuple but received {type(obj)} instead. See https://github.com/CaseMark/casedev-python/tree/main#file-uploads"
) from None
diff --git a/src/casedev/resources/__init__.py b/src/casedev/resources/__init__.py
index 0f0b14f6..84699412 100644
--- a/src/casedev/resources/__init__.py
+++ b/src/casedev/resources/__init__.py
@@ -16,21 +16,13 @@
OcrResourceWithStreamingResponse,
AsyncOcrResourceWithStreamingResponse,
)
-from .mail import (
- MailResource,
- AsyncMailResource,
- MailResourceWithRawResponse,
- AsyncMailResourceWithRawResponse,
- MailResourceWithStreamingResponse,
- AsyncMailResourceWithStreamingResponse,
-)
-from .agent import (
- AgentResource,
- AsyncAgentResource,
- AgentResourceWithRawResponse,
- AsyncAgentResourceWithRawResponse,
- AgentResourceWithStreamingResponse,
- AsyncAgentResourceWithStreamingResponse,
+from .linc import (
+ LincResource,
+ AsyncLincResource,
+ LincResourceWithRawResponse,
+ AsyncLincResourceWithRawResponse,
+ LincResourceWithStreamingResponse,
+ AsyncLincResourceWithStreamingResponse,
)
from .legal import (
LegalResource,
@@ -72,14 +64,6 @@
VoiceResourceWithStreamingResponse,
AsyncVoiceResourceWithStreamingResponse,
)
-from .format import (
- FormatResource,
- AsyncFormatResource,
- FormatResourceWithRawResponse,
- AsyncFormatResourceWithRawResponse,
- FormatResourceWithStreamingResponse,
- AsyncFormatResourceWithStreamingResponse,
-)
from .memory import (
MemoryResource,
AsyncMemoryResource,
@@ -128,22 +112,6 @@
MattersResourceWithStreamingResponse,
AsyncMattersResourceWithStreamingResponse,
)
-from .database import (
- DatabaseResource,
- AsyncDatabaseResource,
- DatabaseResourceWithRawResponse,
- AsyncDatabaseResourceWithRawResponse,
- DatabaseResourceWithStreamingResponse,
- AsyncDatabaseResourceWithStreamingResponse,
-)
-from .superdoc import (
- SuperdocResource,
- AsyncSuperdocResource,
- SuperdocResourceWithRawResponse,
- AsyncSuperdocResourceWithRawResponse,
- SuperdocResourceWithStreamingResponse,
- AsyncSuperdocResourceWithStreamingResponse,
-)
from .webhooks import (
WebhooksResource,
AsyncWebhooksResource,
@@ -168,14 +136,22 @@
TranslateResourceWithStreamingResponse,
AsyncTranslateResourceWithStreamingResponse,
)
+from .connectors import (
+ ConnectorsResource,
+ AsyncConnectorsResource,
+ ConnectorsResourceWithRawResponse,
+ AsyncConnectorsResourceWithRawResponse,
+ ConnectorsResourceWithStreamingResponse,
+ AsyncConnectorsResourceWithStreamingResponse,
+)
__all__ = [
- "AgentResource",
- "AsyncAgentResource",
- "AgentResourceWithRawResponse",
- "AsyncAgentResourceWithRawResponse",
- "AgentResourceWithStreamingResponse",
- "AsyncAgentResourceWithStreamingResponse",
+ "ConnectorsResource",
+ "AsyncConnectorsResource",
+ "ConnectorsResourceWithRawResponse",
+ "AsyncConnectorsResourceWithRawResponse",
+ "ConnectorsResourceWithStreamingResponse",
+ "AsyncConnectorsResourceWithStreamingResponse",
"SystemResource",
"AsyncSystemResource",
"SystemResourceWithRawResponse",
@@ -188,24 +164,18 @@
"AsyncComputeResourceWithRawResponse",
"ComputeResourceWithStreamingResponse",
"AsyncComputeResourceWithStreamingResponse",
- "DatabaseResource",
- "AsyncDatabaseResource",
- "DatabaseResourceWithRawResponse",
- "AsyncDatabaseResourceWithRawResponse",
- "DatabaseResourceWithStreamingResponse",
- "AsyncDatabaseResourceWithStreamingResponse",
- "FormatResource",
- "AsyncFormatResource",
- "FormatResourceWithRawResponse",
- "AsyncFormatResourceWithRawResponse",
- "FormatResourceWithStreamingResponse",
- "AsyncFormatResourceWithStreamingResponse",
"LegalResource",
"AsyncLegalResource",
"LegalResourceWithRawResponse",
"AsyncLegalResourceWithRawResponse",
"LegalResourceWithStreamingResponse",
"AsyncLegalResourceWithStreamingResponse",
+ "LincResource",
+ "AsyncLincResource",
+ "LincResourceWithRawResponse",
+ "AsyncLincResourceWithRawResponse",
+ "LincResourceWithStreamingResponse",
+ "AsyncLincResourceWithStreamingResponse",
"MattersResource",
"AsyncMattersResource",
"MattersResourceWithRawResponse",
@@ -242,12 +212,6 @@
"AsyncPrivilegeResourceWithRawResponse",
"PrivilegeResourceWithStreamingResponse",
"AsyncPrivilegeResourceWithStreamingResponse",
- "MailResource",
- "AsyncMailResource",
- "MailResourceWithRawResponse",
- "AsyncMailResourceWithRawResponse",
- "MailResourceWithStreamingResponse",
- "AsyncMailResourceWithStreamingResponse",
"SkillsResource",
"AsyncSkillsResource",
"SkillsResourceWithRawResponse",
@@ -260,12 +224,6 @@
"AsyncSearchResourceWithRawResponse",
"SearchResourceWithStreamingResponse",
"AsyncSearchResourceWithStreamingResponse",
- "SuperdocResource",
- "AsyncSuperdocResource",
- "SuperdocResourceWithRawResponse",
- "AsyncSuperdocResourceWithRawResponse",
- "SuperdocResourceWithStreamingResponse",
- "AsyncSuperdocResourceWithStreamingResponse",
"TranslateResource",
"AsyncTranslateResource",
"TranslateResourceWithRawResponse",
diff --git a/src/casedev/resources/agent/v1/__init__.py b/src/casedev/resources/agent/v1/__init__.py
deleted file mode 100644
index 1c3608c6..00000000
--- a/src/casedev/resources/agent/v1/__init__.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from .v1 import (
- V1Resource,
- AsyncV1Resource,
- V1ResourceWithRawResponse,
- AsyncV1ResourceWithRawResponse,
- V1ResourceWithStreamingResponse,
- AsyncV1ResourceWithStreamingResponse,
-)
-from .run import (
- RunResource,
- AsyncRunResource,
- RunResourceWithRawResponse,
- AsyncRunResourceWithRawResponse,
- RunResourceWithStreamingResponse,
- AsyncRunResourceWithStreamingResponse,
-)
-from .agents import (
- AgentsResource,
- AsyncAgentsResource,
- AgentsResourceWithRawResponse,
- AsyncAgentsResourceWithRawResponse,
- AgentsResourceWithStreamingResponse,
- AsyncAgentsResourceWithStreamingResponse,
-)
-from .execute import (
- ExecuteResource,
- AsyncExecuteResource,
- ExecuteResourceWithRawResponse,
- AsyncExecuteResourceWithRawResponse,
- ExecuteResourceWithStreamingResponse,
- AsyncExecuteResourceWithStreamingResponse,
-)
-
-__all__ = [
- "AgentsResource",
- "AsyncAgentsResource",
- "AgentsResourceWithRawResponse",
- "AsyncAgentsResourceWithRawResponse",
- "AgentsResourceWithStreamingResponse",
- "AsyncAgentsResourceWithStreamingResponse",
- "RunResource",
- "AsyncRunResource",
- "RunResourceWithRawResponse",
- "AsyncRunResourceWithRawResponse",
- "RunResourceWithStreamingResponse",
- "AsyncRunResourceWithStreamingResponse",
- "ExecuteResource",
- "AsyncExecuteResource",
- "ExecuteResourceWithRawResponse",
- "AsyncExecuteResourceWithRawResponse",
- "ExecuteResourceWithStreamingResponse",
- "AsyncExecuteResourceWithStreamingResponse",
- "V1Resource",
- "AsyncV1Resource",
- "V1ResourceWithRawResponse",
- "AsyncV1ResourceWithRawResponse",
- "V1ResourceWithStreamingResponse",
- "AsyncV1ResourceWithStreamingResponse",
-]
diff --git a/src/casedev/resources/agent/v1/execute.py b/src/casedev/resources/agent/v1/execute.py
deleted file mode 100644
index e78aafba..00000000
--- a/src/casedev/resources/agent/v1/execute.py
+++ /dev/null
@@ -1,279 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Optional
-
-import httpx
-
-from ...._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from ...._utils import maybe_transform, async_maybe_transform
-from ...._compat import cached_property
-from ...._resource import SyncAPIResource, AsyncAPIResource
-from ...._response import (
- to_raw_response_wrapper,
- to_streamed_response_wrapper,
- async_to_raw_response_wrapper,
- async_to_streamed_response_wrapper,
-)
-from ...._base_client import make_request_options
-from ....types.agent.v1 import execute_create_params
-from ....types.agent.v1.execute_create_response import ExecuteCreateResponse
-
-__all__ = ["ExecuteResource", "AsyncExecuteResource"]
-
-
-class ExecuteResource(SyncAPIResource):
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
-
- @cached_property
- def with_raw_response(self) -> ExecuteResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
- """
- return ExecuteResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> ExecuteResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
- """
- return ExecuteResourceWithStreamingResponse(self)
-
- def create(
- self,
- *,
- prompt: str,
- disabled_tools: Optional[SequenceNotStr[str]] | Omit = omit,
- enabled_tools: Optional[SequenceNotStr[str]] | Omit = omit,
- guidance: Optional[str] | Omit = omit,
- instructions: str | Omit = omit,
- model: str | Omit = omit,
- object_ids: Optional[SequenceNotStr[str]] | Omit = omit,
- sandbox: Optional[execute_create_params.Sandbox] | Omit = omit,
- vault_ids: Optional[SequenceNotStr[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,
- ) -> ExecuteCreateResponse:
- """Creates an ephemeral agent and immediately executes a run.
-
- Returns the run ID
- for polling status and results. This is the fastest way to run an agent without
- managing agent lifecycle.
-
- **Ephemeral agent lifecycle:** The agent created by this endpoint is
- automatically soft-deleted and its scoped API key revoked when the run completes
- (whether it succeeds, fails, or times out). Ephemeral agents do not appear in
- GET /agent/v1/agents listings. The returned agentId is valid only for the
- duration of the run — do not store it for reuse. For persistent, reusable
- agents, use POST /agent/v1/agents instead.
-
- Args:
- prompt: Task prompt for the agent
-
- disabled_tools: Denylist of tools the agent cannot use. Mutually exclusive with enabledTools —
- set one or the other, not both.
-
- enabled_tools: Allowlist of tools the agent can use. Mutually exclusive with disabledTools —
- set one or the other, not both.
-
- guidance: Additional context or constraints for this run
-
- instructions: System instructions. Defaults to a general-purpose legal assistant prompt if not
- provided.
-
- model: LLM model identifier. Defaults to anthropic/claude-sonnet-4.6
-
- object_ids: Scope this run to specific vault object IDs. The agent will only access these
- objects.
-
- sandbox: Custom sandbox resources (cpu, memoryMiB)
-
- vault_ids: Restrict agent to specific vault IDs
-
- 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(
- "/agent/v1/execute",
- body=maybe_transform(
- {
- "prompt": prompt,
- "disabled_tools": disabled_tools,
- "enabled_tools": enabled_tools,
- "guidance": guidance,
- "instructions": instructions,
- "model": model,
- "object_ids": object_ids,
- "sandbox": sandbox,
- "vault_ids": vault_ids,
- },
- execute_create_params.ExecuteCreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ExecuteCreateResponse,
- )
-
-
-class AsyncExecuteResource(AsyncAPIResource):
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
-
- @cached_property
- def with_raw_response(self) -> AsyncExecuteResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
- """
- return AsyncExecuteResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncExecuteResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
- """
- return AsyncExecuteResourceWithStreamingResponse(self)
-
- async def create(
- self,
- *,
- prompt: str,
- disabled_tools: Optional[SequenceNotStr[str]] | Omit = omit,
- enabled_tools: Optional[SequenceNotStr[str]] | Omit = omit,
- guidance: Optional[str] | Omit = omit,
- instructions: str | Omit = omit,
- model: str | Omit = omit,
- object_ids: Optional[SequenceNotStr[str]] | Omit = omit,
- sandbox: Optional[execute_create_params.Sandbox] | Omit = omit,
- vault_ids: Optional[SequenceNotStr[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,
- ) -> ExecuteCreateResponse:
- """Creates an ephemeral agent and immediately executes a run.
-
- Returns the run ID
- for polling status and results. This is the fastest way to run an agent without
- managing agent lifecycle.
-
- **Ephemeral agent lifecycle:** The agent created by this endpoint is
- automatically soft-deleted and its scoped API key revoked when the run completes
- (whether it succeeds, fails, or times out). Ephemeral agents do not appear in
- GET /agent/v1/agents listings. The returned agentId is valid only for the
- duration of the run — do not store it for reuse. For persistent, reusable
- agents, use POST /agent/v1/agents instead.
-
- Args:
- prompt: Task prompt for the agent
-
- disabled_tools: Denylist of tools the agent cannot use. Mutually exclusive with enabledTools —
- set one or the other, not both.
-
- enabled_tools: Allowlist of tools the agent can use. Mutually exclusive with disabledTools —
- set one or the other, not both.
-
- guidance: Additional context or constraints for this run
-
- instructions: System instructions. Defaults to a general-purpose legal assistant prompt if not
- provided.
-
- model: LLM model identifier. Defaults to anthropic/claude-sonnet-4.6
-
- object_ids: Scope this run to specific vault object IDs. The agent will only access these
- objects.
-
- sandbox: Custom sandbox resources (cpu, memoryMiB)
-
- vault_ids: Restrict agent to specific vault IDs
-
- 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(
- "/agent/v1/execute",
- body=await async_maybe_transform(
- {
- "prompt": prompt,
- "disabled_tools": disabled_tools,
- "enabled_tools": enabled_tools,
- "guidance": guidance,
- "instructions": instructions,
- "model": model,
- "object_ids": object_ids,
- "sandbox": sandbox,
- "vault_ids": vault_ids,
- },
- execute_create_params.ExecuteCreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ExecuteCreateResponse,
- )
-
-
-class ExecuteResourceWithRawResponse:
- def __init__(self, execute: ExecuteResource) -> None:
- self._execute = execute
-
- self.create = to_raw_response_wrapper(
- execute.create,
- )
-
-
-class AsyncExecuteResourceWithRawResponse:
- def __init__(self, execute: AsyncExecuteResource) -> None:
- self._execute = execute
-
- self.create = async_to_raw_response_wrapper(
- execute.create,
- )
-
-
-class ExecuteResourceWithStreamingResponse:
- def __init__(self, execute: ExecuteResource) -> None:
- self._execute = execute
-
- self.create = to_streamed_response_wrapper(
- execute.create,
- )
-
-
-class AsyncExecuteResourceWithStreamingResponse:
- def __init__(self, execute: AsyncExecuteResource) -> None:
- self._execute = execute
-
- self.create = async_to_streamed_response_wrapper(
- execute.create,
- )
diff --git a/src/casedev/resources/agent/v1/v1.py b/src/casedev/resources/agent/v1/v1.py
deleted file mode 100644
index 5d84bf0b..00000000
--- a/src/casedev/resources/agent/v1/v1.py
+++ /dev/null
@@ -1,220 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from .run import (
- RunResource,
- AsyncRunResource,
- RunResourceWithRawResponse,
- AsyncRunResourceWithRawResponse,
- RunResourceWithStreamingResponse,
- AsyncRunResourceWithStreamingResponse,
-)
-from .agents import (
- AgentsResource,
- AsyncAgentsResource,
- AgentsResourceWithRawResponse,
- AsyncAgentsResourceWithRawResponse,
- AgentsResourceWithStreamingResponse,
- AsyncAgentsResourceWithStreamingResponse,
-)
-from .execute import (
- ExecuteResource,
- AsyncExecuteResource,
- ExecuteResourceWithRawResponse,
- AsyncExecuteResourceWithRawResponse,
- ExecuteResourceWithStreamingResponse,
- AsyncExecuteResourceWithStreamingResponse,
-)
-from ...._compat import cached_property
-from ...._resource import SyncAPIResource, AsyncAPIResource
-
-__all__ = ["V1Resource", "AsyncV1Resource"]
-
-
-class V1Resource(SyncAPIResource):
- @cached_property
- def agents(self) -> AgentsResource:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return AgentsResource(self._client)
-
- @cached_property
- def run(self) -> RunResource:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return RunResource(self._client)
-
- @cached_property
- def execute(self) -> ExecuteResource:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return ExecuteResource(self._client)
-
- @cached_property
- def with_raw_response(self) -> V1ResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
- """
- return V1ResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> V1ResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
- """
- return V1ResourceWithStreamingResponse(self)
-
-
-class AsyncV1Resource(AsyncAPIResource):
- @cached_property
- def agents(self) -> AsyncAgentsResource:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return AsyncAgentsResource(self._client)
-
- @cached_property
- def run(self) -> AsyncRunResource:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return AsyncRunResource(self._client)
-
- @cached_property
- def execute(self) -> AsyncExecuteResource:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return AsyncExecuteResource(self._client)
-
- @cached_property
- def with_raw_response(self) -> AsyncV1ResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
- """
- return AsyncV1ResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncV1ResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
- """
- return AsyncV1ResourceWithStreamingResponse(self)
-
-
-class V1ResourceWithRawResponse:
- def __init__(self, v1: V1Resource) -> None:
- self._v1 = v1
-
- @cached_property
- def agents(self) -> AgentsResourceWithRawResponse:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return AgentsResourceWithRawResponse(self._v1.agents)
-
- @cached_property
- def run(self) -> RunResourceWithRawResponse:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return RunResourceWithRawResponse(self._v1.run)
-
- @cached_property
- def execute(self) -> ExecuteResourceWithRawResponse:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return ExecuteResourceWithRawResponse(self._v1.execute)
-
-
-class AsyncV1ResourceWithRawResponse:
- def __init__(self, v1: AsyncV1Resource) -> None:
- self._v1 = v1
-
- @cached_property
- def agents(self) -> AsyncAgentsResourceWithRawResponse:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return AsyncAgentsResourceWithRawResponse(self._v1.agents)
-
- @cached_property
- def run(self) -> AsyncRunResourceWithRawResponse:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return AsyncRunResourceWithRawResponse(self._v1.run)
-
- @cached_property
- def execute(self) -> AsyncExecuteResourceWithRawResponse:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return AsyncExecuteResourceWithRawResponse(self._v1.execute)
-
-
-class V1ResourceWithStreamingResponse:
- def __init__(self, v1: V1Resource) -> None:
- self._v1 = v1
-
- @cached_property
- def agents(self) -> AgentsResourceWithStreamingResponse:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return AgentsResourceWithStreamingResponse(self._v1.agents)
-
- @cached_property
- def run(self) -> RunResourceWithStreamingResponse:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return RunResourceWithStreamingResponse(self._v1.run)
-
- @cached_property
- def execute(self) -> ExecuteResourceWithStreamingResponse:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return ExecuteResourceWithStreamingResponse(self._v1.execute)
-
-
-class AsyncV1ResourceWithStreamingResponse:
- def __init__(self, v1: AsyncV1Resource) -> None:
- self._v1 = v1
-
- @cached_property
- def agents(self) -> AsyncAgentsResourceWithStreamingResponse:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return AsyncAgentsResourceWithStreamingResponse(self._v1.agents)
-
- @cached_property
- def run(self) -> AsyncRunResourceWithStreamingResponse:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return AsyncRunResourceWithStreamingResponse(self._v1.run)
-
- @cached_property
- def execute(self) -> AsyncExecuteResourceWithStreamingResponse:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return AsyncExecuteResourceWithStreamingResponse(self._v1.execute)
diff --git a/src/casedev/resources/database/__init__.py b/src/casedev/resources/connectors/__init__.py
similarity index 50%
rename from src/casedev/resources/database/__init__.py
rename to src/casedev/resources/connectors/__init__.py
index 02eed9d2..a0e9329f 100644
--- a/src/casedev/resources/database/__init__.py
+++ b/src/casedev/resources/connectors/__init__.py
@@ -8,13 +8,13 @@
V1ResourceWithStreamingResponse,
AsyncV1ResourceWithStreamingResponse,
)
-from .database import (
- DatabaseResource,
- AsyncDatabaseResource,
- DatabaseResourceWithRawResponse,
- AsyncDatabaseResourceWithRawResponse,
- DatabaseResourceWithStreamingResponse,
- AsyncDatabaseResourceWithStreamingResponse,
+from .connectors import (
+ ConnectorsResource,
+ AsyncConnectorsResource,
+ ConnectorsResourceWithRawResponse,
+ AsyncConnectorsResourceWithRawResponse,
+ ConnectorsResourceWithStreamingResponse,
+ AsyncConnectorsResourceWithStreamingResponse,
)
__all__ = [
@@ -24,10 +24,10 @@
"AsyncV1ResourceWithRawResponse",
"V1ResourceWithStreamingResponse",
"AsyncV1ResourceWithStreamingResponse",
- "DatabaseResource",
- "AsyncDatabaseResource",
- "DatabaseResourceWithRawResponse",
- "AsyncDatabaseResourceWithRawResponse",
- "DatabaseResourceWithStreamingResponse",
- "AsyncDatabaseResourceWithStreamingResponse",
+ "ConnectorsResource",
+ "AsyncConnectorsResource",
+ "ConnectorsResourceWithRawResponse",
+ "AsyncConnectorsResourceWithRawResponse",
+ "ConnectorsResourceWithStreamingResponse",
+ "AsyncConnectorsResourceWithStreamingResponse",
]
diff --git a/src/casedev/resources/agent/agent.py b/src/casedev/resources/connectors/connectors.py
similarity index 50%
rename from src/casedev/resources/agent/agent.py
rename to src/casedev/resources/connectors/connectors.py
index 4da17b0d..087107f9 100644
--- a/src/casedev/resources/agent/agent.py
+++ b/src/casedev/resources/connectors/connectors.py
@@ -13,90 +13,96 @@
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
-__all__ = ["AgentResource", "AsyncAgentResource"]
+__all__ = ["ConnectorsResource", "AsyncConnectorsResource"]
-class AgentResource(SyncAPIResource):
+class ConnectorsResource(SyncAPIResource):
@cached_property
def v1(self) -> V1Resource:
+ """Import and export between provider folders (Google Drive) and vaults"""
return V1Resource(self._client)
@cached_property
- def with_raw_response(self) -> AgentResourceWithRawResponse:
+ def with_raw_response(self) -> ConnectorsResourceWithRawResponse:
"""
This property can be used as a prefix for any HTTP method call to return
the raw response object instead of the parsed content.
For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
"""
- return AgentResourceWithRawResponse(self)
+ return ConnectorsResourceWithRawResponse(self)
@cached_property
- def with_streaming_response(self) -> AgentResourceWithStreamingResponse:
+ def with_streaming_response(self) -> ConnectorsResourceWithStreamingResponse:
"""
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
"""
- return AgentResourceWithStreamingResponse(self)
+ return ConnectorsResourceWithStreamingResponse(self)
-class AsyncAgentResource(AsyncAPIResource):
+class AsyncConnectorsResource(AsyncAPIResource):
@cached_property
def v1(self) -> AsyncV1Resource:
+ """Import and export between provider folders (Google Drive) and vaults"""
return AsyncV1Resource(self._client)
@cached_property
- def with_raw_response(self) -> AsyncAgentResourceWithRawResponse:
+ def with_raw_response(self) -> AsyncConnectorsResourceWithRawResponse:
"""
This property can be used as a prefix for any HTTP method call to return
the raw response object instead of the parsed content.
For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
"""
- return AsyncAgentResourceWithRawResponse(self)
+ return AsyncConnectorsResourceWithRawResponse(self)
@cached_property
- def with_streaming_response(self) -> AsyncAgentResourceWithStreamingResponse:
+ def with_streaming_response(self) -> AsyncConnectorsResourceWithStreamingResponse:
"""
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
"""
- return AsyncAgentResourceWithStreamingResponse(self)
+ return AsyncConnectorsResourceWithStreamingResponse(self)
-class AgentResourceWithRawResponse:
- def __init__(self, agent: AgentResource) -> None:
- self._agent = agent
+class ConnectorsResourceWithRawResponse:
+ def __init__(self, connectors: ConnectorsResource) -> None:
+ self._connectors = connectors
@cached_property
def v1(self) -> V1ResourceWithRawResponse:
- return V1ResourceWithRawResponse(self._agent.v1)
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return V1ResourceWithRawResponse(self._connectors.v1)
-class AsyncAgentResourceWithRawResponse:
- def __init__(self, agent: AsyncAgentResource) -> None:
- self._agent = agent
+class AsyncConnectorsResourceWithRawResponse:
+ def __init__(self, connectors: AsyncConnectorsResource) -> None:
+ self._connectors = connectors
@cached_property
def v1(self) -> AsyncV1ResourceWithRawResponse:
- return AsyncV1ResourceWithRawResponse(self._agent.v1)
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return AsyncV1ResourceWithRawResponse(self._connectors.v1)
-class AgentResourceWithStreamingResponse:
- def __init__(self, agent: AgentResource) -> None:
- self._agent = agent
+class ConnectorsResourceWithStreamingResponse:
+ def __init__(self, connectors: ConnectorsResource) -> None:
+ self._connectors = connectors
@cached_property
def v1(self) -> V1ResourceWithStreamingResponse:
- return V1ResourceWithStreamingResponse(self._agent.v1)
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return V1ResourceWithStreamingResponse(self._connectors.v1)
-class AsyncAgentResourceWithStreamingResponse:
- def __init__(self, agent: AsyncAgentResource) -> None:
- self._agent = agent
+class AsyncConnectorsResourceWithStreamingResponse:
+ def __init__(self, connectors: AsyncConnectorsResource) -> None:
+ self._connectors = connectors
@cached_property
def v1(self) -> AsyncV1ResourceWithStreamingResponse:
- return AsyncV1ResourceWithStreamingResponse(self._agent.v1)
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return AsyncV1ResourceWithStreamingResponse(self._connectors.v1)
diff --git a/src/casedev/resources/connectors/v1/__init__.py b/src/casedev/resources/connectors/v1/__init__.py
new file mode 100644
index 00000000..ea1a7d08
--- /dev/null
+++ b/src/casedev/resources/connectors/v1/__init__.py
@@ -0,0 +1,61 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .v1 import (
+ V1Resource,
+ AsyncV1Resource,
+ V1ResourceWithRawResponse,
+ AsyncV1ResourceWithRawResponse,
+ V1ResourceWithStreamingResponse,
+ AsyncV1ResourceWithStreamingResponse,
+)
+from .links import (
+ LinksResource,
+ AsyncLinksResource,
+ LinksResourceWithRawResponse,
+ AsyncLinksResourceWithRawResponse,
+ LinksResourceWithStreamingResponse,
+ AsyncLinksResourceWithStreamingResponse,
+)
+from .connections import (
+ ConnectionsResource,
+ AsyncConnectionsResource,
+ ConnectionsResourceWithRawResponse,
+ AsyncConnectionsResourceWithRawResponse,
+ ConnectionsResourceWithStreamingResponse,
+ AsyncConnectionsResourceWithStreamingResponse,
+)
+from .installations import (
+ InstallationsResource,
+ AsyncInstallationsResource,
+ InstallationsResourceWithRawResponse,
+ AsyncInstallationsResourceWithRawResponse,
+ InstallationsResourceWithStreamingResponse,
+ AsyncInstallationsResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "InstallationsResource",
+ "AsyncInstallationsResource",
+ "InstallationsResourceWithRawResponse",
+ "AsyncInstallationsResourceWithRawResponse",
+ "InstallationsResourceWithStreamingResponse",
+ "AsyncInstallationsResourceWithStreamingResponse",
+ "ConnectionsResource",
+ "AsyncConnectionsResource",
+ "ConnectionsResourceWithRawResponse",
+ "AsyncConnectionsResourceWithRawResponse",
+ "ConnectionsResourceWithStreamingResponse",
+ "AsyncConnectionsResourceWithStreamingResponse",
+ "LinksResource",
+ "AsyncLinksResource",
+ "LinksResourceWithRawResponse",
+ "AsyncLinksResourceWithRawResponse",
+ "LinksResourceWithStreamingResponse",
+ "AsyncLinksResourceWithStreamingResponse",
+ "V1Resource",
+ "AsyncV1Resource",
+ "V1ResourceWithRawResponse",
+ "AsyncV1ResourceWithRawResponse",
+ "V1ResourceWithStreamingResponse",
+ "AsyncV1ResourceWithStreamingResponse",
+]
diff --git a/src/casedev/resources/agent/v1/agents.py b/src/casedev/resources/connectors/v1/connections.py
similarity index 51%
rename from src/casedev/resources/agent/v1/agents.py
rename to src/casedev/resources/connectors/v1/connections.py
index b2c64567..5799a5ff 100644
--- a/src/casedev/resources/agent/v1/agents.py
+++ b/src/casedev/resources/connectors/v1/connections.py
@@ -2,11 +2,11 @@
from __future__ import annotations
-from typing import Optional
+from typing_extensions import Literal
import httpx
-from ...._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
+from ...._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
from ...._utils import path_template, maybe_transform, async_maybe_transform
from ...._compat import cached_property
from ...._resource import SyncAPIResource, AsyncAPIResource
@@ -17,85 +17,63 @@
async_to_streamed_response_wrapper,
)
from ...._base_client import make_request_options
-from ....types.agent.v1 import agent_list_params, agent_create_params, agent_update_params
-from ....types.agent.v1.agent_list_response import AgentListResponse
-from ....types.agent.v1.agent_create_response import AgentCreateResponse
-from ....types.agent.v1.agent_delete_response import AgentDeleteResponse
-from ....types.agent.v1.agent_update_response import AgentUpdateResponse
-from ....types.agent.v1.agent_retrieve_response import AgentRetrieveResponse
+from ....types.connectors.v1 import (
+ connection_list_params,
+ connection_browse_params,
+ connection_create_params,
+ connection_delete_params,
+)
+from ....types.connectors.v1.connection_list_response import ConnectionListResponse
+from ....types.connectors.v1.connection_browse_response import ConnectionBrowseResponse
+from ....types.connectors.v1.connection_create_response import ConnectionCreateResponse
-__all__ = ["AgentsResource", "AsyncAgentsResource"]
+__all__ = ["ConnectionsResource", "AsyncConnectionsResource"]
-class AgentsResource(SyncAPIResource):
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
+class ConnectionsResource(SyncAPIResource):
+ """Import and export between provider folders (Google Drive) and vaults"""
@cached_property
- def with_raw_response(self) -> AgentsResourceWithRawResponse:
+ def with_raw_response(self) -> ConnectionsResourceWithRawResponse:
"""
This property can be used as a prefix for any HTTP method call to return
the raw response object instead of the parsed content.
For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
"""
- return AgentsResourceWithRawResponse(self)
+ return ConnectionsResourceWithRawResponse(self)
@cached_property
- def with_streaming_response(self) -> AgentsResourceWithStreamingResponse:
+ def with_streaming_response(self) -> ConnectionsResourceWithStreamingResponse:
"""
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
"""
- return AgentsResourceWithStreamingResponse(self)
+ return ConnectionsResourceWithStreamingResponse(self)
def create(
self,
*,
- instructions: str,
- name: str,
- description: str | Omit = omit,
- disabled_tools: Optional[SequenceNotStr[str]] | Omit = omit,
- enabled_tools: Optional[SequenceNotStr[str]] | Omit = omit,
- model: str | Omit = omit,
- sandbox: Optional[agent_create_params.Sandbox] | Omit = omit,
- vault_groups: Optional[SequenceNotStr[str]] | Omit = omit,
- vault_ids: Optional[SequenceNotStr[str]] | Omit = omit,
+ provider: Literal["clio", "gdrive", "microsoft"],
+ return_url: str,
+ scope_tier: Literal["clio.us", "drive", "microsoft.read"] | 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,
- ) -> AgentCreateResponse:
- """Creates a new agent definition with a scoped API key.
-
- The agent can then be used
- to create and execute runs.
+ ) -> ConnectionCreateResponse:
+ """
+ Create a pending provider connection and return a one-time connect_url for the
+ hosted OAuth flow. The user completes provider consent at connect_url and is
+ redirected to return_url with ?connection_id=.
Args:
- instructions: System instructions that define agent behavior
-
- name: Display name for the agent
-
- description: Optional description of the agent
-
- disabled_tools: Denylist of tools the agent cannot use. Mutually exclusive with enabledTools —
- set one or the other, not both.
-
- enabled_tools: Allowlist of tools the agent can use. Mutually exclusive with disabledTools —
- set one or the other, not both.
-
- model: LLM model identifier (e.g. anthropic/claude-sonnet-4.6). Defaults to
- anthropic/claude-sonnet-4.6
-
- sandbox: Custom sandbox configuration (cpu, memoryMiB)
-
- vault_groups: Restrict agent to vaults within specific vault group IDs
+ return_url: HTTPS URL the user is sent back to after consent.
- vault_ids: Restrict agent to specific vault IDs
+ scope_tier: Provider-specific OAuth permission tier. Omit to use the provider's default.
extra_headers: Send extra headers
@@ -106,25 +84,19 @@ def create(
timeout: Override the client-level default timeout for this request, in seconds
"""
return self._post(
- "/agent/v1/agents",
+ "/connectors/v1/connections",
body=maybe_transform(
{
- "instructions": instructions,
- "name": name,
- "description": description,
- "disabled_tools": disabled_tools,
- "enabled_tools": enabled_tools,
- "model": model,
- "sandbox": sandbox,
- "vault_groups": vault_groups,
- "vault_ids": vault_ids,
+ "provider": provider,
+ "return_url": return_url,
+ "scope_tier": scope_tier,
},
- agent_create_params.AgentCreateParams,
+ connection_create_params.ConnectionCreateParams,
),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=AgentCreateResponse,
+ cast_to=ConnectionCreateResponse,
)
def retrieve(
@@ -137,9 +109,9 @@ def retrieve(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AgentRetrieveResponse:
+ ) -> None:
"""
- Retrieves a single agent definition by ID.
+ Retrieve one provider connection, including account identity and health.
Args:
extra_headers: Send extra headers
@@ -152,59 +124,31 @@ def retrieve(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._get(
- path_template("/agent/v1/agents/{id}", id=id),
+ path_template("/connectors/v1/connections/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=AgentRetrieveResponse,
+ cast_to=NoneType,
)
- def update(
+ def list(
self,
- id: str,
*,
- description: Optional[str] | Omit = omit,
- disabled_tools: Optional[SequenceNotStr[str]] | Omit = omit,
- enabled_tools: Optional[SequenceNotStr[str]] | Omit = omit,
- instructions: str | Omit = omit,
- model: str | Omit = omit,
- name: str | Omit = omit,
- sandbox: Optional[object] | Omit = omit,
- vault_groups: Optional[SequenceNotStr[str]] | Omit = omit,
- vault_ids: Optional[SequenceNotStr[str]] | Omit = omit,
+ provider: str | Omit = omit,
+ status: Literal["pending", "healthy", "reauth_required", "revoked", "throttled"] | 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,
- ) -> AgentUpdateResponse:
- """Updates an agent definition.
-
- Only provided fields are changed.
+ ) -> ConnectionListResponse:
+ """
+ List provider connections for the organization, with health status.
Args:
- description: Updated agent description. Pass null to clear if supported by the client.
-
- disabled_tools: Denylist of tools the agent cannot use. Mutually exclusive with enabledTools —
- set one or the other, not both. Pass null to clear.
-
- enabled_tools: Allowlist of tools the agent can use. Mutually exclusive with disabledTools —
- set one or the other, not both. Pass null to clear.
-
- instructions: Updated system instructions that guide agent behavior
-
- model: Model identifier the agent should use for future runs
-
- name: Updated agent display name
-
- sandbox: Sandbox configuration override for future agent runs. Pass null to clear.
-
- vault_groups: Vault group IDs the agent can access. Pass null to clear.
-
- vault_ids: Vault IDs the agent can access directly. Pass null to clear.
-
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -213,51 +157,41 @@ def update(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not id:
- raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return self._patch(
- path_template("/agent/v1/agents/{id}", id=id),
- body=maybe_transform(
- {
- "description": description,
- "disabled_tools": disabled_tools,
- "enabled_tools": enabled_tools,
- "instructions": instructions,
- "model": model,
- "name": name,
- "sandbox": sandbox,
- "vault_groups": vault_groups,
- "vault_ids": vault_ids,
- },
- agent_update_params.AgentUpdateParams,
- ),
+ return self._get(
+ "/connectors/v1/connections",
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "provider": provider,
+ "status": status,
+ },
+ connection_list_params.ConnectionListParams,
+ ),
),
- cast_to=AgentUpdateResponse,
+ cast_to=ConnectionListResponse,
)
- def list(
+ def delete(
self,
+ id: str,
*,
- cursor: str | Omit = omit,
- limit: int | Omit = omit,
+ purge: bool | 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,
- ) -> AgentListResponse:
+ ) -> None:
"""
- Lists all active agents for the authenticated organization.
+ Unlink a provider account: revoke tokens at the provider and delete them.
+ purge=true additionally deletes the vault documents its import links brought in.
Args:
- cursor: Pagination cursor (agent ID from previous page). Returns agents created before
- this agent.
-
- limit: Maximum number of agents to return (default 50, max 250)
-
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -266,39 +200,54 @@ def list(
timeout: Override the client-level default timeout for this request, in seconds
"""
- return self._get(
- "/agent/v1/agents",
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._delete(
+ path_template("/connectors/v1/connections/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
- query=maybe_transform(
- {
- "cursor": cursor,
- "limit": limit,
- },
- agent_list_params.AgentListParams,
- ),
+ query=maybe_transform({"purge": purge}, connection_delete_params.ConnectionDeleteParams),
),
- cast_to=AgentListResponse,
+ cast_to=NoneType,
)
- def delete(
+ def browse(
self,
id: str,
*,
+ container: str | Omit = omit,
+ cursor: str | Omit = omit,
+ page_size: int | Omit = omit,
+ parent: str | Omit = omit,
+ query: str | Omit = omit,
+ site: 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,
- ) -> AgentDeleteResponse:
- """
- Soft-deletes an agent and revokes its scoped API key.
+ ) -> ConnectionBrowseResponse:
+ """Browse the provider one level at a time.
+
+ Without a site, container, or parent,
+ returns top-level resources. Pass the stable browse_ref fields returned by one
+ response to navigate into the next level. Returns 403
+ provider_scope_insufficient when the connection scope cannot browse server-side.
Args:
+ container: Container id to list, or the container containing parent
+
+ parent: Folder id to list
+
+ query: Optional provider-supported search text
+
+ site: Site id to list
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -309,84 +258,73 @@ def delete(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return self._delete(
- path_template("/agent/v1/agents/{id}", id=id),
+ return self._get(
+ path_template("/connectors/v1/connections/{id}/browse", id=id),
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "container": container,
+ "cursor": cursor,
+ "page_size": page_size,
+ "parent": parent,
+ "query": query,
+ "site": site,
+ },
+ connection_browse_params.ConnectionBrowseParams,
+ ),
),
- cast_to=AgentDeleteResponse,
+ cast_to=ConnectionBrowseResponse,
)
-class AsyncAgentsResource(AsyncAPIResource):
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
+class AsyncConnectionsResource(AsyncAPIResource):
+ """Import and export between provider folders (Google Drive) and vaults"""
@cached_property
- def with_raw_response(self) -> AsyncAgentsResourceWithRawResponse:
+ def with_raw_response(self) -> AsyncConnectionsResourceWithRawResponse:
"""
This property can be used as a prefix for any HTTP method call to return
the raw response object instead of the parsed content.
For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
"""
- return AsyncAgentsResourceWithRawResponse(self)
+ return AsyncConnectionsResourceWithRawResponse(self)
@cached_property
- def with_streaming_response(self) -> AsyncAgentsResourceWithStreamingResponse:
+ def with_streaming_response(self) -> AsyncConnectionsResourceWithStreamingResponse:
"""
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
"""
- return AsyncAgentsResourceWithStreamingResponse(self)
+ return AsyncConnectionsResourceWithStreamingResponse(self)
async def create(
self,
*,
- instructions: str,
- name: str,
- description: str | Omit = omit,
- disabled_tools: Optional[SequenceNotStr[str]] | Omit = omit,
- enabled_tools: Optional[SequenceNotStr[str]] | Omit = omit,
- model: str | Omit = omit,
- sandbox: Optional[agent_create_params.Sandbox] | Omit = omit,
- vault_groups: Optional[SequenceNotStr[str]] | Omit = omit,
- vault_ids: Optional[SequenceNotStr[str]] | Omit = omit,
+ provider: Literal["clio", "gdrive", "microsoft"],
+ return_url: str,
+ scope_tier: Literal["clio.us", "drive", "microsoft.read"] | 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,
- ) -> AgentCreateResponse:
- """Creates a new agent definition with a scoped API key.
-
- The agent can then be used
- to create and execute runs.
+ ) -> ConnectionCreateResponse:
+ """
+ Create a pending provider connection and return a one-time connect_url for the
+ hosted OAuth flow. The user completes provider consent at connect_url and is
+ redirected to return_url with ?connection_id=.
Args:
- instructions: System instructions that define agent behavior
-
- name: Display name for the agent
-
- description: Optional description of the agent
+ return_url: HTTPS URL the user is sent back to after consent.
- disabled_tools: Denylist of tools the agent cannot use. Mutually exclusive with enabledTools —
- set one or the other, not both.
-
- enabled_tools: Allowlist of tools the agent can use. Mutually exclusive with disabledTools —
- set one or the other, not both.
-
- model: LLM model identifier (e.g. anthropic/claude-sonnet-4.6). Defaults to
- anthropic/claude-sonnet-4.6
-
- sandbox: Custom sandbox configuration (cpu, memoryMiB)
-
- vault_groups: Restrict agent to vaults within specific vault group IDs
-
- vault_ids: Restrict agent to specific vault IDs
+ scope_tier: Provider-specific OAuth permission tier. Omit to use the provider's default.
extra_headers: Send extra headers
@@ -397,25 +335,19 @@ async def create(
timeout: Override the client-level default timeout for this request, in seconds
"""
return await self._post(
- "/agent/v1/agents",
+ "/connectors/v1/connections",
body=await async_maybe_transform(
{
- "instructions": instructions,
- "name": name,
- "description": description,
- "disabled_tools": disabled_tools,
- "enabled_tools": enabled_tools,
- "model": model,
- "sandbox": sandbox,
- "vault_groups": vault_groups,
- "vault_ids": vault_ids,
+ "provider": provider,
+ "return_url": return_url,
+ "scope_tier": scope_tier,
},
- agent_create_params.AgentCreateParams,
+ connection_create_params.ConnectionCreateParams,
),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=AgentCreateResponse,
+ cast_to=ConnectionCreateResponse,
)
async def retrieve(
@@ -428,9 +360,9 @@ async def retrieve(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AgentRetrieveResponse:
+ ) -> None:
"""
- Retrieves a single agent definition by ID.
+ Retrieve one provider connection, including account identity and health.
Args:
extra_headers: Send extra headers
@@ -443,59 +375,31 @@ async def retrieve(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._get(
- path_template("/agent/v1/agents/{id}", id=id),
+ path_template("/connectors/v1/connections/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=AgentRetrieveResponse,
+ cast_to=NoneType,
)
- async def update(
+ async def list(
self,
- id: str,
*,
- description: Optional[str] | Omit = omit,
- disabled_tools: Optional[SequenceNotStr[str]] | Omit = omit,
- enabled_tools: Optional[SequenceNotStr[str]] | Omit = omit,
- instructions: str | Omit = omit,
- model: str | Omit = omit,
- name: str | Omit = omit,
- sandbox: Optional[object] | Omit = omit,
- vault_groups: Optional[SequenceNotStr[str]] | Omit = omit,
- vault_ids: Optional[SequenceNotStr[str]] | Omit = omit,
+ provider: str | Omit = omit,
+ status: Literal["pending", "healthy", "reauth_required", "revoked", "throttled"] | 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,
- ) -> AgentUpdateResponse:
- """Updates an agent definition.
-
- Only provided fields are changed.
+ ) -> ConnectionListResponse:
+ """
+ List provider connections for the organization, with health status.
Args:
- description: Updated agent description. Pass null to clear if supported by the client.
-
- disabled_tools: Denylist of tools the agent cannot use. Mutually exclusive with enabledTools —
- set one or the other, not both. Pass null to clear.
-
- enabled_tools: Allowlist of tools the agent can use. Mutually exclusive with disabledTools —
- set one or the other, not both. Pass null to clear.
-
- instructions: Updated system instructions that guide agent behavior
-
- model: Model identifier the agent should use for future runs
-
- name: Updated agent display name
-
- sandbox: Sandbox configuration override for future agent runs. Pass null to clear.
-
- vault_groups: Vault group IDs the agent can access. Pass null to clear.
-
- vault_ids: Vault IDs the agent can access directly. Pass null to clear.
-
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -504,51 +408,41 @@ async def update(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not id:
- raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return await self._patch(
- path_template("/agent/v1/agents/{id}", id=id),
- body=await async_maybe_transform(
- {
- "description": description,
- "disabled_tools": disabled_tools,
- "enabled_tools": enabled_tools,
- "instructions": instructions,
- "model": model,
- "name": name,
- "sandbox": sandbox,
- "vault_groups": vault_groups,
- "vault_ids": vault_ids,
- },
- agent_update_params.AgentUpdateParams,
- ),
+ return await self._get(
+ "/connectors/v1/connections",
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "provider": provider,
+ "status": status,
+ },
+ connection_list_params.ConnectionListParams,
+ ),
),
- cast_to=AgentUpdateResponse,
+ cast_to=ConnectionListResponse,
)
- async def list(
+ async def delete(
self,
+ id: str,
*,
- cursor: str | Omit = omit,
- limit: int | Omit = omit,
+ purge: bool | 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,
- ) -> AgentListResponse:
+ ) -> None:
"""
- Lists all active agents for the authenticated organization.
+ Unlink a provider account: revoke tokens at the provider and delete them.
+ purge=true additionally deletes the vault documents its import links brought in.
Args:
- cursor: Pagination cursor (agent ID from previous page). Returns agents created before
- this agent.
-
- limit: Maximum number of agents to return (default 50, max 250)
-
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -557,39 +451,54 @@ async def list(
timeout: Override the client-level default timeout for this request, in seconds
"""
- return await self._get(
- "/agent/v1/agents",
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._delete(
+ path_template("/connectors/v1/connections/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
- query=await async_maybe_transform(
- {
- "cursor": cursor,
- "limit": limit,
- },
- agent_list_params.AgentListParams,
- ),
+ query=await async_maybe_transform({"purge": purge}, connection_delete_params.ConnectionDeleteParams),
),
- cast_to=AgentListResponse,
+ cast_to=NoneType,
)
- async def delete(
+ async def browse(
self,
id: str,
*,
+ container: str | Omit = omit,
+ cursor: str | Omit = omit,
+ page_size: int | Omit = omit,
+ parent: str | Omit = omit,
+ query: str | Omit = omit,
+ site: 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,
- ) -> AgentDeleteResponse:
- """
- Soft-deletes an agent and revokes its scoped API key.
+ ) -> ConnectionBrowseResponse:
+ """Browse the provider one level at a time.
+
+ Without a site, container, or parent,
+ returns top-level resources. Pass the stable browse_ref fields returned by one
+ response to navigate into the next level. Returns 403
+ provider_scope_insufficient when the connection scope cannot browse server-side.
Args:
+ container: Container id to list, or the container containing parent
+
+ parent: Folder id to list
+
+ query: Optional provider-supported search text
+
+ site: Site id to list
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -600,94 +509,108 @@ async def delete(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return await self._delete(
- path_template("/agent/v1/agents/{id}", id=id),
+ return await self._get(
+ path_template("/connectors/v1/connections/{id}/browse", id=id),
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "container": container,
+ "cursor": cursor,
+ "page_size": page_size,
+ "parent": parent,
+ "query": query,
+ "site": site,
+ },
+ connection_browse_params.ConnectionBrowseParams,
+ ),
),
- cast_to=AgentDeleteResponse,
+ cast_to=ConnectionBrowseResponse,
)
-class AgentsResourceWithRawResponse:
- def __init__(self, agents: AgentsResource) -> None:
- self._agents = agents
+class ConnectionsResourceWithRawResponse:
+ def __init__(self, connections: ConnectionsResource) -> None:
+ self._connections = connections
self.create = to_raw_response_wrapper(
- agents.create,
+ connections.create,
)
self.retrieve = to_raw_response_wrapper(
- agents.retrieve,
- )
- self.update = to_raw_response_wrapper(
- agents.update,
+ connections.retrieve,
)
self.list = to_raw_response_wrapper(
- agents.list,
+ connections.list,
)
self.delete = to_raw_response_wrapper(
- agents.delete,
+ connections.delete,
+ )
+ self.browse = to_raw_response_wrapper(
+ connections.browse,
)
-class AsyncAgentsResourceWithRawResponse:
- def __init__(self, agents: AsyncAgentsResource) -> None:
- self._agents = agents
+class AsyncConnectionsResourceWithRawResponse:
+ def __init__(self, connections: AsyncConnectionsResource) -> None:
+ self._connections = connections
self.create = async_to_raw_response_wrapper(
- agents.create,
+ connections.create,
)
self.retrieve = async_to_raw_response_wrapper(
- agents.retrieve,
- )
- self.update = async_to_raw_response_wrapper(
- agents.update,
+ connections.retrieve,
)
self.list = async_to_raw_response_wrapper(
- agents.list,
+ connections.list,
)
self.delete = async_to_raw_response_wrapper(
- agents.delete,
+ connections.delete,
+ )
+ self.browse = async_to_raw_response_wrapper(
+ connections.browse,
)
-class AgentsResourceWithStreamingResponse:
- def __init__(self, agents: AgentsResource) -> None:
- self._agents = agents
+class ConnectionsResourceWithStreamingResponse:
+ def __init__(self, connections: ConnectionsResource) -> None:
+ self._connections = connections
self.create = to_streamed_response_wrapper(
- agents.create,
+ connections.create,
)
self.retrieve = to_streamed_response_wrapper(
- agents.retrieve,
- )
- self.update = to_streamed_response_wrapper(
- agents.update,
+ connections.retrieve,
)
self.list = to_streamed_response_wrapper(
- agents.list,
+ connections.list,
)
self.delete = to_streamed_response_wrapper(
- agents.delete,
+ connections.delete,
+ )
+ self.browse = to_streamed_response_wrapper(
+ connections.browse,
)
-class AsyncAgentsResourceWithStreamingResponse:
- def __init__(self, agents: AsyncAgentsResource) -> None:
- self._agents = agents
+class AsyncConnectionsResourceWithStreamingResponse:
+ def __init__(self, connections: AsyncConnectionsResource) -> None:
+ self._connections = connections
self.create = async_to_streamed_response_wrapper(
- agents.create,
+ connections.create,
)
self.retrieve = async_to_streamed_response_wrapper(
- agents.retrieve,
- )
- self.update = async_to_streamed_response_wrapper(
- agents.update,
+ connections.retrieve,
)
self.list = async_to_streamed_response_wrapper(
- agents.list,
+ connections.list,
)
self.delete = async_to_streamed_response_wrapper(
- agents.delete,
+ connections.delete,
+ )
+ self.browse = async_to_streamed_response_wrapper(
+ connections.browse,
)
diff --git a/src/casedev/resources/connectors/v1/installations/__init__.py b/src/casedev/resources/connectors/v1/installations/__init__.py
new file mode 100644
index 00000000..5a4ab57a
--- /dev/null
+++ b/src/casedev/resources/connectors/v1/installations/__init__.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .vaults import (
+ VaultsResource,
+ AsyncVaultsResource,
+ VaultsResourceWithRawResponse,
+ AsyncVaultsResourceWithRawResponse,
+ VaultsResourceWithStreamingResponse,
+ AsyncVaultsResourceWithStreamingResponse,
+)
+from .installations import (
+ InstallationsResource,
+ AsyncInstallationsResource,
+ InstallationsResourceWithRawResponse,
+ AsyncInstallationsResourceWithRawResponse,
+ InstallationsResourceWithStreamingResponse,
+ AsyncInstallationsResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "VaultsResource",
+ "AsyncVaultsResource",
+ "VaultsResourceWithRawResponse",
+ "AsyncVaultsResourceWithRawResponse",
+ "VaultsResourceWithStreamingResponse",
+ "AsyncVaultsResourceWithStreamingResponse",
+ "InstallationsResource",
+ "AsyncInstallationsResource",
+ "InstallationsResourceWithRawResponse",
+ "AsyncInstallationsResourceWithRawResponse",
+ "InstallationsResourceWithStreamingResponse",
+ "AsyncInstallationsResourceWithStreamingResponse",
+]
diff --git a/src/casedev/resources/connectors/v1/installations/installations.py b/src/casedev/resources/connectors/v1/installations/installations.py
new file mode 100644
index 00000000..e7e51664
--- /dev/null
+++ b/src/casedev/resources/connectors/v1/installations/installations.py
@@ -0,0 +1,330 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from .vaults import (
+ VaultsResource,
+ AsyncVaultsResource,
+ VaultsResourceWithRawResponse,
+ AsyncVaultsResourceWithRawResponse,
+ VaultsResourceWithStreamingResponse,
+ AsyncVaultsResourceWithStreamingResponse,
+)
+from ....._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
+from ....._utils import maybe_transform, async_maybe_transform
+from ....._compat import cached_property
+from ....._resource import SyncAPIResource, AsyncAPIResource
+from ....._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ....._base_client import make_request_options
+from .....types.connectors.v1 import installation_list_params, installation_ensure_params
+
+__all__ = ["InstallationsResource", "AsyncInstallationsResource"]
+
+
+class InstallationsResource(SyncAPIResource):
+ """Import and export between provider folders (Google Drive) and vaults"""
+
+ @cached_property
+ def vaults(self) -> VaultsResource:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return VaultsResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> InstallationsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
+ """
+ return InstallationsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> InstallationsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
+ """
+ return InstallationsResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ *,
+ application: str | Omit = omit,
+ external_tenant_id: 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,
+ ) -> None:
+ """
+ List application installations (tenants) in this organization.
+
+ 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
+ """
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._get(
+ "/connectors/v1/installations",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "application": application,
+ "external_tenant_id": external_tenant_id,
+ },
+ installation_list_params.InstallationListParams,
+ ),
+ ),
+ cast_to=NoneType,
+ )
+
+ def ensure(
+ self,
+ *,
+ application: str,
+ external_tenant_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> None:
+ """
+ Idempotently create (or return) the installation for (application,
+ external_tenant_id) in this organization. Send the returned installation id as
+ X-Case-Installation-Id on connector requests to scope them to this tenant.
+
+ Args:
+ application: Consuming application key (e.g. "p3").
+
+ external_tenant_id: The application's own tenant identifier (e.g. a P3 organization id).
+
+ 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
+ """
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._post(
+ "/connectors/v1/installations",
+ body=maybe_transform(
+ {
+ "application": application,
+ "external_tenant_id": external_tenant_id,
+ },
+ installation_ensure_params.InstallationEnsureParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
+
+class AsyncInstallationsResource(AsyncAPIResource):
+ """Import and export between provider folders (Google Drive) and vaults"""
+
+ @cached_property
+ def vaults(self) -> AsyncVaultsResource:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return AsyncVaultsResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncInstallationsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncInstallationsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncInstallationsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
+ """
+ return AsyncInstallationsResourceWithStreamingResponse(self)
+
+ async def list(
+ self,
+ *,
+ application: str | Omit = omit,
+ external_tenant_id: 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,
+ ) -> None:
+ """
+ List application installations (tenants) in this organization.
+
+ 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
+ """
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._get(
+ "/connectors/v1/installations",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "application": application,
+ "external_tenant_id": external_tenant_id,
+ },
+ installation_list_params.InstallationListParams,
+ ),
+ ),
+ cast_to=NoneType,
+ )
+
+ async def ensure(
+ self,
+ *,
+ application: str,
+ external_tenant_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> None:
+ """
+ Idempotently create (or return) the installation for (application,
+ external_tenant_id) in this organization. Send the returned installation id as
+ X-Case-Installation-Id on connector requests to scope them to this tenant.
+
+ Args:
+ application: Consuming application key (e.g. "p3").
+
+ external_tenant_id: The application's own tenant identifier (e.g. a P3 organization id).
+
+ 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
+ """
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._post(
+ "/connectors/v1/installations",
+ body=await async_maybe_transform(
+ {
+ "application": application,
+ "external_tenant_id": external_tenant_id,
+ },
+ installation_ensure_params.InstallationEnsureParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
+
+class InstallationsResourceWithRawResponse:
+ def __init__(self, installations: InstallationsResource) -> None:
+ self._installations = installations
+
+ self.list = to_raw_response_wrapper(
+ installations.list,
+ )
+ self.ensure = to_raw_response_wrapper(
+ installations.ensure,
+ )
+
+ @cached_property
+ def vaults(self) -> VaultsResourceWithRawResponse:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return VaultsResourceWithRawResponse(self._installations.vaults)
+
+
+class AsyncInstallationsResourceWithRawResponse:
+ def __init__(self, installations: AsyncInstallationsResource) -> None:
+ self._installations = installations
+
+ self.list = async_to_raw_response_wrapper(
+ installations.list,
+ )
+ self.ensure = async_to_raw_response_wrapper(
+ installations.ensure,
+ )
+
+ @cached_property
+ def vaults(self) -> AsyncVaultsResourceWithRawResponse:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return AsyncVaultsResourceWithRawResponse(self._installations.vaults)
+
+
+class InstallationsResourceWithStreamingResponse:
+ def __init__(self, installations: InstallationsResource) -> None:
+ self._installations = installations
+
+ self.list = to_streamed_response_wrapper(
+ installations.list,
+ )
+ self.ensure = to_streamed_response_wrapper(
+ installations.ensure,
+ )
+
+ @cached_property
+ def vaults(self) -> VaultsResourceWithStreamingResponse:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return VaultsResourceWithStreamingResponse(self._installations.vaults)
+
+
+class AsyncInstallationsResourceWithStreamingResponse:
+ def __init__(self, installations: AsyncInstallationsResource) -> None:
+ self._installations = installations
+
+ self.list = async_to_streamed_response_wrapper(
+ installations.list,
+ )
+ self.ensure = async_to_streamed_response_wrapper(
+ installations.ensure,
+ )
+
+ @cached_property
+ def vaults(self) -> AsyncVaultsResourceWithStreamingResponse:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return AsyncVaultsResourceWithStreamingResponse(self._installations.vaults)
diff --git a/src/casedev/resources/vault/graphrag.py b/src/casedev/resources/connectors/v1/installations/vaults.py
similarity index 53%
rename from src/casedev/resources/vault/graphrag.py
rename to src/casedev/resources/connectors/v1/installations/vaults.py
index 7e214417..eef851eb 100644
--- a/src/casedev/resources/vault/graphrag.py
+++ b/src/casedev/resources/connectors/v1/installations/vaults.py
@@ -2,49 +2,49 @@
from __future__ import annotations
+from typing_extensions import Literal
+
import httpx
-from ..._types import Body, Query, Headers, NotGiven, not_given
-from ..._utils import path_template
-from ..._compat import cached_property
-from ..._resource import SyncAPIResource, AsyncAPIResource
-from ..._response import (
+from ....._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
+from ....._utils import path_template, maybe_transform, async_maybe_transform
+from ....._compat import cached_property
+from ....._resource import SyncAPIResource, AsyncAPIResource
+from ....._response import (
to_raw_response_wrapper,
to_streamed_response_wrapper,
async_to_raw_response_wrapper,
async_to_streamed_response_wrapper,
)
-from ..._base_client import make_request_options
-from ...types.vault.graphrag_init_response import GraphragInitResponse
-from ...types.vault.graphrag_get_stats_response import GraphragGetStatsResponse
-from ...types.vault.graphrag_process_object_response import GraphragProcessObjectResponse
+from ....._base_client import make_request_options
+from .....types.connectors.v1.installations import vault_grant_params
-__all__ = ["GraphragResource", "AsyncGraphragResource"]
+__all__ = ["VaultsResource", "AsyncVaultsResource"]
-class GraphragResource(SyncAPIResource):
- """Secure document storage with semantic search and GraphRAG"""
+class VaultsResource(SyncAPIResource):
+ """Import and export between provider folders (Google Drive) and vaults"""
@cached_property
- def with_raw_response(self) -> GraphragResourceWithRawResponse:
+ def with_raw_response(self) -> VaultsResourceWithRawResponse:
"""
This property can be used as a prefix for any HTTP method call to return
the raw response object instead of the parsed content.
For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
"""
- return GraphragResourceWithRawResponse(self)
+ return VaultsResourceWithRawResponse(self)
@cached_property
- def with_streaming_response(self) -> GraphragResourceWithStreamingResponse:
+ def with_streaming_response(self) -> VaultsResourceWithStreamingResponse:
"""
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
"""
- return GraphragResourceWithStreamingResponse(self)
+ return VaultsResourceWithStreamingResponse(self)
- def get_stats(
+ def list(
self,
id: str,
*,
@@ -54,12 +54,9 @@ def get_stats(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> GraphragGetStatsResponse:
+ ) -> None:
"""
- Retrieve GraphRAG (Graph Retrieval-Augmented Generation) statistics for a
- specific vault. This includes metrics about the knowledge graph structure,
- entity relationships, and processing status that enable advanced semantic search
- and AI-powered document analysis.
+ List the vaults an installation may use, with capabilities and revocation state.
Args:
extra_headers: Send extra headers
@@ -72,30 +69,37 @@ def get_stats(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._get(
- path_template("/vault/{id}/graphrag/stats", id=id),
+ path_template("/connectors/v1/installations/{id}/vaults", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=GraphragGetStatsResponse,
+ cast_to=NoneType,
)
- def init(
+ def grant(
self,
- id: str,
+ vault_id: str,
*,
+ id: str,
+ can_manage: bool | Omit = omit,
+ can_read: bool | Omit = omit,
+ can_write: bool | Omit = omit,
+ relationship: Literal["owned", "shared"] | Omit = omit,
+ source: Literal["provisioning", "lazy_reconcile", "explicit_share"] | 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,
- ) -> GraphragInitResponse:
- """
- Initialize a GraphRAG workspace for a vault to enable advanced knowledge graph
- and retrieval-augmented generation capabilities. This creates the necessary
- infrastructure for semantic document analysis and graph-based querying within
- the vault.
+ ) -> None:
+ """Grant (or update) an installation's access to a vault.
+
+ Re-granting a revoked
+ vault reactivates it. Import links need can_write; export links need can_read;
+ mirror deletion and purge need can_manage.
Args:
extra_headers: Send extra headers
@@ -108,17 +112,30 @@ def init(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return self._post(
- path_template("/vault/{id}/graphrag/init", id=id),
+ if not vault_id:
+ raise ValueError(f"Expected a non-empty value for `vault_id` but received {vault_id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._put(
+ path_template("/connectors/v1/installations/{id}/vaults/{vault_id}", id=id, vault_id=vault_id),
+ body=maybe_transform(
+ {
+ "can_manage": can_manage,
+ "can_read": can_read,
+ "can_write": can_write,
+ "relationship": relationship,
+ "source": source,
+ },
+ vault_grant_params.VaultGrantParams,
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=GraphragInitResponse,
+ cast_to=NoneType,
)
- def process_object(
+ def revoke(
self,
- object_id: str,
+ vault_id: str,
*,
id: str,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -127,12 +144,11 @@ def process_object(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> GraphragProcessObjectResponse:
- """Manually trigger GraphRAG indexing for a vault object.
+ ) -> None:
+ """Revoke an installation's access to a vault.
- The object must already
- be ingested (completed status). This extracts entities, relationships, and
- communities from the document for advanced knowledge graph queries.
+ Links using the vault pause at their
+ next run; nothing is deleted.
Args:
extra_headers: Send extra headers
@@ -145,40 +161,41 @@ def process_object(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- if not object_id:
- raise ValueError(f"Expected a non-empty value for `object_id` but received {object_id!r}")
- return self._post(
- path_template("/vault/{id}/graphrag/{object_id}", id=id, object_id=object_id),
+ if not vault_id:
+ raise ValueError(f"Expected a non-empty value for `vault_id` but received {vault_id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._delete(
+ path_template("/connectors/v1/installations/{id}/vaults/{vault_id}", id=id, vault_id=vault_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=GraphragProcessObjectResponse,
+ cast_to=NoneType,
)
-class AsyncGraphragResource(AsyncAPIResource):
- """Secure document storage with semantic search and GraphRAG"""
+class AsyncVaultsResource(AsyncAPIResource):
+ """Import and export between provider folders (Google Drive) and vaults"""
@cached_property
- def with_raw_response(self) -> AsyncGraphragResourceWithRawResponse:
+ def with_raw_response(self) -> AsyncVaultsResourceWithRawResponse:
"""
This property can be used as a prefix for any HTTP method call to return
the raw response object instead of the parsed content.
For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
"""
- return AsyncGraphragResourceWithRawResponse(self)
+ return AsyncVaultsResourceWithRawResponse(self)
@cached_property
- def with_streaming_response(self) -> AsyncGraphragResourceWithStreamingResponse:
+ def with_streaming_response(self) -> AsyncVaultsResourceWithStreamingResponse:
"""
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
"""
- return AsyncGraphragResourceWithStreamingResponse(self)
+ return AsyncVaultsResourceWithStreamingResponse(self)
- async def get_stats(
+ async def list(
self,
id: str,
*,
@@ -188,12 +205,9 @@ async def get_stats(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> GraphragGetStatsResponse:
+ ) -> None:
"""
- Retrieve GraphRAG (Graph Retrieval-Augmented Generation) statistics for a
- specific vault. This includes metrics about the knowledge graph structure,
- entity relationships, and processing status that enable advanced semantic search
- and AI-powered document analysis.
+ List the vaults an installation may use, with capabilities and revocation state.
Args:
extra_headers: Send extra headers
@@ -206,30 +220,37 @@ async def get_stats(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._get(
- path_template("/vault/{id}/graphrag/stats", id=id),
+ path_template("/connectors/v1/installations/{id}/vaults", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=GraphragGetStatsResponse,
+ cast_to=NoneType,
)
- async def init(
+ async def grant(
self,
- id: str,
+ vault_id: str,
*,
+ id: str,
+ can_manage: bool | Omit = omit,
+ can_read: bool | Omit = omit,
+ can_write: bool | Omit = omit,
+ relationship: Literal["owned", "shared"] | Omit = omit,
+ source: Literal["provisioning", "lazy_reconcile", "explicit_share"] | 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,
- ) -> GraphragInitResponse:
- """
- Initialize a GraphRAG workspace for a vault to enable advanced knowledge graph
- and retrieval-augmented generation capabilities. This creates the necessary
- infrastructure for semantic document analysis and graph-based querying within
- the vault.
+ ) -> None:
+ """Grant (or update) an installation's access to a vault.
+
+ Re-granting a revoked
+ vault reactivates it. Import links need can_write; export links need can_read;
+ mirror deletion and purge need can_manage.
Args:
extra_headers: Send extra headers
@@ -242,17 +263,30 @@ async def init(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return await self._post(
- path_template("/vault/{id}/graphrag/init", id=id),
+ if not vault_id:
+ raise ValueError(f"Expected a non-empty value for `vault_id` but received {vault_id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._put(
+ path_template("/connectors/v1/installations/{id}/vaults/{vault_id}", id=id, vault_id=vault_id),
+ body=await async_maybe_transform(
+ {
+ "can_manage": can_manage,
+ "can_read": can_read,
+ "can_write": can_write,
+ "relationship": relationship,
+ "source": source,
+ },
+ vault_grant_params.VaultGrantParams,
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=GraphragInitResponse,
+ cast_to=NoneType,
)
- async def process_object(
+ async def revoke(
self,
- object_id: str,
+ vault_id: str,
*,
id: str,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -261,12 +295,11 @@ async def process_object(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> GraphragProcessObjectResponse:
- """Manually trigger GraphRAG indexing for a vault object.
+ ) -> None:
+ """Revoke an installation's access to a vault.
- The object must already
- be ingested (completed status). This extracts entities, relationships, and
- communities from the document for advanced knowledge graph queries.
+ Links using the vault pause at their
+ next run; nothing is deleted.
Args:
extra_headers: Send extra headers
@@ -279,72 +312,73 @@ async def process_object(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- if not object_id:
- raise ValueError(f"Expected a non-empty value for `object_id` but received {object_id!r}")
- return await self._post(
- path_template("/vault/{id}/graphrag/{object_id}", id=id, object_id=object_id),
+ if not vault_id:
+ raise ValueError(f"Expected a non-empty value for `vault_id` but received {vault_id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._delete(
+ path_template("/connectors/v1/installations/{id}/vaults/{vault_id}", id=id, vault_id=vault_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=GraphragProcessObjectResponse,
+ cast_to=NoneType,
)
-class GraphragResourceWithRawResponse:
- def __init__(self, graphrag: GraphragResource) -> None:
- self._graphrag = graphrag
+class VaultsResourceWithRawResponse:
+ def __init__(self, vaults: VaultsResource) -> None:
+ self._vaults = vaults
- self.get_stats = to_raw_response_wrapper(
- graphrag.get_stats,
+ self.list = to_raw_response_wrapper(
+ vaults.list,
)
- self.init = to_raw_response_wrapper(
- graphrag.init,
+ self.grant = to_raw_response_wrapper(
+ vaults.grant,
)
- self.process_object = to_raw_response_wrapper(
- graphrag.process_object,
+ self.revoke = to_raw_response_wrapper(
+ vaults.revoke,
)
-class AsyncGraphragResourceWithRawResponse:
- def __init__(self, graphrag: AsyncGraphragResource) -> None:
- self._graphrag = graphrag
+class AsyncVaultsResourceWithRawResponse:
+ def __init__(self, vaults: AsyncVaultsResource) -> None:
+ self._vaults = vaults
- self.get_stats = async_to_raw_response_wrapper(
- graphrag.get_stats,
+ self.list = async_to_raw_response_wrapper(
+ vaults.list,
)
- self.init = async_to_raw_response_wrapper(
- graphrag.init,
+ self.grant = async_to_raw_response_wrapper(
+ vaults.grant,
)
- self.process_object = async_to_raw_response_wrapper(
- graphrag.process_object,
+ self.revoke = async_to_raw_response_wrapper(
+ vaults.revoke,
)
-class GraphragResourceWithStreamingResponse:
- def __init__(self, graphrag: GraphragResource) -> None:
- self._graphrag = graphrag
+class VaultsResourceWithStreamingResponse:
+ def __init__(self, vaults: VaultsResource) -> None:
+ self._vaults = vaults
- self.get_stats = to_streamed_response_wrapper(
- graphrag.get_stats,
+ self.list = to_streamed_response_wrapper(
+ vaults.list,
)
- self.init = to_streamed_response_wrapper(
- graphrag.init,
+ self.grant = to_streamed_response_wrapper(
+ vaults.grant,
)
- self.process_object = to_streamed_response_wrapper(
- graphrag.process_object,
+ self.revoke = to_streamed_response_wrapper(
+ vaults.revoke,
)
-class AsyncGraphragResourceWithStreamingResponse:
- def __init__(self, graphrag: AsyncGraphragResource) -> None:
- self._graphrag = graphrag
+class AsyncVaultsResourceWithStreamingResponse:
+ def __init__(self, vaults: AsyncVaultsResource) -> None:
+ self._vaults = vaults
- self.get_stats = async_to_streamed_response_wrapper(
- graphrag.get_stats,
+ self.list = async_to_streamed_response_wrapper(
+ vaults.list,
)
- self.init = async_to_streamed_response_wrapper(
- graphrag.init,
+ self.grant = async_to_streamed_response_wrapper(
+ vaults.grant,
)
- self.process_object = async_to_streamed_response_wrapper(
- graphrag.process_object,
+ self.revoke = async_to_streamed_response_wrapper(
+ vaults.revoke,
)
diff --git a/src/casedev/resources/connectors/v1/links.py b/src/casedev/resources/connectors/v1/links.py
new file mode 100644
index 00000000..7c93bbb4
--- /dev/null
+++ b/src/casedev/resources/connectors/v1/links.py
@@ -0,0 +1,598 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal
+
+import httpx
+
+from ...._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
+from ...._utils import path_template, maybe_transform, async_maybe_transform
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from ...._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ...._base_client import make_request_options
+from ....types.connectors.v1 import link_list_params, link_delete_params, link_update_params, link_list_objects_params
+
+__all__ = ["LinksResource", "AsyncLinksResource"]
+
+
+class LinksResource(SyncAPIResource):
+ """Import and export between provider folders (Google Drive) and vaults"""
+
+ @cached_property
+ def with_raw_response(self) -> LinksResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
+ """
+ return LinksResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> LinksResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
+ """
+ return LinksResourceWithStreamingResponse(self)
+
+ def retrieve(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> None:
+ """Retrieve one link: state, counts, and embedded active_run/last_run.
+
+ Poll this
+ after POST /transfer.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._get(
+ path_template("/connectors/v1/links/{id}", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
+ def update(
+ self,
+ id: str,
+ *,
+ mode: Literal["once", "synced"] | Omit = omit,
+ policy: object | Omit = omit,
+ state: Literal["paused", "ready"] | 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,
+ ) -> None:
+ """
+ Pause/resume a link (state "paused" | "ready"), change its mode (synced -> once
+ is the sync downgrade), or edit its policy in place.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._patch(
+ path_template("/connectors/v1/links/{id}", id=id),
+ body=maybe_transform(
+ {
+ "mode": mode,
+ "policy": policy,
+ "state": state,
+ },
+ link_update_params.LinkUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
+ def list(
+ self,
+ *,
+ connection_id: str | Omit = omit,
+ direction: Literal["import", "export"] | Omit = omit,
+ mode: Literal["once", "synced"] | Omit = omit,
+ pair_id: str | Omit = omit,
+ state: Literal["ready", "running", "active", "paused", "orphaned", "error"] | Omit = omit,
+ vault_id: 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,
+ ) -> None:
+ """
+ List transfer links, filterable by vault, connection, direction, mode, and
+ state.
+
+ 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
+ """
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._get(
+ "/connectors/v1/links",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "connection_id": connection_id,
+ "direction": direction,
+ "mode": mode,
+ "pair_id": pair_id,
+ "state": state,
+ "vault_id": vault_id,
+ },
+ link_list_params.LinkListParams,
+ ),
+ ),
+ cast_to=NoneType,
+ )
+
+ def delete(
+ self,
+ id: str,
+ *,
+ vault_docs: Literal["keep", "delete"] | 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,
+ ) -> None:
+ """Delete a link and its ledger.
+
+ vault_docs=delete additionally removes the vault
+ documents an import link brought in (default: keep).
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._delete(
+ path_template("/connectors/v1/links/{id}", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform({"vault_docs": vault_docs}, link_delete_params.LinkDeleteParams),
+ ),
+ cast_to=NoneType,
+ )
+
+ def list_objects(
+ self,
+ id: str,
+ *,
+ cursor: str | Omit = omit,
+ state: Literal["pending", "transferring", "ingesting", "synced", "skipped", "failed", "tombstoned"]
+ | 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,
+ ) -> None:
+ """
+ Per-file transfer ledger for a link: provider item, vault object, path, content
+ version, state, and error.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._get(
+ path_template("/connectors/v1/links/{id}/objects", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "cursor": cursor,
+ "state": state,
+ },
+ link_list_objects_params.LinkListObjectsParams,
+ ),
+ ),
+ cast_to=NoneType,
+ )
+
+
+class AsyncLinksResource(AsyncAPIResource):
+ """Import and export between provider folders (Google Drive) and vaults"""
+
+ @cached_property
+ def with_raw_response(self) -> AsyncLinksResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncLinksResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncLinksResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
+ """
+ return AsyncLinksResourceWithStreamingResponse(self)
+
+ async def retrieve(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> None:
+ """Retrieve one link: state, counts, and embedded active_run/last_run.
+
+ Poll this
+ after POST /transfer.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._get(
+ path_template("/connectors/v1/links/{id}", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
+ async def update(
+ self,
+ id: str,
+ *,
+ mode: Literal["once", "synced"] | Omit = omit,
+ policy: object | Omit = omit,
+ state: Literal["paused", "ready"] | 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,
+ ) -> None:
+ """
+ Pause/resume a link (state "paused" | "ready"), change its mode (synced -> once
+ is the sync downgrade), or edit its policy in place.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._patch(
+ path_template("/connectors/v1/links/{id}", id=id),
+ body=await async_maybe_transform(
+ {
+ "mode": mode,
+ "policy": policy,
+ "state": state,
+ },
+ link_update_params.LinkUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
+ async def list(
+ self,
+ *,
+ connection_id: str | Omit = omit,
+ direction: Literal["import", "export"] | Omit = omit,
+ mode: Literal["once", "synced"] | Omit = omit,
+ pair_id: str | Omit = omit,
+ state: Literal["ready", "running", "active", "paused", "orphaned", "error"] | Omit = omit,
+ vault_id: 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,
+ ) -> None:
+ """
+ List transfer links, filterable by vault, connection, direction, mode, and
+ state.
+
+ 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
+ """
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._get(
+ "/connectors/v1/links",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "connection_id": connection_id,
+ "direction": direction,
+ "mode": mode,
+ "pair_id": pair_id,
+ "state": state,
+ "vault_id": vault_id,
+ },
+ link_list_params.LinkListParams,
+ ),
+ ),
+ cast_to=NoneType,
+ )
+
+ async def delete(
+ self,
+ id: str,
+ *,
+ vault_docs: Literal["keep", "delete"] | 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,
+ ) -> None:
+ """Delete a link and its ledger.
+
+ vault_docs=delete additionally removes the vault
+ documents an import link brought in (default: keep).
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._delete(
+ path_template("/connectors/v1/links/{id}", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform({"vault_docs": vault_docs}, link_delete_params.LinkDeleteParams),
+ ),
+ cast_to=NoneType,
+ )
+
+ async def list_objects(
+ self,
+ id: str,
+ *,
+ cursor: str | Omit = omit,
+ state: Literal["pending", "transferring", "ingesting", "synced", "skipped", "failed", "tombstoned"]
+ | 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,
+ ) -> None:
+ """
+ Per-file transfer ledger for a link: provider item, vault object, path, content
+ version, state, and error.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._get(
+ path_template("/connectors/v1/links/{id}/objects", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "cursor": cursor,
+ "state": state,
+ },
+ link_list_objects_params.LinkListObjectsParams,
+ ),
+ ),
+ cast_to=NoneType,
+ )
+
+
+class LinksResourceWithRawResponse:
+ def __init__(self, links: LinksResource) -> None:
+ self._links = links
+
+ self.retrieve = to_raw_response_wrapper(
+ links.retrieve,
+ )
+ self.update = to_raw_response_wrapper(
+ links.update,
+ )
+ self.list = to_raw_response_wrapper(
+ links.list,
+ )
+ self.delete = to_raw_response_wrapper(
+ links.delete,
+ )
+ self.list_objects = to_raw_response_wrapper(
+ links.list_objects,
+ )
+
+
+class AsyncLinksResourceWithRawResponse:
+ def __init__(self, links: AsyncLinksResource) -> None:
+ self._links = links
+
+ self.retrieve = async_to_raw_response_wrapper(
+ links.retrieve,
+ )
+ self.update = async_to_raw_response_wrapper(
+ links.update,
+ )
+ self.list = async_to_raw_response_wrapper(
+ links.list,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ links.delete,
+ )
+ self.list_objects = async_to_raw_response_wrapper(
+ links.list_objects,
+ )
+
+
+class LinksResourceWithStreamingResponse:
+ def __init__(self, links: LinksResource) -> None:
+ self._links = links
+
+ self.retrieve = to_streamed_response_wrapper(
+ links.retrieve,
+ )
+ self.update = to_streamed_response_wrapper(
+ links.update,
+ )
+ self.list = to_streamed_response_wrapper(
+ links.list,
+ )
+ self.delete = to_streamed_response_wrapper(
+ links.delete,
+ )
+ self.list_objects = to_streamed_response_wrapper(
+ links.list_objects,
+ )
+
+
+class AsyncLinksResourceWithStreamingResponse:
+ def __init__(self, links: AsyncLinksResource) -> None:
+ self._links = links
+
+ self.retrieve = async_to_streamed_response_wrapper(
+ links.retrieve,
+ )
+ self.update = async_to_streamed_response_wrapper(
+ links.update,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ links.list,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ links.delete,
+ )
+ self.list_objects = async_to_streamed_response_wrapper(
+ links.list_objects,
+ )
diff --git a/src/casedev/resources/connectors/v1/v1.py b/src/casedev/resources/connectors/v1/v1.py
new file mode 100644
index 00000000..cff90974
--- /dev/null
+++ b/src/casedev/resources/connectors/v1/v1.py
@@ -0,0 +1,439 @@
+# 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 Literal
+
+import httpx
+
+from .links import (
+ LinksResource,
+ AsyncLinksResource,
+ LinksResourceWithRawResponse,
+ AsyncLinksResourceWithRawResponse,
+ LinksResourceWithStreamingResponse,
+ AsyncLinksResourceWithStreamingResponse,
+)
+from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ...._utils import maybe_transform, async_maybe_transform
+from ...._compat import cached_property
+from .connections import (
+ ConnectionsResource,
+ AsyncConnectionsResource,
+ ConnectionsResourceWithRawResponse,
+ AsyncConnectionsResourceWithRawResponse,
+ ConnectionsResourceWithStreamingResponse,
+ AsyncConnectionsResourceWithStreamingResponse,
+)
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from ...._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ...._base_client import make_request_options
+from ....types.connectors import v1_transfer_params, v1_sync_link_params
+from .installations.installations import (
+ InstallationsResource,
+ AsyncInstallationsResource,
+ InstallationsResourceWithRawResponse,
+ AsyncInstallationsResourceWithRawResponse,
+ InstallationsResourceWithStreamingResponse,
+ AsyncInstallationsResourceWithStreamingResponse,
+)
+from ....types.connectors.v1_transfer_response import V1TransferResponse
+from ....types.connectors.v1_sync_link_response import V1SyncLinkResponse
+
+__all__ = ["V1Resource", "AsyncV1Resource"]
+
+
+class V1Resource(SyncAPIResource):
+ """Import and export between provider folders (Google Drive) and vaults"""
+
+ @cached_property
+ def installations(self) -> InstallationsResource:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return InstallationsResource(self._client)
+
+ @cached_property
+ def connections(self) -> ConnectionsResource:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return ConnectionsResource(self._client)
+
+ @cached_property
+ def links(self) -> LinksResource:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return LinksResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> V1ResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
+ """
+ return V1ResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> V1ResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
+ """
+ return V1ResourceWithStreamingResponse(self)
+
+ def sync_link(
+ self,
+ *,
+ connection_id: str,
+ direction: Literal["import", "export"],
+ remote: v1_sync_link_params.Remote,
+ vault_id: str,
+ matter_id: Optional[str] | Omit = omit,
+ policy: v1_sync_link_params.Policy | 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,
+ ) -> V1SyncLinkResponse:
+ """
+ Standing promise: backfill now, then stay current (the sync sweeper re-runs
+ synced links on a schedule). Same body as /transfer minus run_mode. Upserts the
+ link identified by (connection_id, direction, remote, vault_id); an existing
+ once-link is upgraded in place with its ledger and cursor preserved. Downgrade
+ or pause via PATCH /links/{id}.
+
+ 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(
+ "/connectors/v1/sync-link",
+ body=maybe_transform(
+ {
+ "connection_id": connection_id,
+ "direction": direction,
+ "remote": remote,
+ "vault_id": vault_id,
+ "matter_id": matter_id,
+ "policy": policy,
+ },
+ v1_sync_link_params.V1SyncLinkParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=V1SyncLinkResponse,
+ )
+
+ def transfer(
+ self,
+ *,
+ connection_id: str,
+ direction: Literal["import", "export"],
+ remote: v1_transfer_params.Remote,
+ vault_id: str,
+ matter_id: Optional[str] | Omit = omit,
+ policy: v1_transfer_params.Policy | Omit = omit,
+ run_mode: Literal["auto", "full_reconcile"] | 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,
+ ) -> V1TransferResponse:
+ """
+ One-shot import (provider folder → vault) or export (vault → provider folder).
+ Upserts the link identified by (connection_id, direction, remote, vault_id):
+ first call backfills, later calls move only new/changed files via the ledger.
+ Poll GET /links/{id} → active_run for progress.
+
+ 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(
+ "/connectors/v1/transfer",
+ body=maybe_transform(
+ {
+ "connection_id": connection_id,
+ "direction": direction,
+ "remote": remote,
+ "vault_id": vault_id,
+ "matter_id": matter_id,
+ "policy": policy,
+ "run_mode": run_mode,
+ },
+ v1_transfer_params.V1TransferParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=V1TransferResponse,
+ )
+
+
+class AsyncV1Resource(AsyncAPIResource):
+ """Import and export between provider folders (Google Drive) and vaults"""
+
+ @cached_property
+ def installations(self) -> AsyncInstallationsResource:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return AsyncInstallationsResource(self._client)
+
+ @cached_property
+ def connections(self) -> AsyncConnectionsResource:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return AsyncConnectionsResource(self._client)
+
+ @cached_property
+ def links(self) -> AsyncLinksResource:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return AsyncLinksResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncV1ResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncV1ResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncV1ResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
+ """
+ return AsyncV1ResourceWithStreamingResponse(self)
+
+ async def sync_link(
+ self,
+ *,
+ connection_id: str,
+ direction: Literal["import", "export"],
+ remote: v1_sync_link_params.Remote,
+ vault_id: str,
+ matter_id: Optional[str] | Omit = omit,
+ policy: v1_sync_link_params.Policy | 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,
+ ) -> V1SyncLinkResponse:
+ """
+ Standing promise: backfill now, then stay current (the sync sweeper re-runs
+ synced links on a schedule). Same body as /transfer minus run_mode. Upserts the
+ link identified by (connection_id, direction, remote, vault_id); an existing
+ once-link is upgraded in place with its ledger and cursor preserved. Downgrade
+ or pause via PATCH /links/{id}.
+
+ 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(
+ "/connectors/v1/sync-link",
+ body=await async_maybe_transform(
+ {
+ "connection_id": connection_id,
+ "direction": direction,
+ "remote": remote,
+ "vault_id": vault_id,
+ "matter_id": matter_id,
+ "policy": policy,
+ },
+ v1_sync_link_params.V1SyncLinkParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=V1SyncLinkResponse,
+ )
+
+ async def transfer(
+ self,
+ *,
+ connection_id: str,
+ direction: Literal["import", "export"],
+ remote: v1_transfer_params.Remote,
+ vault_id: str,
+ matter_id: Optional[str] | Omit = omit,
+ policy: v1_transfer_params.Policy | Omit = omit,
+ run_mode: Literal["auto", "full_reconcile"] | 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,
+ ) -> V1TransferResponse:
+ """
+ One-shot import (provider folder → vault) or export (vault → provider folder).
+ Upserts the link identified by (connection_id, direction, remote, vault_id):
+ first call backfills, later calls move only new/changed files via the ledger.
+ Poll GET /links/{id} → active_run for progress.
+
+ 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(
+ "/connectors/v1/transfer",
+ body=await async_maybe_transform(
+ {
+ "connection_id": connection_id,
+ "direction": direction,
+ "remote": remote,
+ "vault_id": vault_id,
+ "matter_id": matter_id,
+ "policy": policy,
+ "run_mode": run_mode,
+ },
+ v1_transfer_params.V1TransferParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=V1TransferResponse,
+ )
+
+
+class V1ResourceWithRawResponse:
+ def __init__(self, v1: V1Resource) -> None:
+ self._v1 = v1
+
+ self.sync_link = to_raw_response_wrapper(
+ v1.sync_link,
+ )
+ self.transfer = to_raw_response_wrapper(
+ v1.transfer,
+ )
+
+ @cached_property
+ def installations(self) -> InstallationsResourceWithRawResponse:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return InstallationsResourceWithRawResponse(self._v1.installations)
+
+ @cached_property
+ def connections(self) -> ConnectionsResourceWithRawResponse:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return ConnectionsResourceWithRawResponse(self._v1.connections)
+
+ @cached_property
+ def links(self) -> LinksResourceWithRawResponse:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return LinksResourceWithRawResponse(self._v1.links)
+
+
+class AsyncV1ResourceWithRawResponse:
+ def __init__(self, v1: AsyncV1Resource) -> None:
+ self._v1 = v1
+
+ self.sync_link = async_to_raw_response_wrapper(
+ v1.sync_link,
+ )
+ self.transfer = async_to_raw_response_wrapper(
+ v1.transfer,
+ )
+
+ @cached_property
+ def installations(self) -> AsyncInstallationsResourceWithRawResponse:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return AsyncInstallationsResourceWithRawResponse(self._v1.installations)
+
+ @cached_property
+ def connections(self) -> AsyncConnectionsResourceWithRawResponse:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return AsyncConnectionsResourceWithRawResponse(self._v1.connections)
+
+ @cached_property
+ def links(self) -> AsyncLinksResourceWithRawResponse:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return AsyncLinksResourceWithRawResponse(self._v1.links)
+
+
+class V1ResourceWithStreamingResponse:
+ def __init__(self, v1: V1Resource) -> None:
+ self._v1 = v1
+
+ self.sync_link = to_streamed_response_wrapper(
+ v1.sync_link,
+ )
+ self.transfer = to_streamed_response_wrapper(
+ v1.transfer,
+ )
+
+ @cached_property
+ def installations(self) -> InstallationsResourceWithStreamingResponse:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return InstallationsResourceWithStreamingResponse(self._v1.installations)
+
+ @cached_property
+ def connections(self) -> ConnectionsResourceWithStreamingResponse:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return ConnectionsResourceWithStreamingResponse(self._v1.connections)
+
+ @cached_property
+ def links(self) -> LinksResourceWithStreamingResponse:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return LinksResourceWithStreamingResponse(self._v1.links)
+
+
+class AsyncV1ResourceWithStreamingResponse:
+ def __init__(self, v1: AsyncV1Resource) -> None:
+ self._v1 = v1
+
+ self.sync_link = async_to_streamed_response_wrapper(
+ v1.sync_link,
+ )
+ self.transfer = async_to_streamed_response_wrapper(
+ v1.transfer,
+ )
+
+ @cached_property
+ def installations(self) -> AsyncInstallationsResourceWithStreamingResponse:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return AsyncInstallationsResourceWithStreamingResponse(self._v1.installations)
+
+ @cached_property
+ def connections(self) -> AsyncConnectionsResourceWithStreamingResponse:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return AsyncConnectionsResourceWithStreamingResponse(self._v1.connections)
+
+ @cached_property
+ def links(self) -> AsyncLinksResourceWithStreamingResponse:
+ """Import and export between provider folders (Google Drive) and vaults"""
+ return AsyncLinksResourceWithStreamingResponse(self._v1.links)
diff --git a/src/casedev/resources/database/database.py b/src/casedev/resources/database/database.py
deleted file mode 100644
index 7c1f0e2f..00000000
--- a/src/casedev/resources/database/database.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from .v1.v1 import (
- V1Resource,
- AsyncV1Resource,
- V1ResourceWithRawResponse,
- AsyncV1ResourceWithRawResponse,
- V1ResourceWithStreamingResponse,
- AsyncV1ResourceWithStreamingResponse,
-)
-from ..._compat import cached_property
-from ..._resource import SyncAPIResource, AsyncAPIResource
-
-__all__ = ["DatabaseResource", "AsyncDatabaseResource"]
-
-
-class DatabaseResource(SyncAPIResource):
- @cached_property
- def v1(self) -> V1Resource:
- """Serverless PostgreSQL databases with instant branching"""
- return V1Resource(self._client)
-
- @cached_property
- def with_raw_response(self) -> DatabaseResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
- """
- return DatabaseResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> DatabaseResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
- """
- return DatabaseResourceWithStreamingResponse(self)
-
-
-class AsyncDatabaseResource(AsyncAPIResource):
- @cached_property
- def v1(self) -> AsyncV1Resource:
- """Serverless PostgreSQL databases with instant branching"""
- return AsyncV1Resource(self._client)
-
- @cached_property
- def with_raw_response(self) -> AsyncDatabaseResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
- """
- return AsyncDatabaseResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncDatabaseResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
- """
- return AsyncDatabaseResourceWithStreamingResponse(self)
-
-
-class DatabaseResourceWithRawResponse:
- def __init__(self, database: DatabaseResource) -> None:
- self._database = database
-
- @cached_property
- def v1(self) -> V1ResourceWithRawResponse:
- """Serverless PostgreSQL databases with instant branching"""
- return V1ResourceWithRawResponse(self._database.v1)
-
-
-class AsyncDatabaseResourceWithRawResponse:
- def __init__(self, database: AsyncDatabaseResource) -> None:
- self._database = database
-
- @cached_property
- def v1(self) -> AsyncV1ResourceWithRawResponse:
- """Serverless PostgreSQL databases with instant branching"""
- return AsyncV1ResourceWithRawResponse(self._database.v1)
-
-
-class DatabaseResourceWithStreamingResponse:
- def __init__(self, database: DatabaseResource) -> None:
- self._database = database
-
- @cached_property
- def v1(self) -> V1ResourceWithStreamingResponse:
- """Serverless PostgreSQL databases with instant branching"""
- return V1ResourceWithStreamingResponse(self._database.v1)
-
-
-class AsyncDatabaseResourceWithStreamingResponse:
- def __init__(self, database: AsyncDatabaseResource) -> None:
- self._database = database
-
- @cached_property
- def v1(self) -> AsyncV1ResourceWithStreamingResponse:
- """Serverless PostgreSQL databases with instant branching"""
- return AsyncV1ResourceWithStreamingResponse(self._database.v1)
diff --git a/src/casedev/resources/database/v1/__init__.py b/src/casedev/resources/database/v1/__init__.py
deleted file mode 100644
index 56e28d44..00000000
--- a/src/casedev/resources/database/v1/__init__.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from .v1 import (
- V1Resource,
- AsyncV1Resource,
- V1ResourceWithRawResponse,
- AsyncV1ResourceWithRawResponse,
- V1ResourceWithStreamingResponse,
- AsyncV1ResourceWithStreamingResponse,
-)
-from .projects import (
- ProjectsResource,
- AsyncProjectsResource,
- ProjectsResourceWithRawResponse,
- AsyncProjectsResourceWithRawResponse,
- ProjectsResourceWithStreamingResponse,
- AsyncProjectsResourceWithStreamingResponse,
-)
-
-__all__ = [
- "ProjectsResource",
- "AsyncProjectsResource",
- "ProjectsResourceWithRawResponse",
- "AsyncProjectsResourceWithRawResponse",
- "ProjectsResourceWithStreamingResponse",
- "AsyncProjectsResourceWithStreamingResponse",
- "V1Resource",
- "AsyncV1Resource",
- "V1ResourceWithRawResponse",
- "AsyncV1ResourceWithRawResponse",
- "V1ResourceWithStreamingResponse",
- "AsyncV1ResourceWithStreamingResponse",
-]
diff --git a/src/casedev/resources/database/v1/projects.py b/src/casedev/resources/database/v1/projects.py
deleted file mode 100644
index 8b33fa40..00000000
--- a/src/casedev/resources/database/v1/projects.py
+++ /dev/null
@@ -1,775 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal
-
-import httpx
-
-from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ...._utils import path_template, maybe_transform, async_maybe_transform
-from ...._compat import cached_property
-from ...._resource import SyncAPIResource, AsyncAPIResource
-from ...._response import (
- to_raw_response_wrapper,
- to_streamed_response_wrapper,
- async_to_raw_response_wrapper,
- async_to_streamed_response_wrapper,
-)
-from ...._base_client import make_request_options
-from ....types.database.v1 import project_create_params, project_create_branch_params, project_get_connection_params
-from ....types.database.v1.project_list_response import ProjectListResponse
-from ....types.database.v1.project_create_response import ProjectCreateResponse
-from ....types.database.v1.project_delete_response import ProjectDeleteResponse
-from ....types.database.v1.project_retrieve_response import ProjectRetrieveResponse
-from ....types.database.v1.project_create_branch_response import ProjectCreateBranchResponse
-from ....types.database.v1.project_list_branches_response import ProjectListBranchesResponse
-from ....types.database.v1.project_get_connection_response import ProjectGetConnectionResponse
-
-__all__ = ["ProjectsResource", "AsyncProjectsResource"]
-
-
-class ProjectsResource(SyncAPIResource):
- """Serverless PostgreSQL databases with instant branching"""
-
- @cached_property
- def with_raw_response(self) -> ProjectsResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
- """
- return ProjectsResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> ProjectsResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
- """
- return ProjectsResourceWithStreamingResponse(self)
-
- def create(
- self,
- *,
- name: str,
- description: str | Omit = omit,
- region: Literal[
- "aws-us-east-1",
- "aws-us-east-2",
- "aws-us-west-2",
- "aws-eu-central-1",
- "aws-eu-west-1",
- "aws-eu-west-2",
- "aws-ap-southeast-1",
- "aws-ap-southeast-2",
- ]
- | 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,
- ) -> ProjectCreateResponse:
- """Creates a new serverless Postgres database project powered by Neon.
-
- Includes
- automatic scaling, connection pooling, and a default 'main' branch with 'neondb'
- database. Supports branching for isolated dev/staging environments. Perfect for
- case management applications, document workflows, and litigation support
- systems.
-
- Args:
- name: Project name (letters, numbers, hyphens, underscores only)
-
- description: Optional project description
-
- region: AWS region for database deployment
-
- 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(
- "/database/v1/projects",
- body=maybe_transform(
- {
- "name": name,
- "description": description,
- "region": region,
- },
- project_create_params.ProjectCreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ProjectCreateResponse,
- )
-
- def retrieve(
- self,
- id: str,
- *,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ProjectRetrieveResponse:
- """
- Retrieves detailed information about a specific database project including
- branches, databases, storage/compute metrics, connection host, and linked
- deployments. Fetches live usage statistics from Neon API.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not id:
- raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return self._get(
- path_template("/database/v1/projects/{id}", id=id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ProjectRetrieveResponse,
- )
-
- def list(
- self,
- *,
- # 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,
- ) -> ProjectListResponse:
- """
- Retrieves all serverless Postgres database projects for the authenticated
- organization. Includes storage and compute metrics, plus linked application
- deployments and Compute instances.
- """
- return self._get(
- "/database/v1/projects",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ProjectListResponse,
- )
-
- def delete(
- self,
- id: str,
- *,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ProjectDeleteResponse:
- """
- Permanently deletes a database project from Neon and marks it as deleted in
- Case.dev. This action cannot be undone and will destroy all data including
- branches and databases. Use with caution.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not id:
- raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return self._delete(
- path_template("/database/v1/projects/{id}", id=id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ProjectDeleteResponse,
- )
-
- def create_branch(
- self,
- id: str,
- *,
- name: str,
- parent_branch_id: 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,
- ) -> ProjectCreateBranchResponse:
- """Creates a new branch from the specified parent branch (or default 'main'
- branch).
-
- Branches provide instant point-in-time clones of your database for
- isolated development, staging, testing, or feature work. Perfect for testing
- schema changes, running migrations safely, or creating ephemeral preview
- environments.
-
- Args:
- name: Branch name (letters, numbers, hyphens, underscores only)
-
- parent_branch_id: Parent branch ID to clone from (defaults to main branch)
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not id:
- raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return self._post(
- path_template("/database/v1/projects/{id}/branches", id=id),
- body=maybe_transform(
- {
- "name": name,
- "parent_branch_id": parent_branch_id,
- },
- project_create_branch_params.ProjectCreateBranchParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ProjectCreateBranchResponse,
- )
-
- def get_connection(
- self,
- id: str,
- *,
- branch: str | Omit = omit,
- pooled: bool | 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,
- ) -> ProjectGetConnectionResponse:
- """Retrieves the PostgreSQL connection URI for a database project.
-
- Supports
- selecting specific branches and pooled vs direct connections. Connection strings
- include credentials and should be stored securely. Use for configuring
- applications and deployment environments.
-
- Args:
- branch: Branch name (defaults to 'main')
-
- pooled: Use pooled connection (PgBouncer)
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not id:
- raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return self._get(
- path_template("/database/v1/projects/{id}/connection", id=id),
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "branch": branch,
- "pooled": pooled,
- },
- project_get_connection_params.ProjectGetConnectionParams,
- ),
- ),
- cast_to=ProjectGetConnectionResponse,
- )
-
- def list_branches(
- self,
- id: str,
- *,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ProjectListBranchesResponse:
- """Retrieves all branches for a database project.
-
- Branches enable isolated
- development and testing environments with instant point-in-time cloning. Each
- branch includes the default branch and any custom branches created for staging,
- testing, or feature development.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not id:
- raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return self._get(
- path_template("/database/v1/projects/{id}/branches", id=id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ProjectListBranchesResponse,
- )
-
-
-class AsyncProjectsResource(AsyncAPIResource):
- """Serverless PostgreSQL databases with instant branching"""
-
- @cached_property
- def with_raw_response(self) -> AsyncProjectsResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
- """
- return AsyncProjectsResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncProjectsResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
- """
- return AsyncProjectsResourceWithStreamingResponse(self)
-
- async def create(
- self,
- *,
- name: str,
- description: str | Omit = omit,
- region: Literal[
- "aws-us-east-1",
- "aws-us-east-2",
- "aws-us-west-2",
- "aws-eu-central-1",
- "aws-eu-west-1",
- "aws-eu-west-2",
- "aws-ap-southeast-1",
- "aws-ap-southeast-2",
- ]
- | 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,
- ) -> ProjectCreateResponse:
- """Creates a new serverless Postgres database project powered by Neon.
-
- Includes
- automatic scaling, connection pooling, and a default 'main' branch with 'neondb'
- database. Supports branching for isolated dev/staging environments. Perfect for
- case management applications, document workflows, and litigation support
- systems.
-
- Args:
- name: Project name (letters, numbers, hyphens, underscores only)
-
- description: Optional project description
-
- region: AWS region for database deployment
-
- 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(
- "/database/v1/projects",
- body=await async_maybe_transform(
- {
- "name": name,
- "description": description,
- "region": region,
- },
- project_create_params.ProjectCreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ProjectCreateResponse,
- )
-
- async def retrieve(
- self,
- id: str,
- *,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ProjectRetrieveResponse:
- """
- Retrieves detailed information about a specific database project including
- branches, databases, storage/compute metrics, connection host, and linked
- deployments. Fetches live usage statistics from Neon API.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not id:
- raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return await self._get(
- path_template("/database/v1/projects/{id}", id=id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ProjectRetrieveResponse,
- )
-
- async def list(
- self,
- *,
- # 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,
- ) -> ProjectListResponse:
- """
- Retrieves all serverless Postgres database projects for the authenticated
- organization. Includes storage and compute metrics, plus linked application
- deployments and Compute instances.
- """
- return await self._get(
- "/database/v1/projects",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ProjectListResponse,
- )
-
- async def delete(
- self,
- id: str,
- *,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ProjectDeleteResponse:
- """
- Permanently deletes a database project from Neon and marks it as deleted in
- Case.dev. This action cannot be undone and will destroy all data including
- branches and databases. Use with caution.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not id:
- raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return await self._delete(
- path_template("/database/v1/projects/{id}", id=id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ProjectDeleteResponse,
- )
-
- async def create_branch(
- self,
- id: str,
- *,
- name: str,
- parent_branch_id: 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,
- ) -> ProjectCreateBranchResponse:
- """Creates a new branch from the specified parent branch (or default 'main'
- branch).
-
- Branches provide instant point-in-time clones of your database for
- isolated development, staging, testing, or feature work. Perfect for testing
- schema changes, running migrations safely, or creating ephemeral preview
- environments.
-
- Args:
- name: Branch name (letters, numbers, hyphens, underscores only)
-
- parent_branch_id: Parent branch ID to clone from (defaults to main branch)
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not id:
- raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return await self._post(
- path_template("/database/v1/projects/{id}/branches", id=id),
- body=await async_maybe_transform(
- {
- "name": name,
- "parent_branch_id": parent_branch_id,
- },
- project_create_branch_params.ProjectCreateBranchParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ProjectCreateBranchResponse,
- )
-
- async def get_connection(
- self,
- id: str,
- *,
- branch: str | Omit = omit,
- pooled: bool | 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,
- ) -> ProjectGetConnectionResponse:
- """Retrieves the PostgreSQL connection URI for a database project.
-
- Supports
- selecting specific branches and pooled vs direct connections. Connection strings
- include credentials and should be stored securely. Use for configuring
- applications and deployment environments.
-
- Args:
- branch: Branch name (defaults to 'main')
-
- pooled: Use pooled connection (PgBouncer)
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not id:
- raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return await self._get(
- path_template("/database/v1/projects/{id}/connection", id=id),
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {
- "branch": branch,
- "pooled": pooled,
- },
- project_get_connection_params.ProjectGetConnectionParams,
- ),
- ),
- cast_to=ProjectGetConnectionResponse,
- )
-
- async def list_branches(
- self,
- id: str,
- *,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ProjectListBranchesResponse:
- """Retrieves all branches for a database project.
-
- Branches enable isolated
- development and testing environments with instant point-in-time cloning. Each
- branch includes the default branch and any custom branches created for staging,
- testing, or feature development.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not id:
- raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return await self._get(
- path_template("/database/v1/projects/{id}/branches", id=id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=ProjectListBranchesResponse,
- )
-
-
-class ProjectsResourceWithRawResponse:
- def __init__(self, projects: ProjectsResource) -> None:
- self._projects = projects
-
- self.create = to_raw_response_wrapper(
- projects.create,
- )
- self.retrieve = to_raw_response_wrapper(
- projects.retrieve,
- )
- self.list = to_raw_response_wrapper(
- projects.list,
- )
- self.delete = to_raw_response_wrapper(
- projects.delete,
- )
- self.create_branch = to_raw_response_wrapper(
- projects.create_branch,
- )
- self.get_connection = to_raw_response_wrapper(
- projects.get_connection,
- )
- self.list_branches = to_raw_response_wrapper(
- projects.list_branches,
- )
-
-
-class AsyncProjectsResourceWithRawResponse:
- def __init__(self, projects: AsyncProjectsResource) -> None:
- self._projects = projects
-
- self.create = async_to_raw_response_wrapper(
- projects.create,
- )
- self.retrieve = async_to_raw_response_wrapper(
- projects.retrieve,
- )
- self.list = async_to_raw_response_wrapper(
- projects.list,
- )
- self.delete = async_to_raw_response_wrapper(
- projects.delete,
- )
- self.create_branch = async_to_raw_response_wrapper(
- projects.create_branch,
- )
- self.get_connection = async_to_raw_response_wrapper(
- projects.get_connection,
- )
- self.list_branches = async_to_raw_response_wrapper(
- projects.list_branches,
- )
-
-
-class ProjectsResourceWithStreamingResponse:
- def __init__(self, projects: ProjectsResource) -> None:
- self._projects = projects
-
- self.create = to_streamed_response_wrapper(
- projects.create,
- )
- self.retrieve = to_streamed_response_wrapper(
- projects.retrieve,
- )
- self.list = to_streamed_response_wrapper(
- projects.list,
- )
- self.delete = to_streamed_response_wrapper(
- projects.delete,
- )
- self.create_branch = to_streamed_response_wrapper(
- projects.create_branch,
- )
- self.get_connection = to_streamed_response_wrapper(
- projects.get_connection,
- )
- self.list_branches = to_streamed_response_wrapper(
- projects.list_branches,
- )
-
-
-class AsyncProjectsResourceWithStreamingResponse:
- def __init__(self, projects: AsyncProjectsResource) -> None:
- self._projects = projects
-
- self.create = async_to_streamed_response_wrapper(
- projects.create,
- )
- self.retrieve = async_to_streamed_response_wrapper(
- projects.retrieve,
- )
- self.list = async_to_streamed_response_wrapper(
- projects.list,
- )
- self.delete = async_to_streamed_response_wrapper(
- projects.delete,
- )
- self.create_branch = async_to_streamed_response_wrapper(
- projects.create_branch,
- )
- self.get_connection = async_to_streamed_response_wrapper(
- projects.get_connection,
- )
- self.list_branches = async_to_streamed_response_wrapper(
- projects.list_branches,
- )
diff --git a/src/casedev/resources/database/v1/v1.py b/src/casedev/resources/database/v1/v1.py
deleted file mode 100644
index 85259d30..00000000
--- a/src/casedev/resources/database/v1/v1.py
+++ /dev/null
@@ -1,185 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import httpx
-
-from .projects import (
- ProjectsResource,
- AsyncProjectsResource,
- ProjectsResourceWithRawResponse,
- AsyncProjectsResourceWithRawResponse,
- ProjectsResourceWithStreamingResponse,
- AsyncProjectsResourceWithStreamingResponse,
-)
-from ...._types import Body, Query, Headers, NotGiven, not_given
-from ...._compat import cached_property
-from ...._resource import SyncAPIResource, AsyncAPIResource
-from ...._response import (
- to_raw_response_wrapper,
- to_streamed_response_wrapper,
- async_to_raw_response_wrapper,
- async_to_streamed_response_wrapper,
-)
-from ...._base_client import make_request_options
-from ....types.database.v1_get_usage_response import V1GetUsageResponse
-
-__all__ = ["V1Resource", "AsyncV1Resource"]
-
-
-class V1Resource(SyncAPIResource):
- """Serverless PostgreSQL databases with instant branching"""
-
- @cached_property
- def projects(self) -> ProjectsResource:
- """Serverless PostgreSQL databases with instant branching"""
- return ProjectsResource(self._client)
-
- @cached_property
- def with_raw_response(self) -> V1ResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
- """
- return V1ResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> V1ResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
- """
- return V1ResourceWithStreamingResponse(self)
-
- def get_usage(
- self,
- *,
- # 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,
- ) -> V1GetUsageResponse:
- """
- Returns detailed database usage statistics and billing information for the
- current billing period. Includes compute hours, storage, data transfer, and
- branch counts with associated costs broken down by project.
- """
- return self._get(
- "/database/v1/usage",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=V1GetUsageResponse,
- )
-
-
-class AsyncV1Resource(AsyncAPIResource):
- """Serverless PostgreSQL databases with instant branching"""
-
- @cached_property
- def projects(self) -> AsyncProjectsResource:
- """Serverless PostgreSQL databases with instant branching"""
- return AsyncProjectsResource(self._client)
-
- @cached_property
- def with_raw_response(self) -> AsyncV1ResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
- """
- return AsyncV1ResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncV1ResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
- """
- return AsyncV1ResourceWithStreamingResponse(self)
-
- async def get_usage(
- self,
- *,
- # 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,
- ) -> V1GetUsageResponse:
- """
- Returns detailed database usage statistics and billing information for the
- current billing period. Includes compute hours, storage, data transfer, and
- branch counts with associated costs broken down by project.
- """
- return await self._get(
- "/database/v1/usage",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=V1GetUsageResponse,
- )
-
-
-class V1ResourceWithRawResponse:
- def __init__(self, v1: V1Resource) -> None:
- self._v1 = v1
-
- self.get_usage = to_raw_response_wrapper(
- v1.get_usage,
- )
-
- @cached_property
- def projects(self) -> ProjectsResourceWithRawResponse:
- """Serverless PostgreSQL databases with instant branching"""
- return ProjectsResourceWithRawResponse(self._v1.projects)
-
-
-class AsyncV1ResourceWithRawResponse:
- def __init__(self, v1: AsyncV1Resource) -> None:
- self._v1 = v1
-
- self.get_usage = async_to_raw_response_wrapper(
- v1.get_usage,
- )
-
- @cached_property
- def projects(self) -> AsyncProjectsResourceWithRawResponse:
- """Serverless PostgreSQL databases with instant branching"""
- return AsyncProjectsResourceWithRawResponse(self._v1.projects)
-
-
-class V1ResourceWithStreamingResponse:
- def __init__(self, v1: V1Resource) -> None:
- self._v1 = v1
-
- self.get_usage = to_streamed_response_wrapper(
- v1.get_usage,
- )
-
- @cached_property
- def projects(self) -> ProjectsResourceWithStreamingResponse:
- """Serverless PostgreSQL databases with instant branching"""
- return ProjectsResourceWithStreamingResponse(self._v1.projects)
-
-
-class AsyncV1ResourceWithStreamingResponse:
- def __init__(self, v1: AsyncV1Resource) -> None:
- self._v1 = v1
-
- self.get_usage = async_to_streamed_response_wrapper(
- v1.get_usage,
- )
-
- @cached_property
- def projects(self) -> AsyncProjectsResourceWithStreamingResponse:
- """Serverless PostgreSQL databases with instant branching"""
- return AsyncProjectsResourceWithStreamingResponse(self._v1.projects)
diff --git a/src/casedev/resources/format/__init__.py b/src/casedev/resources/format/__init__.py
deleted file mode 100644
index c3ff26ae..00000000
--- a/src/casedev/resources/format/__init__.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from .v1 import (
- V1Resource,
- AsyncV1Resource,
- V1ResourceWithRawResponse,
- AsyncV1ResourceWithRawResponse,
- V1ResourceWithStreamingResponse,
- AsyncV1ResourceWithStreamingResponse,
-)
-from .format import (
- FormatResource,
- AsyncFormatResource,
- FormatResourceWithRawResponse,
- AsyncFormatResourceWithRawResponse,
- FormatResourceWithStreamingResponse,
- AsyncFormatResourceWithStreamingResponse,
-)
-
-__all__ = [
- "V1Resource",
- "AsyncV1Resource",
- "V1ResourceWithRawResponse",
- "AsyncV1ResourceWithRawResponse",
- "V1ResourceWithStreamingResponse",
- "AsyncV1ResourceWithStreamingResponse",
- "FormatResource",
- "AsyncFormatResource",
- "FormatResourceWithRawResponse",
- "AsyncFormatResourceWithRawResponse",
- "FormatResourceWithStreamingResponse",
- "AsyncFormatResourceWithStreamingResponse",
-]
diff --git a/src/casedev/resources/format/format.py b/src/casedev/resources/format/format.py
deleted file mode 100644
index e3c7ea24..00000000
--- a/src/casedev/resources/format/format.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from .v1.v1 import (
- V1Resource,
- AsyncV1Resource,
- V1ResourceWithRawResponse,
- AsyncV1ResourceWithRawResponse,
- V1ResourceWithStreamingResponse,
- AsyncV1ResourceWithStreamingResponse,
-)
-from ..._compat import cached_property
-from ..._resource import SyncAPIResource, AsyncAPIResource
-
-__all__ = ["FormatResource", "AsyncFormatResource"]
-
-
-class FormatResource(SyncAPIResource):
- @cached_property
- def v1(self) -> V1Resource:
- """Document formatting and template rendering (MD/JSON to PDF/DOCX)"""
- return V1Resource(self._client)
-
- @cached_property
- def with_raw_response(self) -> FormatResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
- """
- return FormatResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> FormatResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
- """
- return FormatResourceWithStreamingResponse(self)
-
-
-class AsyncFormatResource(AsyncAPIResource):
- @cached_property
- def v1(self) -> AsyncV1Resource:
- """Document formatting and template rendering (MD/JSON to PDF/DOCX)"""
- return AsyncV1Resource(self._client)
-
- @cached_property
- def with_raw_response(self) -> AsyncFormatResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
- """
- return AsyncFormatResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncFormatResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
- """
- return AsyncFormatResourceWithStreamingResponse(self)
-
-
-class FormatResourceWithRawResponse:
- def __init__(self, format: FormatResource) -> None:
- self._format = format
-
- @cached_property
- def v1(self) -> V1ResourceWithRawResponse:
- """Document formatting and template rendering (MD/JSON to PDF/DOCX)"""
- return V1ResourceWithRawResponse(self._format.v1)
-
-
-class AsyncFormatResourceWithRawResponse:
- def __init__(self, format: AsyncFormatResource) -> None:
- self._format = format
-
- @cached_property
- def v1(self) -> AsyncV1ResourceWithRawResponse:
- """Document formatting and template rendering (MD/JSON to PDF/DOCX)"""
- return AsyncV1ResourceWithRawResponse(self._format.v1)
-
-
-class FormatResourceWithStreamingResponse:
- def __init__(self, format: FormatResource) -> None:
- self._format = format
-
- @cached_property
- def v1(self) -> V1ResourceWithStreamingResponse:
- """Document formatting and template rendering (MD/JSON to PDF/DOCX)"""
- return V1ResourceWithStreamingResponse(self._format.v1)
-
-
-class AsyncFormatResourceWithStreamingResponse:
- def __init__(self, format: AsyncFormatResource) -> None:
- self._format = format
-
- @cached_property
- def v1(self) -> AsyncV1ResourceWithStreamingResponse:
- """Document formatting and template rendering (MD/JSON to PDF/DOCX)"""
- return AsyncV1ResourceWithStreamingResponse(self._format.v1)
diff --git a/src/casedev/resources/format/v1/__init__.py b/src/casedev/resources/format/v1/__init__.py
deleted file mode 100644
index 368db88d..00000000
--- a/src/casedev/resources/format/v1/__init__.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from .v1 import (
- V1Resource,
- AsyncV1Resource,
- V1ResourceWithRawResponse,
- AsyncV1ResourceWithRawResponse,
- V1ResourceWithStreamingResponse,
- AsyncV1ResourceWithStreamingResponse,
-)
-from .templates import (
- TemplatesResource,
- AsyncTemplatesResource,
- TemplatesResourceWithRawResponse,
- AsyncTemplatesResourceWithRawResponse,
- TemplatesResourceWithStreamingResponse,
- AsyncTemplatesResourceWithStreamingResponse,
-)
-
-__all__ = [
- "TemplatesResource",
- "AsyncTemplatesResource",
- "TemplatesResourceWithRawResponse",
- "AsyncTemplatesResourceWithRawResponse",
- "TemplatesResourceWithStreamingResponse",
- "AsyncTemplatesResourceWithStreamingResponse",
- "V1Resource",
- "AsyncV1Resource",
- "V1ResourceWithRawResponse",
- "AsyncV1ResourceWithRawResponse",
- "V1ResourceWithStreamingResponse",
- "AsyncV1ResourceWithStreamingResponse",
-]
diff --git a/src/casedev/resources/format/v1/templates.py b/src/casedev/resources/format/v1/templates.py
deleted file mode 100644
index 09364955..00000000
--- a/src/casedev/resources/format/v1/templates.py
+++ /dev/null
@@ -1,421 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal
-
-import httpx
-
-from ...._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from ...._utils import path_template, maybe_transform, async_maybe_transform
-from ...._compat import cached_property
-from ...._resource import SyncAPIResource, AsyncAPIResource
-from ...._response import (
- to_raw_response_wrapper,
- to_streamed_response_wrapper,
- async_to_raw_response_wrapper,
- async_to_streamed_response_wrapper,
-)
-from ...._base_client import make_request_options
-from ....types.format.v1 import template_list_params, template_create_params
-from ....types.format.v1.template_list_response import TemplateListResponse
-from ....types.format.v1.template_create_response import TemplateCreateResponse
-from ....types.format.v1.template_retrieve_response import TemplateRetrieveResponse
-
-__all__ = ["TemplatesResource", "AsyncTemplatesResource"]
-
-
-class TemplatesResource(SyncAPIResource):
- """Document formatting and template rendering (MD/JSON to PDF/DOCX)"""
-
- @cached_property
- def with_raw_response(self) -> TemplatesResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
- """
- return TemplatesResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> TemplatesResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
- """
- return TemplatesResourceWithStreamingResponse(self)
-
- def create(
- self,
- *,
- content: str,
- name: str,
- type: Literal["caption", "signature", "letterhead", "certificate", "footer", "custom"],
- description: str | Omit = omit,
- styles: object | Omit = omit,
- tags: SequenceNotStr[str] | Omit = omit,
- variables: SequenceNotStr[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,
- ) -> TemplateCreateResponse:
- """Create a new format template for document formatting.
-
- Templates support
- variables using `{{variable}}` syntax and can be used for captions, signatures,
- letterheads, certificates, footers, or custom formatting needs.
-
- Args:
- content: Template content with {{variable}} placeholders
-
- name: Template name
-
- type: Template type
-
- description: Template description
-
- styles: CSS styles for the template
-
- tags: Template tags for organization
-
- variables: Template variables (auto-detected if not provided)
-
- 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(
- "/format/v1/templates",
- body=maybe_transform(
- {
- "content": content,
- "name": name,
- "type": type,
- "description": description,
- "styles": styles,
- "tags": tags,
- "variables": variables,
- },
- template_create_params.TemplateCreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=TemplateCreateResponse,
- )
-
- def retrieve(
- self,
- id: str,
- *,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> TemplateRetrieveResponse:
- """Retrieve a specific document format template by ID.
-
- Format templates define how
- documents should be structured and formatted for specific legal use cases such
- as contracts, briefs, or pleadings.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not id:
- raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return self._get(
- path_template("/format/v1/templates/{id}", id=id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=TemplateRetrieveResponse,
- )
-
- def list(
- self,
- *,
- type: 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,
- ) -> TemplateListResponse:
- """Retrieve all format templates for the organization.
-
- Templates define reusable
- document formatting patterns with customizable variables for consistent legal
- document generation.
-
- Filter by type to get specific template categories like contracts, pleadings, or
- correspondence.
-
- Args:
- type: Filter templates by type (e.g., contract, pleading, letter)
-
- 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._get(
- "/format/v1/templates",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform({"type": type}, template_list_params.TemplateListParams),
- ),
- cast_to=TemplateListResponse,
- )
-
-
-class AsyncTemplatesResource(AsyncAPIResource):
- """Document formatting and template rendering (MD/JSON to PDF/DOCX)"""
-
- @cached_property
- def with_raw_response(self) -> AsyncTemplatesResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
- """
- return AsyncTemplatesResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncTemplatesResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
- """
- return AsyncTemplatesResourceWithStreamingResponse(self)
-
- async def create(
- self,
- *,
- content: str,
- name: str,
- type: Literal["caption", "signature", "letterhead", "certificate", "footer", "custom"],
- description: str | Omit = omit,
- styles: object | Omit = omit,
- tags: SequenceNotStr[str] | Omit = omit,
- variables: SequenceNotStr[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,
- ) -> TemplateCreateResponse:
- """Create a new format template for document formatting.
-
- Templates support
- variables using `{{variable}}` syntax and can be used for captions, signatures,
- letterheads, certificates, footers, or custom formatting needs.
-
- Args:
- content: Template content with {{variable}} placeholders
-
- name: Template name
-
- type: Template type
-
- description: Template description
-
- styles: CSS styles for the template
-
- tags: Template tags for organization
-
- variables: Template variables (auto-detected if not provided)
-
- 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(
- "/format/v1/templates",
- body=await async_maybe_transform(
- {
- "content": content,
- "name": name,
- "type": type,
- "description": description,
- "styles": styles,
- "tags": tags,
- "variables": variables,
- },
- template_create_params.TemplateCreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=TemplateCreateResponse,
- )
-
- async def retrieve(
- self,
- id: str,
- *,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> TemplateRetrieveResponse:
- """Retrieve a specific document format template by ID.
-
- Format templates define how
- documents should be structured and formatted for specific legal use cases such
- as contracts, briefs, or pleadings.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not id:
- raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return await self._get(
- path_template("/format/v1/templates/{id}", id=id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=TemplateRetrieveResponse,
- )
-
- async def list(
- self,
- *,
- type: 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,
- ) -> TemplateListResponse:
- """Retrieve all format templates for the organization.
-
- Templates define reusable
- document formatting patterns with customizable variables for consistent legal
- document generation.
-
- Filter by type to get specific template categories like contracts, pleadings, or
- correspondence.
-
- Args:
- type: Filter templates by type (e.g., contract, pleading, letter)
-
- 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._get(
- "/format/v1/templates",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform({"type": type}, template_list_params.TemplateListParams),
- ),
- cast_to=TemplateListResponse,
- )
-
-
-class TemplatesResourceWithRawResponse:
- def __init__(self, templates: TemplatesResource) -> None:
- self._templates = templates
-
- self.create = to_raw_response_wrapper(
- templates.create,
- )
- self.retrieve = to_raw_response_wrapper(
- templates.retrieve,
- )
- self.list = to_raw_response_wrapper(
- templates.list,
- )
-
-
-class AsyncTemplatesResourceWithRawResponse:
- def __init__(self, templates: AsyncTemplatesResource) -> None:
- self._templates = templates
-
- self.create = async_to_raw_response_wrapper(
- templates.create,
- )
- self.retrieve = async_to_raw_response_wrapper(
- templates.retrieve,
- )
- self.list = async_to_raw_response_wrapper(
- templates.list,
- )
-
-
-class TemplatesResourceWithStreamingResponse:
- def __init__(self, templates: TemplatesResource) -> None:
- self._templates = templates
-
- self.create = to_streamed_response_wrapper(
- templates.create,
- )
- self.retrieve = to_streamed_response_wrapper(
- templates.retrieve,
- )
- self.list = to_streamed_response_wrapper(
- templates.list,
- )
-
-
-class AsyncTemplatesResourceWithStreamingResponse:
- def __init__(self, templates: AsyncTemplatesResource) -> None:
- self._templates = templates
-
- self.create = async_to_streamed_response_wrapper(
- templates.create,
- )
- self.retrieve = async_to_streamed_response_wrapper(
- templates.retrieve,
- )
- self.list = async_to_streamed_response_wrapper(
- templates.list,
- )
diff --git a/src/casedev/resources/format/v1/v1.py b/src/casedev/resources/format/v1/v1.py
deleted file mode 100644
index 166fe1ce..00000000
--- a/src/casedev/resources/format/v1/v1.py
+++ /dev/null
@@ -1,260 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal
-
-import httpx
-
-from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ...._utils import maybe_transform, async_maybe_transform
-from .templates import (
- TemplatesResource,
- AsyncTemplatesResource,
- TemplatesResourceWithRawResponse,
- AsyncTemplatesResourceWithRawResponse,
- TemplatesResourceWithStreamingResponse,
- AsyncTemplatesResourceWithStreamingResponse,
-)
-from ...._compat import cached_property
-from ...._resource import SyncAPIResource, AsyncAPIResource
-from ...._response import (
- BinaryAPIResponse,
- AsyncBinaryAPIResponse,
- StreamedBinaryAPIResponse,
- AsyncStreamedBinaryAPIResponse,
- to_custom_raw_response_wrapper,
- to_custom_streamed_response_wrapper,
- async_to_custom_raw_response_wrapper,
- async_to_custom_streamed_response_wrapper,
-)
-from ...._base_client import make_request_options
-from ....types.format import v1_create_document_params
-
-__all__ = ["V1Resource", "AsyncV1Resource"]
-
-
-class V1Resource(SyncAPIResource):
- """Document formatting and template rendering (MD/JSON to PDF/DOCX)"""
-
- @cached_property
- def templates(self) -> TemplatesResource:
- """Document formatting and template rendering (MD/JSON to PDF/DOCX)"""
- return TemplatesResource(self._client)
-
- @cached_property
- def with_raw_response(self) -> V1ResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
- """
- return V1ResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> V1ResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
- """
- return V1ResourceWithStreamingResponse(self)
-
- def create_document(
- self,
- *,
- content: str,
- output_format: Literal["pdf", "docx", "html_preview"],
- input_format: Literal["md", "json", "text"] | Omit = omit,
- options: v1_create_document_params.Options | 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,
- ) -> BinaryAPIResponse:
- """
- Convert Markdown, JSON, or text content to professionally formatted PDF, DOCX,
- or HTML documents. Supports template components with variable interpolation for
- creating consistent legal documents like contracts, briefs, and reports.
-
- Args:
- content: The source content to format
-
- output_format: Desired output format
-
- input_format: Format of the input content
-
- options: Optional template composition and styling settings used during document
- generation
-
- 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
- """
- extra_headers = {"Accept": "application/pdf", **(extra_headers or {})}
- return self._post(
- "/format/v1/document",
- body=maybe_transform(
- {
- "content": content,
- "output_format": output_format,
- "input_format": input_format,
- "options": options,
- },
- v1_create_document_params.V1CreateDocumentParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=BinaryAPIResponse,
- )
-
-
-class AsyncV1Resource(AsyncAPIResource):
- """Document formatting and template rendering (MD/JSON to PDF/DOCX)"""
-
- @cached_property
- def templates(self) -> AsyncTemplatesResource:
- """Document formatting and template rendering (MD/JSON to PDF/DOCX)"""
- return AsyncTemplatesResource(self._client)
-
- @cached_property
- def with_raw_response(self) -> AsyncV1ResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
- """
- return AsyncV1ResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncV1ResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
- """
- return AsyncV1ResourceWithStreamingResponse(self)
-
- async def create_document(
- self,
- *,
- content: str,
- output_format: Literal["pdf", "docx", "html_preview"],
- input_format: Literal["md", "json", "text"] | Omit = omit,
- options: v1_create_document_params.Options | 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,
- ) -> AsyncBinaryAPIResponse:
- """
- Convert Markdown, JSON, or text content to professionally formatted PDF, DOCX,
- or HTML documents. Supports template components with variable interpolation for
- creating consistent legal documents like contracts, briefs, and reports.
-
- Args:
- content: The source content to format
-
- output_format: Desired output format
-
- input_format: Format of the input content
-
- options: Optional template composition and styling settings used during document
- generation
-
- 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
- """
- extra_headers = {"Accept": "application/pdf", **(extra_headers or {})}
- return await self._post(
- "/format/v1/document",
- body=await async_maybe_transform(
- {
- "content": content,
- "output_format": output_format,
- "input_format": input_format,
- "options": options,
- },
- v1_create_document_params.V1CreateDocumentParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=AsyncBinaryAPIResponse,
- )
-
-
-class V1ResourceWithRawResponse:
- def __init__(self, v1: V1Resource) -> None:
- self._v1 = v1
-
- self.create_document = to_custom_raw_response_wrapper(
- v1.create_document,
- BinaryAPIResponse,
- )
-
- @cached_property
- def templates(self) -> TemplatesResourceWithRawResponse:
- """Document formatting and template rendering (MD/JSON to PDF/DOCX)"""
- return TemplatesResourceWithRawResponse(self._v1.templates)
-
-
-class AsyncV1ResourceWithRawResponse:
- def __init__(self, v1: AsyncV1Resource) -> None:
- self._v1 = v1
-
- self.create_document = async_to_custom_raw_response_wrapper(
- v1.create_document,
- AsyncBinaryAPIResponse,
- )
-
- @cached_property
- def templates(self) -> AsyncTemplatesResourceWithRawResponse:
- """Document formatting and template rendering (MD/JSON to PDF/DOCX)"""
- return AsyncTemplatesResourceWithRawResponse(self._v1.templates)
-
-
-class V1ResourceWithStreamingResponse:
- def __init__(self, v1: V1Resource) -> None:
- self._v1 = v1
-
- self.create_document = to_custom_streamed_response_wrapper(
- v1.create_document,
- StreamedBinaryAPIResponse,
- )
-
- @cached_property
- def templates(self) -> TemplatesResourceWithStreamingResponse:
- """Document formatting and template rendering (MD/JSON to PDF/DOCX)"""
- return TemplatesResourceWithStreamingResponse(self._v1.templates)
-
-
-class AsyncV1ResourceWithStreamingResponse:
- def __init__(self, v1: AsyncV1Resource) -> None:
- self._v1 = v1
-
- self.create_document = async_to_custom_streamed_response_wrapper(
- v1.create_document,
- AsyncStreamedBinaryAPIResponse,
- )
-
- @cached_property
- def templates(self) -> AsyncTemplatesResourceWithStreamingResponse:
- """Document formatting and template rendering (MD/JSON to PDF/DOCX)"""
- return AsyncTemplatesResourceWithStreamingResponse(self._v1.templates)
diff --git a/src/casedev/resources/legal/v1.py b/src/casedev/resources/legal/v1.py
index 92f34cc6..6775550c 100644
--- a/src/casedev/resources/legal/v1.py
+++ b/src/casedev/resources/legal/v1.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import Union, Optional
+from typing import Union
from datetime import date
from typing_extensions import Literal
@@ -20,7 +20,6 @@
)
from ...types.legal import (
v1_find_params,
- v1_draft_params,
v1_docket_params,
v1_verify_params,
v1_similar_params,
@@ -36,7 +35,6 @@
)
from ..._base_client import make_request_options
from ...types.legal.v1_find_response import V1FindResponse
-from ...types.legal.v1_draft_response import V1DraftResponse
from ...types.legal.v1_docket_response import V1DocketResponse
from ...types.legal.v1_verify_response import V1VerifyResponse
from ...types.legal.v1_similar_response import V1SimilarResponse
@@ -124,7 +122,8 @@ def docket(
acknowledgePacerFees: true. PACER charges up to $3.00 per docket sheet plus a
$0.05 service fee. Only valid with type: "lookup".
- offset: Offset for search results or entry list
+ offset: Offset for search results or entry list (maximum 200 when including lookup
+ entries)
query: Case name or party name search query (required for search)
@@ -160,87 +159,6 @@ def docket(
cast_to=V1DocketResponse,
)
- def draft(
- self,
- *,
- instructions: str,
- vault_id: str,
- citations: bool | Omit = omit,
- format: Optional[str] | Omit = omit,
- length: Optional[v1_draft_params.Length] | Omit = omit,
- model: Optional[str] | Omit = omit,
- object_ids: Optional[SequenceNotStr[str]] | Omit = omit,
- output_name: Optional[str] | Omit = omit,
- output_type: Literal["pdf", "docx", "xlsx", "pptx", "md"] | Omit = omit,
- verified: bool | 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,
- ) -> V1DraftResponse:
- """Generate a legal document with structured inputs.
-
- Powered by an agent that
- handles research, formatting, citation verification, and vault upload. Returns a
- run ID for polling.
-
- Args:
- instructions: What to draft — the core task. E.g., "Motion to compel defendant to produce
- discovery responses"
-
- vault_id: Vault ID where the final document will be uploaded
-
- citations: Research and include legal citations
-
- format: Court or jurisdiction formatting hint. Triggers a legal-skills search. E.g.,
- "California Superior Court", "SDNY", "federal pleading"
-
- length: Target document length
-
- model: LLM model override. Defaults to anthropic/claude-sonnet-4.6
-
- object_ids: Vault object IDs to use as source/reference documents
-
- output_name: Filename for the output document. Auto-generated if omitted.
-
- output_type: Output file format
-
- verified: Verify all citations in a loop — re-run verification and repair bad citations
- until they pass
-
- 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(
- "/legal/v1/draft",
- body=maybe_transform(
- {
- "instructions": instructions,
- "vault_id": vault_id,
- "citations": citations,
- "format": format,
- "length": length,
- "model": model,
- "object_ids": object_ids,
- "output_name": output_name,
- "output_type": output_type,
- "verified": verified,
- },
- v1_draft_params.V1DraftParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=V1DraftResponse,
- )
-
def find(
self,
*,
@@ -948,7 +866,8 @@ async def docket(
acknowledgePacerFees: true. PACER charges up to $3.00 per docket sheet plus a
$0.05 service fee. Only valid with type: "lookup".
- offset: Offset for search results or entry list
+ offset: Offset for search results or entry list (maximum 200 when including lookup
+ entries)
query: Case name or party name search query (required for search)
@@ -984,87 +903,6 @@ async def docket(
cast_to=V1DocketResponse,
)
- async def draft(
- self,
- *,
- instructions: str,
- vault_id: str,
- citations: bool | Omit = omit,
- format: Optional[str] | Omit = omit,
- length: Optional[v1_draft_params.Length] | Omit = omit,
- model: Optional[str] | Omit = omit,
- object_ids: Optional[SequenceNotStr[str]] | Omit = omit,
- output_name: Optional[str] | Omit = omit,
- output_type: Literal["pdf", "docx", "xlsx", "pptx", "md"] | Omit = omit,
- verified: bool | 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,
- ) -> V1DraftResponse:
- """Generate a legal document with structured inputs.
-
- Powered by an agent that
- handles research, formatting, citation verification, and vault upload. Returns a
- run ID for polling.
-
- Args:
- instructions: What to draft — the core task. E.g., "Motion to compel defendant to produce
- discovery responses"
-
- vault_id: Vault ID where the final document will be uploaded
-
- citations: Research and include legal citations
-
- format: Court or jurisdiction formatting hint. Triggers a legal-skills search. E.g.,
- "California Superior Court", "SDNY", "federal pleading"
-
- length: Target document length
-
- model: LLM model override. Defaults to anthropic/claude-sonnet-4.6
-
- object_ids: Vault object IDs to use as source/reference documents
-
- output_name: Filename for the output document. Auto-generated if omitted.
-
- output_type: Output file format
-
- verified: Verify all citations in a loop — re-run verification and repair bad citations
- until they pass
-
- 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(
- "/legal/v1/draft",
- body=await async_maybe_transform(
- {
- "instructions": instructions,
- "vault_id": vault_id,
- "citations": citations,
- "format": format,
- "length": length,
- "model": model,
- "object_ids": object_ids,
- "output_name": output_name,
- "output_type": output_type,
- "verified": verified,
- },
- v1_draft_params.V1DraftParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=V1DraftResponse,
- )
-
async def find(
self,
*,
@@ -1710,9 +1548,6 @@ def __init__(self, v1: V1Resource) -> None:
self.docket = to_raw_response_wrapper(
v1.docket,
)
- self.draft = to_raw_response_wrapper(
- v1.draft,
- )
self.find = to_raw_response_wrapper(
v1.find,
)
@@ -1758,9 +1593,6 @@ def __init__(self, v1: AsyncV1Resource) -> None:
self.docket = async_to_raw_response_wrapper(
v1.docket,
)
- self.draft = async_to_raw_response_wrapper(
- v1.draft,
- )
self.find = async_to_raw_response_wrapper(
v1.find,
)
@@ -1806,9 +1638,6 @@ def __init__(self, v1: V1Resource) -> None:
self.docket = to_streamed_response_wrapper(
v1.docket,
)
- self.draft = to_streamed_response_wrapper(
- v1.draft,
- )
self.find = to_streamed_response_wrapper(
v1.find,
)
@@ -1854,9 +1683,6 @@ def __init__(self, v1: AsyncV1Resource) -> None:
self.docket = async_to_streamed_response_wrapper(
v1.docket,
)
- self.draft = async_to_streamed_response_wrapper(
- v1.draft,
- )
self.find = async_to_streamed_response_wrapper(
v1.find,
)
diff --git a/src/casedev/resources/mail/__init__.py b/src/casedev/resources/linc/__init__.py
similarity index 54%
rename from src/casedev/resources/mail/__init__.py
rename to src/casedev/resources/linc/__init__.py
index 35f6ebf0..71fe8770 100644
--- a/src/casedev/resources/mail/__init__.py
+++ b/src/casedev/resources/linc/__init__.py
@@ -8,13 +8,13 @@
V1ResourceWithStreamingResponse,
AsyncV1ResourceWithStreamingResponse,
)
-from .mail import (
- MailResource,
- AsyncMailResource,
- MailResourceWithRawResponse,
- AsyncMailResourceWithRawResponse,
- MailResourceWithStreamingResponse,
- AsyncMailResourceWithStreamingResponse,
+from .linc import (
+ LincResource,
+ AsyncLincResource,
+ LincResourceWithRawResponse,
+ AsyncLincResourceWithRawResponse,
+ LincResourceWithStreamingResponse,
+ AsyncLincResourceWithStreamingResponse,
)
__all__ = [
@@ -24,10 +24,10 @@
"AsyncV1ResourceWithRawResponse",
"V1ResourceWithStreamingResponse",
"AsyncV1ResourceWithStreamingResponse",
- "MailResource",
- "AsyncMailResource",
- "MailResourceWithRawResponse",
- "AsyncMailResourceWithRawResponse",
- "MailResourceWithStreamingResponse",
- "AsyncMailResourceWithStreamingResponse",
+ "LincResource",
+ "AsyncLincResource",
+ "LincResourceWithRawResponse",
+ "AsyncLincResourceWithRawResponse",
+ "LincResourceWithStreamingResponse",
+ "AsyncLincResourceWithStreamingResponse",
]
diff --git a/src/casedev/resources/mail/mail.py b/src/casedev/resources/linc/linc.py
similarity index 61%
rename from src/casedev/resources/mail/mail.py
rename to src/casedev/resources/linc/linc.py
index c97214b9..3eedd0b7 100644
--- a/src/casedev/resources/mail/mail.py
+++ b/src/casedev/resources/linc/linc.py
@@ -13,90 +13,90 @@
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
-__all__ = ["MailResource", "AsyncMailResource"]
+__all__ = ["LincResource", "AsyncLincResource"]
-class MailResource(SyncAPIResource):
+class LincResource(SyncAPIResource):
@cached_property
def v1(self) -> V1Resource:
return V1Resource(self._client)
@cached_property
- def with_raw_response(self) -> MailResourceWithRawResponse:
+ def with_raw_response(self) -> LincResourceWithRawResponse:
"""
This property can be used as a prefix for any HTTP method call to return
the raw response object instead of the parsed content.
For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
"""
- return MailResourceWithRawResponse(self)
+ return LincResourceWithRawResponse(self)
@cached_property
- def with_streaming_response(self) -> MailResourceWithStreamingResponse:
+ def with_streaming_response(self) -> LincResourceWithStreamingResponse:
"""
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
"""
- return MailResourceWithStreamingResponse(self)
+ return LincResourceWithStreamingResponse(self)
-class AsyncMailResource(AsyncAPIResource):
+class AsyncLincResource(AsyncAPIResource):
@cached_property
def v1(self) -> AsyncV1Resource:
return AsyncV1Resource(self._client)
@cached_property
- def with_raw_response(self) -> AsyncMailResourceWithRawResponse:
+ def with_raw_response(self) -> AsyncLincResourceWithRawResponse:
"""
This property can be used as a prefix for any HTTP method call to return
the raw response object instead of the parsed content.
For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
"""
- return AsyncMailResourceWithRawResponse(self)
+ return AsyncLincResourceWithRawResponse(self)
@cached_property
- def with_streaming_response(self) -> AsyncMailResourceWithStreamingResponse:
+ def with_streaming_response(self) -> AsyncLincResourceWithStreamingResponse:
"""
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
"""
- return AsyncMailResourceWithStreamingResponse(self)
+ return AsyncLincResourceWithStreamingResponse(self)
-class MailResourceWithRawResponse:
- def __init__(self, mail: MailResource) -> None:
- self._mail = mail
+class LincResourceWithRawResponse:
+ def __init__(self, linc: LincResource) -> None:
+ self._linc = linc
@cached_property
def v1(self) -> V1ResourceWithRawResponse:
- return V1ResourceWithRawResponse(self._mail.v1)
+ return V1ResourceWithRawResponse(self._linc.v1)
-class AsyncMailResourceWithRawResponse:
- def __init__(self, mail: AsyncMailResource) -> None:
- self._mail = mail
+class AsyncLincResourceWithRawResponse:
+ def __init__(self, linc: AsyncLincResource) -> None:
+ self._linc = linc
@cached_property
def v1(self) -> AsyncV1ResourceWithRawResponse:
- return AsyncV1ResourceWithRawResponse(self._mail.v1)
+ return AsyncV1ResourceWithRawResponse(self._linc.v1)
-class MailResourceWithStreamingResponse:
- def __init__(self, mail: MailResource) -> None:
- self._mail = mail
+class LincResourceWithStreamingResponse:
+ def __init__(self, linc: LincResource) -> None:
+ self._linc = linc
@cached_property
def v1(self) -> V1ResourceWithStreamingResponse:
- return V1ResourceWithStreamingResponse(self._mail.v1)
+ return V1ResourceWithStreamingResponse(self._linc.v1)
-class AsyncMailResourceWithStreamingResponse:
- def __init__(self, mail: AsyncMailResource) -> None:
- self._mail = mail
+class AsyncLincResourceWithStreamingResponse:
+ def __init__(self, linc: AsyncLincResource) -> None:
+ self._linc = linc
@cached_property
def v1(self) -> AsyncV1ResourceWithStreamingResponse:
- return AsyncV1ResourceWithStreamingResponse(self._mail.v1)
+ return AsyncV1ResourceWithStreamingResponse(self._linc.v1)
diff --git a/src/casedev/resources/agent/__init__.py b/src/casedev/resources/linc/v1/__init__.py
similarity index 51%
rename from src/casedev/resources/agent/__init__.py
rename to src/casedev/resources/linc/v1/__init__.py
index 1c506f86..93ec4af8 100644
--- a/src/casedev/resources/agent/__init__.py
+++ b/src/casedev/resources/linc/v1/__init__.py
@@ -8,26 +8,26 @@
V1ResourceWithStreamingResponse,
AsyncV1ResourceWithStreamingResponse,
)
-from .agent import (
- AgentResource,
- AsyncAgentResource,
- AgentResourceWithRawResponse,
- AsyncAgentResourceWithRawResponse,
- AgentResourceWithStreamingResponse,
- AsyncAgentResourceWithStreamingResponse,
+from .sessions import (
+ SessionsResource,
+ AsyncSessionsResource,
+ SessionsResourceWithRawResponse,
+ AsyncSessionsResourceWithRawResponse,
+ SessionsResourceWithStreamingResponse,
+ AsyncSessionsResourceWithStreamingResponse,
)
__all__ = [
+ "SessionsResource",
+ "AsyncSessionsResource",
+ "SessionsResourceWithRawResponse",
+ "AsyncSessionsResourceWithRawResponse",
+ "SessionsResourceWithStreamingResponse",
+ "AsyncSessionsResourceWithStreamingResponse",
"V1Resource",
"AsyncV1Resource",
"V1ResourceWithRawResponse",
"AsyncV1ResourceWithRawResponse",
"V1ResourceWithStreamingResponse",
"AsyncV1ResourceWithStreamingResponse",
- "AgentResource",
- "AsyncAgentResource",
- "AgentResourceWithRawResponse",
- "AsyncAgentResourceWithRawResponse",
- "AgentResourceWithStreamingResponse",
- "AsyncAgentResourceWithStreamingResponse",
]
diff --git a/src/casedev/resources/agent/v1/run.py b/src/casedev/resources/linc/v1/sessions.py
similarity index 51%
rename from src/casedev/resources/agent/v1/run.py
rename to src/casedev/resources/linc/v1/sessions.py
index c70c8fc8..4a9ce336 100644
--- a/src/casedev/resources/agent/v1/run.py
+++ b/src/casedev/resources/linc/v1/sessions.py
@@ -2,12 +2,12 @@
from __future__ import annotations
-from typing import Optional
+from typing import Iterable, Optional
from typing_extensions import Literal
import httpx
-from ...._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
+from ...._types import Body, Omit, Query, Headers, NoneType, NotGiven, SequenceNotStr, omit, not_given
from ...._utils import path_template, maybe_transform, async_maybe_transform
from ...._compat import cached_property
from ...._resource import SyncAPIResource, AsyncAPIResource
@@ -17,81 +17,82 @@
async_to_raw_response_wrapper,
async_to_streamed_response_wrapper,
)
-from ...._streaming import Stream, AsyncStream
from ...._base_client import make_request_options
-from ....types.agent.v1 import run_list_params, run_watch_params, run_create_params, run_events_params
-from ....types.agent.v1.run_exec_response import RunExecResponse
-from ....types.agent.v1.run_list_response import RunListResponse
-from ....types.agent.v1.run_watch_response import RunWatchResponse
-from ....types.agent.v1.run_cancel_response import RunCancelResponse
-from ....types.agent.v1.run_create_response import RunCreateResponse
-from ....types.agent.v1.run_events_response import RunEventsResponse
-from ....types.agent.v1.run_get_status_response import RunGetStatusResponse
-from ....types.agent.v1.run_get_details_response import RunGetDetailsResponse
+from ....types.linc.v1 import (
+ session_cancel_params,
+ session_create_params,
+ session_send_rpc_params,
+ session_ingest_events_params,
+ session_retrieve_events_params,
+ session_retrieve_messages_params,
+)
-__all__ = ["RunResource", "AsyncRunResource"]
+__all__ = ["SessionsResource", "AsyncSessionsResource"]
-class RunResource(SyncAPIResource):
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
+class SessionsResource(SyncAPIResource):
+ """Durable, stateful legal agent sessions with sandboxed tools and files"""
@cached_property
- def with_raw_response(self) -> RunResourceWithRawResponse:
+ def with_raw_response(self) -> SessionsResourceWithRawResponse:
"""
This property can be used as a prefix for any HTTP method call to return
the raw response object instead of the parsed content.
For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
"""
- return RunResourceWithRawResponse(self)
+ return SessionsResourceWithRawResponse(self)
@cached_property
- def with_streaming_response(self) -> RunResourceWithStreamingResponse:
+ def with_streaming_response(self) -> SessionsResourceWithStreamingResponse:
"""
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
"""
- return RunResourceWithStreamingResponse(self)
+ return SessionsResourceWithStreamingResponse(self)
def create(
self,
*,
- agent_id: str,
- prompt: str,
- callback_url: Optional[str] | Omit = omit,
- guidance: Optional[str] | Omit = omit,
+ document_template_slugs: Optional[SequenceNotStr[str]] | Omit = omit,
+ idle_timeout_ms: Optional[int] | Omit = omit,
+ include_document_templates: Optional[bool] | Omit = omit,
+ instructions: Optional[str] | Omit = omit,
model: Optional[str] | Omit = omit,
- object_ids: Optional[SequenceNotStr[str]] | Omit = omit,
+ scoped_api_key: Optional[str] | Omit = omit,
+ service_tier: Literal["default", "priority"] | Omit = omit,
+ skill_slugs: Optional[SequenceNotStr[str]] | Omit = omit,
+ title: str | Omit = omit,
+ vault_ids: Optional[SequenceNotStr[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,
- ) -> RunCreateResponse:
- """Creates a run in queued state.
-
- Call POST /agent/v1/run/:id/exec to start
- execution.
+ ) -> None:
+ """
+ Creates a Daytona-backed native Linc session with scoped Case.dev credentials.
+ This endpoint starts the sandbox actor only; messages and event replay use
+ separate endpoints.
Args:
- agent_id: ID of the agent to run
+ document_template_slugs: Specific document template slugs to inject into the using-document-templates
+ skill.
- prompt: Task prompt for the agent
+ include_document_templates: When true, inject all active org document templates into the
+ using-document-templates skill.
- callback_url: HTTPS callback URL to receive a notification when the run completes. Registered
- atomically with the run — eliminates the race condition of calling /watch after
- /exec. Additional watchers can still be added via POST /run/:id/watch.
+ instructions: Privileged C3-only hidden app instructions to append to the sandbox AGENTS.md.
- guidance: Additional guidance for this run
+ scoped_api_key: Optional caller-provided scoped Case.dev API key for the runtime.
- model: Override the agent default model for this run
+ service_tier: Processing tier for eligible OpenAI GPT models. Priority provides lower latency
+ at premium cost.
- object_ids: Scope this run to specific vault object IDs. The agent will only be able to
- access these objects during execution.
+ skill_slugs: Skills API slugs to install into the runtime sandbox before the native session
+ starts.
extra_headers: Send extra headers
@@ -101,54 +102,45 @@ def create(
timeout: Override the client-level default timeout for this request, in seconds
"""
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._post(
- "/agent/v1/run",
+ "/linc/v1/sessions",
body=maybe_transform(
{
- "agent_id": agent_id,
- "prompt": prompt,
- "callback_url": callback_url,
- "guidance": guidance,
+ "document_template_slugs": document_template_slugs,
+ "idle_timeout_ms": idle_timeout_ms,
+ "include_document_templates": include_document_templates,
+ "instructions": instructions,
"model": model,
- "object_ids": object_ids,
+ "scoped_api_key": scoped_api_key,
+ "service_tier": service_tier,
+ "skill_slugs": skill_slugs,
+ "title": title,
+ "vault_ids": vault_ids,
},
- run_create_params.RunCreateParams,
+ session_create_params.SessionCreateParams,
),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=RunCreateResponse,
+ cast_to=NoneType,
)
- def list(
+ def delete(
self,
+ id: str,
*,
- agent_id: str | Omit = omit,
- cursor: str | Omit = omit,
- limit: int | Omit = omit,
- status: Literal["queued", "running", "completed", "failed", "cancelled"] | 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,
- ) -> RunListResponse:
- """Lists agent runs for the authenticated organization.
-
- Supports filtering by
- agent, status, and cursor-based pagination.
+ ) -> None:
+ """
+ End native Linc session
Args:
- agent_id: Filter by agent ID
-
- cursor: Pagination cursor (run ID from previous page). Returns runs created before this
- run.
-
- limit: Maximum number of runs to return (default 50, max 250)
-
- status: Filter by run status
-
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -157,43 +149,43 @@ def list(
timeout: Override the client-level default timeout for this request, in seconds
"""
- return self._get(
- "/agent/v1/run",
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._delete(
+ path_template("/linc/v1/sessions/{id}", id=id),
options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "agent_id": agent_id,
- "cursor": cursor,
- "limit": limit,
- "status": status,
- },
- run_list_params.RunListParams,
- ),
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=RunListResponse,
+ cast_to=NoneType,
)
def cancel(
self,
id: str,
*,
+ clear_queue: bool | 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,
- ) -> RunCancelResponse:
- """Cancels a running or queued run.
-
- Idempotent — cancelling a finished run returns
- its current status.
+ ) -> None:
+ """
+ Sends an abort RPC to the session runtime, ending the current turn while keeping
+ the session alive. Body handling is intentionally lenient — cancel is a stop
+ control, so unknown fields are ignored and an invalid or missing body is treated
+ as empty rather than rejected.
Args:
+ clear_queue: Also clear queued steering/follow-up messages so the abort leaves the agent
+ fully idle. Cleared texts are returned in the `response.data.clearedQueue` field
+ of the response body. Without it, messages still queued when the abort settles
+ are auto-continued as a new run. Runtimes older than the Linc release that
+ supports this flag ignore it: the abort still happens but the queue is left
+ untouched.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -204,32 +196,35 @@ def cancel(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._post(
- path_template("/agent/v1/run/{id}/cancel", id=id),
+ path_template("/linc/v1/sessions/{id}/cancel", id=id),
+ body=maybe_transform({"clear_queue": clear_queue}, session_cancel_params.SessionCancelParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=RunCancelResponse,
+ cast_to=NoneType,
)
- def events(
+ def ingest_events(
self,
id: str,
*,
- last_event_id: int | Omit = omit,
+ frames: Iterable[session_ingest_events_params.Frame],
# 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,
- ) -> Stream[RunEventsResponse]:
- """Streams real-time run events over SSE.
+ ) -> None:
+ """Runtime ingest endpoint for sandbox runtimes.
- Supports replay using Last-Event-ID.
+ Frames are persisted for replay;
+ terminal frames emit the durable Linc session ended webhook.
Args:
- last_event_id: Replay events after this sequence number
+ frames: Native Linc event frames to persist for replay.
extra_headers: Send extra headers
@@ -241,38 +236,44 @@ def events(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- extra_headers = {"Accept": "text/event-stream", **(extra_headers or {})}
- return self._get(
- path_template("/agent/v1/run/{id}/events", id=id),
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._post(
+ path_template("/linc/v1/sessions/{id}/events/ingest", id=id),
+ body=maybe_transform({"frames": frames}, session_ingest_events_params.SessionIngestEventsParams),
options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform({"last_event_id": last_event_id}, run_events_params.RunEventsParams),
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=str,
- stream=True,
- stream_cls=Stream[RunEventsResponse],
+ cast_to=NoneType,
)
- def exec(
+ def retrieve_events(
self,
id: str,
*,
+ after_seq: int | Omit = omit,
+ cursor: int | Omit = omit,
+ exclude_event_types: SequenceNotStr[str] | Omit = omit,
+ limit: 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,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> RunExecResponse:
- """Starts execution of a queued run.
-
- The agent runs in a durable workflow — poll
- /run/:id/status for progress.
+ ) -> None:
+ """
+ Returns persisted native Pi/Linc event envelopes after the requested cursor.
+ Live delivery is handled by the Linc stream service.
Args:
+ after_seq: Alias for cursor. Ignored when cursor is also provided.
+
+ cursor: Replay events with a sequence number greater than this cursor.
+
+ exclude_event_types: Comma-separated Linc event types to omit from replay.
+
+ limit: Maximum number of events to return.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -283,30 +284,53 @@ def exec(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return self._post(
- path_template("/agent/v1/run/{id}/exec", id=id),
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._get(
+ path_template("/linc/v1/sessions/{id}/events", id=id),
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "after_seq": after_seq,
+ "cursor": cursor,
+ "exclude_event_types": exclude_event_types,
+ "limit": limit,
+ },
+ session_retrieve_events_params.SessionRetrieveEventsParams,
+ ),
),
- cast_to=RunExecResponse,
+ cast_to=NoneType,
)
- def get_details(
+ def retrieve_messages(
self,
id: str,
*,
+ after_seq: int | Omit = omit,
+ cursor: int | Omit = omit,
+ limit: 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,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> RunGetDetailsResponse:
+ ) -> None:
"""
- Full audit trail for a run including output, steps (tool calls, text), and token
- usage.
+ Returns completed Pi/Linc message entries derived from durable native Linc
+ events. This is the stable session-message read model for callers that need to
+ persist or recover chat history without depending on a live SSE stream.
Args:
+ after_seq: Alias for cursor. Ignored when cursor is also provided.
+
+ cursor: Replay messages with a source event sequence number greater than this cursor.
+
+ limit: Maximum number of source events to scan for completed messages.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -317,15 +341,27 @@ def get_details(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._get(
- path_template("/agent/v1/run/{id}/details", id=id),
+ path_template("/linc/v1/sessions/{id}/messages", id=id),
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "after_seq": after_seq,
+ "cursor": cursor,
+ "limit": limit,
+ },
+ session_retrieve_messages_params.SessionRetrieveMessagesParams,
+ ),
),
- cast_to=RunGetDetailsResponse,
+ cast_to=NoneType,
)
- def get_status(
+ def retrieve_state(
self,
id: str,
*,
@@ -335,11 +371,9 @@ def get_status(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> RunGetStatusResponse:
- """Lightweight status poll for a run.
-
- Use /run/:id/details for the full audit
- trail.
+ ) -> None:
+ """
+ Get native Linc session state
Args:
extra_headers: Send extra headers
@@ -352,33 +386,38 @@ def get_status(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._get(
- path_template("/agent/v1/run/{id}/status", id=id),
+ path_template("/linc/v1/sessions/{id}/state", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=RunGetStatusResponse,
+ cast_to=NoneType,
)
- def watch(
+ def send_rpc(
self,
- id: str,
+ path_id: str,
*,
- callback_url: str,
+ type: str,
+ body_id: 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,
- ) -> RunWatchResponse:
- """Register a callback URL to receive notifications when the run completes.
-
- URL
- must use https and must not point to a private network.
+ ) -> None:
+ """
+ Forwards a native Pi/Linc RPC command object to the sandbox-local Linc bridge
+ unchanged. The route returns after Pi accepts or rejects the command; native
+ events are read through the events endpoint.
Args:
- callback_url: HTTPS URL to receive completion callback
+ type: Native Pi/Linc RPC command type. Prompt commands also require a string id for
+ idempotency.
+
+ body_id: Command idempotency key. Required when type is prompt.
extra_headers: Send extra headers
@@ -388,78 +427,88 @@ def watch(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not id:
- raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ if not path_id:
+ raise ValueError(f"Expected a non-empty value for `path_id` but received {path_id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._post(
- path_template("/agent/v1/run/{id}/watch", id=id),
- body=maybe_transform({"callback_url": callback_url}, run_watch_params.RunWatchParams),
+ path_template("/linc/v1/sessions/{path_id}/rpc", path_id=path_id),
+ body=maybe_transform(
+ {
+ "type": type,
+ "body_id": body_id,
+ },
+ session_send_rpc_params.SessionSendRpcParams,
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=RunWatchResponse,
+ cast_to=NoneType,
)
-class AsyncRunResource(AsyncAPIResource):
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
+class AsyncSessionsResource(AsyncAPIResource):
+ """Durable, stateful legal agent sessions with sandboxed tools and files"""
@cached_property
- def with_raw_response(self) -> AsyncRunResourceWithRawResponse:
+ def with_raw_response(self) -> AsyncSessionsResourceWithRawResponse:
"""
This property can be used as a prefix for any HTTP method call to return
the raw response object instead of the parsed content.
For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
"""
- return AsyncRunResourceWithRawResponse(self)
+ return AsyncSessionsResourceWithRawResponse(self)
@cached_property
- def with_streaming_response(self) -> AsyncRunResourceWithStreamingResponse:
+ def with_streaming_response(self) -> AsyncSessionsResourceWithStreamingResponse:
"""
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
"""
- return AsyncRunResourceWithStreamingResponse(self)
+ return AsyncSessionsResourceWithStreamingResponse(self)
async def create(
self,
*,
- agent_id: str,
- prompt: str,
- callback_url: Optional[str] | Omit = omit,
- guidance: Optional[str] | Omit = omit,
+ document_template_slugs: Optional[SequenceNotStr[str]] | Omit = omit,
+ idle_timeout_ms: Optional[int] | Omit = omit,
+ include_document_templates: Optional[bool] | Omit = omit,
+ instructions: Optional[str] | Omit = omit,
model: Optional[str] | Omit = omit,
- object_ids: Optional[SequenceNotStr[str]] | Omit = omit,
+ scoped_api_key: Optional[str] | Omit = omit,
+ service_tier: Literal["default", "priority"] | Omit = omit,
+ skill_slugs: Optional[SequenceNotStr[str]] | Omit = omit,
+ title: str | Omit = omit,
+ vault_ids: Optional[SequenceNotStr[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,
- ) -> RunCreateResponse:
- """Creates a run in queued state.
-
- Call POST /agent/v1/run/:id/exec to start
- execution.
+ ) -> None:
+ """
+ Creates a Daytona-backed native Linc session with scoped Case.dev credentials.
+ This endpoint starts the sandbox actor only; messages and event replay use
+ separate endpoints.
Args:
- agent_id: ID of the agent to run
+ document_template_slugs: Specific document template slugs to inject into the using-document-templates
+ skill.
- prompt: Task prompt for the agent
+ include_document_templates: When true, inject all active org document templates into the
+ using-document-templates skill.
- callback_url: HTTPS callback URL to receive a notification when the run completes. Registered
- atomically with the run — eliminates the race condition of calling /watch after
- /exec. Additional watchers can still be added via POST /run/:id/watch.
+ instructions: Privileged C3-only hidden app instructions to append to the sandbox AGENTS.md.
- guidance: Additional guidance for this run
+ scoped_api_key: Optional caller-provided scoped Case.dev API key for the runtime.
- model: Override the agent default model for this run
+ service_tier: Processing tier for eligible OpenAI GPT models. Priority provides lower latency
+ at premium cost.
- object_ids: Scope this run to specific vault object IDs. The agent will only be able to
- access these objects during execution.
+ skill_slugs: Skills API slugs to install into the runtime sandbox before the native session
+ starts.
extra_headers: Send extra headers
@@ -469,54 +518,45 @@ async def create(
timeout: Override the client-level default timeout for this request, in seconds
"""
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._post(
- "/agent/v1/run",
+ "/linc/v1/sessions",
body=await async_maybe_transform(
{
- "agent_id": agent_id,
- "prompt": prompt,
- "callback_url": callback_url,
- "guidance": guidance,
+ "document_template_slugs": document_template_slugs,
+ "idle_timeout_ms": idle_timeout_ms,
+ "include_document_templates": include_document_templates,
+ "instructions": instructions,
"model": model,
- "object_ids": object_ids,
+ "scoped_api_key": scoped_api_key,
+ "service_tier": service_tier,
+ "skill_slugs": skill_slugs,
+ "title": title,
+ "vault_ids": vault_ids,
},
- run_create_params.RunCreateParams,
+ session_create_params.SessionCreateParams,
),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=RunCreateResponse,
+ cast_to=NoneType,
)
- async def list(
+ async def delete(
self,
+ id: str,
*,
- agent_id: str | Omit = omit,
- cursor: str | Omit = omit,
- limit: int | Omit = omit,
- status: Literal["queued", "running", "completed", "failed", "cancelled"] | 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,
- ) -> RunListResponse:
- """Lists agent runs for the authenticated organization.
-
- Supports filtering by
- agent, status, and cursor-based pagination.
+ ) -> None:
+ """
+ End native Linc session
Args:
- agent_id: Filter by agent ID
-
- cursor: Pagination cursor (run ID from previous page). Returns runs created before this
- run.
-
- limit: Maximum number of runs to return (default 50, max 250)
-
- status: Filter by run status
-
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -525,43 +565,43 @@ async def list(
timeout: Override the client-level default timeout for this request, in seconds
"""
- return await self._get(
- "/agent/v1/run",
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._delete(
+ path_template("/linc/v1/sessions/{id}", id=id),
options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {
- "agent_id": agent_id,
- "cursor": cursor,
- "limit": limit,
- "status": status,
- },
- run_list_params.RunListParams,
- ),
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=RunListResponse,
+ cast_to=NoneType,
)
async def cancel(
self,
id: str,
*,
+ clear_queue: bool | 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,
- ) -> RunCancelResponse:
- """Cancels a running or queued run.
-
- Idempotent — cancelling a finished run returns
- its current status.
+ ) -> None:
+ """
+ Sends an abort RPC to the session runtime, ending the current turn while keeping
+ the session alive. Body handling is intentionally lenient — cancel is a stop
+ control, so unknown fields are ignored and an invalid or missing body is treated
+ as empty rather than rejected.
Args:
+ clear_queue: Also clear queued steering/follow-up messages so the abort leaves the agent
+ fully idle. Cleared texts are returned in the `response.data.clearedQueue` field
+ of the response body. Without it, messages still queued when the abort settles
+ are auto-continued as a new run. Runtimes older than the Linc release that
+ supports this flag ignore it: the abort still happens but the queue is left
+ untouched.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -572,32 +612,35 @@ async def cancel(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._post(
- path_template("/agent/v1/run/{id}/cancel", id=id),
+ path_template("/linc/v1/sessions/{id}/cancel", id=id),
+ body=await async_maybe_transform({"clear_queue": clear_queue}, session_cancel_params.SessionCancelParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=RunCancelResponse,
+ cast_to=NoneType,
)
- async def events(
+ async def ingest_events(
self,
id: str,
*,
- last_event_id: int | Omit = omit,
+ frames: Iterable[session_ingest_events_params.Frame],
# 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,
- ) -> AsyncStream[RunEventsResponse]:
- """Streams real-time run events over SSE.
+ ) -> None:
+ """Runtime ingest endpoint for sandbox runtimes.
- Supports replay using Last-Event-ID.
+ Frames are persisted for replay;
+ terminal frames emit the durable Linc session ended webhook.
Args:
- last_event_id: Replay events after this sequence number
+ frames: Native Linc event frames to persist for replay.
extra_headers: Send extra headers
@@ -609,38 +652,46 @@ async def events(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- extra_headers = {"Accept": "text/event-stream", **(extra_headers or {})}
- return await self._get(
- path_template("/agent/v1/run/{id}/events", id=id),
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._post(
+ path_template("/linc/v1/sessions/{id}/events/ingest", id=id),
+ body=await async_maybe_transform(
+ {"frames": frames}, session_ingest_events_params.SessionIngestEventsParams
+ ),
options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform({"last_event_id": last_event_id}, run_events_params.RunEventsParams),
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=str,
- stream=True,
- stream_cls=AsyncStream[RunEventsResponse],
+ cast_to=NoneType,
)
- async def exec(
+ async def retrieve_events(
self,
id: str,
*,
+ after_seq: int | Omit = omit,
+ cursor: int | Omit = omit,
+ exclude_event_types: SequenceNotStr[str] | Omit = omit,
+ limit: 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,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> RunExecResponse:
- """Starts execution of a queued run.
-
- The agent runs in a durable workflow — poll
- /run/:id/status for progress.
+ ) -> None:
+ """
+ Returns persisted native Pi/Linc event envelopes after the requested cursor.
+ Live delivery is handled by the Linc stream service.
Args:
+ after_seq: Alias for cursor. Ignored when cursor is also provided.
+
+ cursor: Replay events with a sequence number greater than this cursor.
+
+ exclude_event_types: Comma-separated Linc event types to omit from replay.
+
+ limit: Maximum number of events to return.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -651,30 +702,53 @@ async def exec(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return await self._post(
- path_template("/agent/v1/run/{id}/exec", id=id),
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._get(
+ path_template("/linc/v1/sessions/{id}/events", id=id),
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "after_seq": after_seq,
+ "cursor": cursor,
+ "exclude_event_types": exclude_event_types,
+ "limit": limit,
+ },
+ session_retrieve_events_params.SessionRetrieveEventsParams,
+ ),
),
- cast_to=RunExecResponse,
+ cast_to=NoneType,
)
- async def get_details(
+ async def retrieve_messages(
self,
id: str,
*,
+ after_seq: int | Omit = omit,
+ cursor: int | Omit = omit,
+ limit: 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,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> RunGetDetailsResponse:
+ ) -> None:
"""
- Full audit trail for a run including output, steps (tool calls, text), and token
- usage.
+ Returns completed Pi/Linc message entries derived from durable native Linc
+ events. This is the stable session-message read model for callers that need to
+ persist or recover chat history without depending on a live SSE stream.
Args:
+ after_seq: Alias for cursor. Ignored when cursor is also provided.
+
+ cursor: Replay messages with a source event sequence number greater than this cursor.
+
+ limit: Maximum number of source events to scan for completed messages.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -685,15 +759,27 @@ async def get_details(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._get(
- path_template("/agent/v1/run/{id}/details", id=id),
+ path_template("/linc/v1/sessions/{id}/messages", id=id),
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "after_seq": after_seq,
+ "cursor": cursor,
+ "limit": limit,
+ },
+ session_retrieve_messages_params.SessionRetrieveMessagesParams,
+ ),
),
- cast_to=RunGetDetailsResponse,
+ cast_to=NoneType,
)
- async def get_status(
+ async def retrieve_state(
self,
id: str,
*,
@@ -703,11 +789,9 @@ async def get_status(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> RunGetStatusResponse:
- """Lightweight status poll for a run.
-
- Use /run/:id/details for the full audit
- trail.
+ ) -> None:
+ """
+ Get native Linc session state
Args:
extra_headers: Send extra headers
@@ -720,33 +804,38 @@ async def get_status(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._get(
- path_template("/agent/v1/run/{id}/status", id=id),
+ path_template("/linc/v1/sessions/{id}/state", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=RunGetStatusResponse,
+ cast_to=NoneType,
)
- async def watch(
+ async def send_rpc(
self,
- id: str,
+ path_id: str,
*,
- callback_url: str,
+ type: str,
+ body_id: 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,
- ) -> RunWatchResponse:
- """Register a callback URL to receive notifications when the run completes.
-
- URL
- must use https and must not point to a private network.
+ ) -> None:
+ """
+ Forwards a native Pi/Linc RPC command object to the sandbox-local Linc bridge
+ unchanged. The route returns after Pi accepts or rejects the command; native
+ events are read through the events endpoint.
Args:
- callback_url: HTTPS URL to receive completion callback
+ type: Native Pi/Linc RPC command type. Prompt commands also require a string id for
+ idempotency.
+
+ body_id: Command idempotency key. Required when type is prompt.
extra_headers: Send extra headers
@@ -756,133 +845,140 @@ async def watch(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not id:
- raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ if not path_id:
+ raise ValueError(f"Expected a non-empty value for `path_id` but received {path_id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._post(
- path_template("/agent/v1/run/{id}/watch", id=id),
- body=await async_maybe_transform({"callback_url": callback_url}, run_watch_params.RunWatchParams),
+ path_template("/linc/v1/sessions/{path_id}/rpc", path_id=path_id),
+ body=await async_maybe_transform(
+ {
+ "type": type,
+ "body_id": body_id,
+ },
+ session_send_rpc_params.SessionSendRpcParams,
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=RunWatchResponse,
+ cast_to=NoneType,
)
-class RunResourceWithRawResponse:
- def __init__(self, run: RunResource) -> None:
- self._run = run
+class SessionsResourceWithRawResponse:
+ def __init__(self, sessions: SessionsResource) -> None:
+ self._sessions = sessions
self.create = to_raw_response_wrapper(
- run.create,
+ sessions.create,
)
- self.list = to_raw_response_wrapper(
- run.list,
+ self.delete = to_raw_response_wrapper(
+ sessions.delete,
)
self.cancel = to_raw_response_wrapper(
- run.cancel,
+ sessions.cancel,
)
- self.events = to_raw_response_wrapper(
- run.events,
+ self.ingest_events = to_raw_response_wrapper(
+ sessions.ingest_events,
)
- self.exec = to_raw_response_wrapper(
- run.exec,
+ self.retrieve_events = to_raw_response_wrapper(
+ sessions.retrieve_events,
)
- self.get_details = to_raw_response_wrapper(
- run.get_details,
+ self.retrieve_messages = to_raw_response_wrapper(
+ sessions.retrieve_messages,
)
- self.get_status = to_raw_response_wrapper(
- run.get_status,
+ self.retrieve_state = to_raw_response_wrapper(
+ sessions.retrieve_state,
)
- self.watch = to_raw_response_wrapper(
- run.watch,
+ self.send_rpc = to_raw_response_wrapper(
+ sessions.send_rpc,
)
-class AsyncRunResourceWithRawResponse:
- def __init__(self, run: AsyncRunResource) -> None:
- self._run = run
+class AsyncSessionsResourceWithRawResponse:
+ def __init__(self, sessions: AsyncSessionsResource) -> None:
+ self._sessions = sessions
self.create = async_to_raw_response_wrapper(
- run.create,
+ sessions.create,
)
- self.list = async_to_raw_response_wrapper(
- run.list,
+ self.delete = async_to_raw_response_wrapper(
+ sessions.delete,
)
self.cancel = async_to_raw_response_wrapper(
- run.cancel,
+ sessions.cancel,
)
- self.events = async_to_raw_response_wrapper(
- run.events,
+ self.ingest_events = async_to_raw_response_wrapper(
+ sessions.ingest_events,
)
- self.exec = async_to_raw_response_wrapper(
- run.exec,
+ self.retrieve_events = async_to_raw_response_wrapper(
+ sessions.retrieve_events,
)
- self.get_details = async_to_raw_response_wrapper(
- run.get_details,
+ self.retrieve_messages = async_to_raw_response_wrapper(
+ sessions.retrieve_messages,
)
- self.get_status = async_to_raw_response_wrapper(
- run.get_status,
+ self.retrieve_state = async_to_raw_response_wrapper(
+ sessions.retrieve_state,
)
- self.watch = async_to_raw_response_wrapper(
- run.watch,
+ self.send_rpc = async_to_raw_response_wrapper(
+ sessions.send_rpc,
)
-class RunResourceWithStreamingResponse:
- def __init__(self, run: RunResource) -> None:
- self._run = run
+class SessionsResourceWithStreamingResponse:
+ def __init__(self, sessions: SessionsResource) -> None:
+ self._sessions = sessions
self.create = to_streamed_response_wrapper(
- run.create,
+ sessions.create,
)
- self.list = to_streamed_response_wrapper(
- run.list,
+ self.delete = to_streamed_response_wrapper(
+ sessions.delete,
)
self.cancel = to_streamed_response_wrapper(
- run.cancel,
+ sessions.cancel,
)
- self.events = to_streamed_response_wrapper(
- run.events,
+ self.ingest_events = to_streamed_response_wrapper(
+ sessions.ingest_events,
)
- self.exec = to_streamed_response_wrapper(
- run.exec,
+ self.retrieve_events = to_streamed_response_wrapper(
+ sessions.retrieve_events,
)
- self.get_details = to_streamed_response_wrapper(
- run.get_details,
+ self.retrieve_messages = to_streamed_response_wrapper(
+ sessions.retrieve_messages,
)
- self.get_status = to_streamed_response_wrapper(
- run.get_status,
+ self.retrieve_state = to_streamed_response_wrapper(
+ sessions.retrieve_state,
)
- self.watch = to_streamed_response_wrapper(
- run.watch,
+ self.send_rpc = to_streamed_response_wrapper(
+ sessions.send_rpc,
)
-class AsyncRunResourceWithStreamingResponse:
- def __init__(self, run: AsyncRunResource) -> None:
- self._run = run
+class AsyncSessionsResourceWithStreamingResponse:
+ def __init__(self, sessions: AsyncSessionsResource) -> None:
+ self._sessions = sessions
self.create = async_to_streamed_response_wrapper(
- run.create,
+ sessions.create,
)
- self.list = async_to_streamed_response_wrapper(
- run.list,
+ self.delete = async_to_streamed_response_wrapper(
+ sessions.delete,
)
self.cancel = async_to_streamed_response_wrapper(
- run.cancel,
+ sessions.cancel,
)
- self.events = async_to_streamed_response_wrapper(
- run.events,
+ self.ingest_events = async_to_streamed_response_wrapper(
+ sessions.ingest_events,
)
- self.exec = async_to_streamed_response_wrapper(
- run.exec,
+ self.retrieve_events = async_to_streamed_response_wrapper(
+ sessions.retrieve_events,
)
- self.get_details = async_to_streamed_response_wrapper(
- run.get_details,
+ self.retrieve_messages = async_to_streamed_response_wrapper(
+ sessions.retrieve_messages,
)
- self.get_status = async_to_streamed_response_wrapper(
- run.get_status,
+ self.retrieve_state = async_to_streamed_response_wrapper(
+ sessions.retrieve_state,
)
- self.watch = async_to_streamed_response_wrapper(
- run.watch,
+ self.send_rpc = async_to_streamed_response_wrapper(
+ sessions.send_rpc,
)
diff --git a/src/casedev/resources/mail/v1/v1.py b/src/casedev/resources/linc/v1/v1.py
similarity index 59%
rename from src/casedev/resources/mail/v1/v1.py
rename to src/casedev/resources/linc/v1/v1.py
index 2bdc9298..6e356c43 100644
--- a/src/casedev/resources/mail/v1/v1.py
+++ b/src/casedev/resources/linc/v1/v1.py
@@ -2,13 +2,13 @@
from __future__ import annotations
-from .inboxes import (
- InboxesResource,
- AsyncInboxesResource,
- InboxesResourceWithRawResponse,
- AsyncInboxesResourceWithRawResponse,
- InboxesResourceWithStreamingResponse,
- AsyncInboxesResourceWithStreamingResponse,
+from .sessions import (
+ SessionsResource,
+ AsyncSessionsResource,
+ SessionsResourceWithRawResponse,
+ AsyncSessionsResourceWithRawResponse,
+ SessionsResourceWithStreamingResponse,
+ AsyncSessionsResourceWithStreamingResponse,
)
from ...._compat import cached_property
from ...._resource import SyncAPIResource, AsyncAPIResource
@@ -18,11 +18,9 @@
class V1Resource(SyncAPIResource):
@cached_property
- def inboxes(self) -> InboxesResource:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return InboxesResource(self._client)
+ def sessions(self) -> SessionsResource:
+ """Durable, stateful legal agent sessions with sandboxed tools and files"""
+ return SessionsResource(self._client)
@cached_property
def with_raw_response(self) -> V1ResourceWithRawResponse:
@@ -46,11 +44,9 @@ def with_streaming_response(self) -> V1ResourceWithStreamingResponse:
class AsyncV1Resource(AsyncAPIResource):
@cached_property
- def inboxes(self) -> AsyncInboxesResource:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return AsyncInboxesResource(self._client)
+ def sessions(self) -> AsyncSessionsResource:
+ """Durable, stateful legal agent sessions with sandboxed tools and files"""
+ return AsyncSessionsResource(self._client)
@cached_property
def with_raw_response(self) -> AsyncV1ResourceWithRawResponse:
@@ -77,11 +73,9 @@ def __init__(self, v1: V1Resource) -> None:
self._v1 = v1
@cached_property
- def inboxes(self) -> InboxesResourceWithRawResponse:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return InboxesResourceWithRawResponse(self._v1.inboxes)
+ def sessions(self) -> SessionsResourceWithRawResponse:
+ """Durable, stateful legal agent sessions with sandboxed tools and files"""
+ return SessionsResourceWithRawResponse(self._v1.sessions)
class AsyncV1ResourceWithRawResponse:
@@ -89,11 +83,9 @@ def __init__(self, v1: AsyncV1Resource) -> None:
self._v1 = v1
@cached_property
- def inboxes(self) -> AsyncInboxesResourceWithRawResponse:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return AsyncInboxesResourceWithRawResponse(self._v1.inboxes)
+ def sessions(self) -> AsyncSessionsResourceWithRawResponse:
+ """Durable, stateful legal agent sessions with sandboxed tools and files"""
+ return AsyncSessionsResourceWithRawResponse(self._v1.sessions)
class V1ResourceWithStreamingResponse:
@@ -101,11 +93,9 @@ def __init__(self, v1: V1Resource) -> None:
self._v1 = v1
@cached_property
- def inboxes(self) -> InboxesResourceWithStreamingResponse:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return InboxesResourceWithStreamingResponse(self._v1.inboxes)
+ def sessions(self) -> SessionsResourceWithStreamingResponse:
+ """Durable, stateful legal agent sessions with sandboxed tools and files"""
+ return SessionsResourceWithStreamingResponse(self._v1.sessions)
class AsyncV1ResourceWithStreamingResponse:
@@ -113,8 +103,6 @@ def __init__(self, v1: AsyncV1Resource) -> None:
self._v1 = v1
@cached_property
- def inboxes(self) -> AsyncInboxesResourceWithStreamingResponse:
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
- return AsyncInboxesResourceWithStreamingResponse(self._v1.inboxes)
+ def sessions(self) -> AsyncSessionsResourceWithStreamingResponse:
+ """Durable, stateful legal agent sessions with sandboxed tools and files"""
+ return AsyncSessionsResourceWithStreamingResponse(self._v1.sessions)
diff --git a/src/casedev/resources/llm/v1/chat.py b/src/casedev/resources/llm/v1/chat.py
index 10f4bde3..55a9d098 100644
--- a/src/casedev/resources/llm/v1/chat.py
+++ b/src/casedev/resources/llm/v1/chat.py
@@ -74,8 +74,9 @@ def create_completion(
Args:
messages: List of messages comprising the conversation
- casemark_show_reasoning: CaseMark-only: when true, allows reasoning fields in responses. Defaults to
- false (reasoning is suppressed).
+ casemark_show_reasoning: CaseMark-only: controls whether reasoning fields appear in responses. Defaults
+ to false (suppressed) for most CaseMark models; defaults to true for
+ casemark/core-potassium.
frequency_penalty: Frequency penalty parameter
@@ -173,8 +174,9 @@ async def create_completion(
Args:
messages: List of messages comprising the conversation
- casemark_show_reasoning: CaseMark-only: when true, allows reasoning fields in responses. Defaults to
- false (reasoning is suppressed).
+ casemark_show_reasoning: CaseMark-only: controls whether reasoning fields appear in responses. Defaults
+ to false (suppressed) for most CaseMark models; defaults to true for
+ casemark/core-potassium.
frequency_penalty: Frequency penalty parameter
diff --git a/src/casedev/resources/mail/v1/__init__.py b/src/casedev/resources/mail/v1/__init__.py
deleted file mode 100644
index fd8876c6..00000000
--- a/src/casedev/resources/mail/v1/__init__.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from .v1 import (
- V1Resource,
- AsyncV1Resource,
- V1ResourceWithRawResponse,
- AsyncV1ResourceWithRawResponse,
- V1ResourceWithStreamingResponse,
- AsyncV1ResourceWithStreamingResponse,
-)
-from .inboxes import (
- InboxesResource,
- AsyncInboxesResource,
- InboxesResourceWithRawResponse,
- AsyncInboxesResourceWithRawResponse,
- InboxesResourceWithStreamingResponse,
- AsyncInboxesResourceWithStreamingResponse,
-)
-
-__all__ = [
- "InboxesResource",
- "AsyncInboxesResource",
- "InboxesResourceWithRawResponse",
- "AsyncInboxesResourceWithRawResponse",
- "InboxesResourceWithStreamingResponse",
- "AsyncInboxesResourceWithStreamingResponse",
- "V1Resource",
- "AsyncV1Resource",
- "V1ResourceWithRawResponse",
- "AsyncV1ResourceWithRawResponse",
- "V1ResourceWithStreamingResponse",
- "AsyncV1ResourceWithStreamingResponse",
-]
diff --git a/src/casedev/resources/mail/v1/inboxes.py b/src/casedev/resources/mail/v1/inboxes.py
deleted file mode 100644
index c55c95a3..00000000
--- a/src/casedev/resources/mail/v1/inboxes.py
+++ /dev/null
@@ -1,1056 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import httpx
-
-from ...._types import Body, Omit, Query, Headers, NoneType, NotGiven, SequenceNotStr, omit, not_given
-from ...._utils import path_template, maybe_transform, async_maybe_transform
-from ...._compat import cached_property
-from ...._resource import SyncAPIResource, AsyncAPIResource
-from ...._response import (
- to_raw_response_wrapper,
- to_streamed_response_wrapper,
- async_to_raw_response_wrapper,
- async_to_streamed_response_wrapper,
-)
-from ...._base_client import make_request_options
-from ....types.mail.v1 import inbox_create_params, inbox_set_policy_params
-
-__all__ = ["InboxesResource", "AsyncInboxesResource"]
-
-
-class InboxesResource(SyncAPIResource):
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
-
- @cached_property
- def with_raw_response(self) -> InboxesResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
- """
- return InboxesResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> InboxesResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
- """
- return InboxesResourceWithStreamingResponse(self)
-
- def create(
- self,
- *,
- address: str | Omit = omit,
- display_name: 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,
- ) -> None:
- """
- Create an inbox owned by the authenticated organization.
-
- 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
- """
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return self._post(
- "/mail/v1/inboxes",
- body=maybe_transform(
- {
- "address": address,
- "display_name": display_name,
- },
- inbox_create_params.InboxCreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- def retrieve(
- self,
- inbox_id: str,
- *,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """
- Get an inbox owned by the authenticated organization.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not inbox_id:
- raise ValueError(f"Expected a non-empty value for `inbox_id` but received {inbox_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return self._get(
- path_template("/mail/v1/inboxes/{inbox_id}", inbox_id=inbox_id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- def list(
- self,
- *,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """List inboxes owned by the authenticated organization."""
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return self._get(
- "/mail/v1/inboxes",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- def delete(
- self,
- inbox_id: str,
- *,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """
- Delete an inbox owned by the authenticated organization.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not inbox_id:
- raise ValueError(f"Expected a non-empty value for `inbox_id` but received {inbox_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return self._delete(
- path_template("/mail/v1/inboxes/{inbox_id}", inbox_id=inbox_id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- def get_attachment(
- self,
- attachment_id: str,
- *,
- inbox_id: str,
- message_id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """
- Get attachment metadata for a message in an inbox owned by the authenticated
- organization.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not inbox_id:
- raise ValueError(f"Expected a non-empty value for `inbox_id` but received {inbox_id!r}")
- if not message_id:
- raise ValueError(f"Expected a non-empty value for `message_id` but received {message_id!r}")
- if not attachment_id:
- raise ValueError(f"Expected a non-empty value for `attachment_id` but received {attachment_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return self._get(
- path_template(
- "/mail/v1/inboxes/{inbox_id}/messages/{message_id}/attachments/{attachment_id}",
- inbox_id=inbox_id,
- message_id=message_id,
- attachment_id=attachment_id,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- def get_message(
- self,
- message_id: str,
- *,
- inbox_id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """
- Get a message for an inbox owned by the authenticated organization.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not inbox_id:
- raise ValueError(f"Expected a non-empty value for `inbox_id` but received {inbox_id!r}")
- if not message_id:
- raise ValueError(f"Expected a non-empty value for `message_id` but received {message_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return self._get(
- path_template(
- "/mail/v1/inboxes/{inbox_id}/messages/{message_id}", inbox_id=inbox_id, message_id=message_id
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- def get_policy(
- self,
- inbox_id: str,
- *,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """
- Get the sender allowlist and send/reply/read access rules for an inbox owned by
- the authenticated organization.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not inbox_id:
- raise ValueError(f"Expected a non-empty value for `inbox_id` but received {inbox_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return self._get(
- path_template("/mail/v1/inboxes/{inbox_id}/policy", inbox_id=inbox_id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- def list_messages(
- self,
- inbox_id: str,
- *,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """
- List messages for an inbox owned by the authenticated organization.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not inbox_id:
- raise ValueError(f"Expected a non-empty value for `inbox_id` but received {inbox_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return self._get(
- path_template("/mail/v1/inboxes/{inbox_id}/messages", inbox_id=inbox_id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- def reply(
- self,
- message_id: str,
- *,
- inbox_id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """
- Reply to a message in an inbox owned by the authenticated organization.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not inbox_id:
- raise ValueError(f"Expected a non-empty value for `inbox_id` but received {inbox_id!r}")
- if not message_id:
- raise ValueError(f"Expected a non-empty value for `message_id` but received {message_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return self._post(
- path_template(
- "/mail/v1/inboxes/{inbox_id}/messages/{message_id}/reply", inbox_id=inbox_id, message_id=message_id
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- def send(
- self,
- inbox_id: str,
- *,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """
- Send a message from an inbox owned by the authenticated organization.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not inbox_id:
- raise ValueError(f"Expected a non-empty value for `inbox_id` but received {inbox_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return self._post(
- path_template("/mail/v1/inboxes/{inbox_id}/messages/send", inbox_id=inbox_id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- def set_policy(
- self,
- inbox_id: str,
- *,
- allowed_sender_patterns: SequenceNotStr[str] | Omit = omit,
- enforce_sender_allowlist: bool | Omit = omit,
- read_access_rules: SequenceNotStr[str] | Omit = omit,
- reply_access_rules: SequenceNotStr[str] | Omit = omit,
- send_access_rules: SequenceNotStr[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,
- ) -> None:
- """
- Set the sender allowlist and send/reply/read access rules for an inbox owned by
- the authenticated organization.
-
- Args:
- allowed_sender_patterns: Exact emails, @domain rules, or \\**
-
- read_access_rules: Rules like organization, operator, user:, api_key, api_key:,
- clerk_session, or \\**
-
- reply_access_rules: Rules like organization, operator, user:, api_key, api_key:,
- clerk_session, or \\**
-
- send_access_rules: Rules like organization, user:, api_key, api_key:, clerk_session, or \\**
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not inbox_id:
- raise ValueError(f"Expected a non-empty value for `inbox_id` but received {inbox_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return self._put(
- path_template("/mail/v1/inboxes/{inbox_id}/policy", inbox_id=inbox_id),
- body=maybe_transform(
- {
- "allowed_sender_patterns": allowed_sender_patterns,
- "enforce_sender_allowlist": enforce_sender_allowlist,
- "read_access_rules": read_access_rules,
- "reply_access_rules": reply_access_rules,
- "send_access_rules": send_access_rules,
- },
- inbox_set_policy_params.InboxSetPolicyParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
-
-class AsyncInboxesResource(AsyncAPIResource):
- """
- Create, manage, and execute AI agents with tool access, sandbox environments, and async run workflows
- """
-
- @cached_property
- def with_raw_response(self) -> AsyncInboxesResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
- """
- return AsyncInboxesResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncInboxesResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
- """
- return AsyncInboxesResourceWithStreamingResponse(self)
-
- async def create(
- self,
- *,
- address: str | Omit = omit,
- display_name: 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,
- ) -> None:
- """
- Create an inbox owned by the authenticated organization.
-
- 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
- """
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return await self._post(
- "/mail/v1/inboxes",
- body=await async_maybe_transform(
- {
- "address": address,
- "display_name": display_name,
- },
- inbox_create_params.InboxCreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- async def retrieve(
- self,
- inbox_id: str,
- *,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """
- Get an inbox owned by the authenticated organization.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not inbox_id:
- raise ValueError(f"Expected a non-empty value for `inbox_id` but received {inbox_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return await self._get(
- path_template("/mail/v1/inboxes/{inbox_id}", inbox_id=inbox_id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- async def list(
- self,
- *,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """List inboxes owned by the authenticated organization."""
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return await self._get(
- "/mail/v1/inboxes",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- async def delete(
- self,
- inbox_id: str,
- *,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """
- Delete an inbox owned by the authenticated organization.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not inbox_id:
- raise ValueError(f"Expected a non-empty value for `inbox_id` but received {inbox_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return await self._delete(
- path_template("/mail/v1/inboxes/{inbox_id}", inbox_id=inbox_id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- async def get_attachment(
- self,
- attachment_id: str,
- *,
- inbox_id: str,
- message_id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """
- Get attachment metadata for a message in an inbox owned by the authenticated
- organization.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not inbox_id:
- raise ValueError(f"Expected a non-empty value for `inbox_id` but received {inbox_id!r}")
- if not message_id:
- raise ValueError(f"Expected a non-empty value for `message_id` but received {message_id!r}")
- if not attachment_id:
- raise ValueError(f"Expected a non-empty value for `attachment_id` but received {attachment_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return await self._get(
- path_template(
- "/mail/v1/inboxes/{inbox_id}/messages/{message_id}/attachments/{attachment_id}",
- inbox_id=inbox_id,
- message_id=message_id,
- attachment_id=attachment_id,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- async def get_message(
- self,
- message_id: str,
- *,
- inbox_id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """
- Get a message for an inbox owned by the authenticated organization.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not inbox_id:
- raise ValueError(f"Expected a non-empty value for `inbox_id` but received {inbox_id!r}")
- if not message_id:
- raise ValueError(f"Expected a non-empty value for `message_id` but received {message_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return await self._get(
- path_template(
- "/mail/v1/inboxes/{inbox_id}/messages/{message_id}", inbox_id=inbox_id, message_id=message_id
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- async def get_policy(
- self,
- inbox_id: str,
- *,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """
- Get the sender allowlist and send/reply/read access rules for an inbox owned by
- the authenticated organization.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not inbox_id:
- raise ValueError(f"Expected a non-empty value for `inbox_id` but received {inbox_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return await self._get(
- path_template("/mail/v1/inboxes/{inbox_id}/policy", inbox_id=inbox_id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- async def list_messages(
- self,
- inbox_id: str,
- *,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """
- List messages for an inbox owned by the authenticated organization.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not inbox_id:
- raise ValueError(f"Expected a non-empty value for `inbox_id` but received {inbox_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return await self._get(
- path_template("/mail/v1/inboxes/{inbox_id}/messages", inbox_id=inbox_id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- async def reply(
- self,
- message_id: str,
- *,
- inbox_id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """
- Reply to a message in an inbox owned by the authenticated organization.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not inbox_id:
- raise ValueError(f"Expected a non-empty value for `inbox_id` but received {inbox_id!r}")
- if not message_id:
- raise ValueError(f"Expected a non-empty value for `message_id` but received {message_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return await self._post(
- path_template(
- "/mail/v1/inboxes/{inbox_id}/messages/{message_id}/reply", inbox_id=inbox_id, message_id=message_id
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- async def send(
- self,
- inbox_id: str,
- *,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """
- Send a message from an inbox owned by the authenticated organization.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not inbox_id:
- raise ValueError(f"Expected a non-empty value for `inbox_id` but received {inbox_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return await self._post(
- path_template("/mail/v1/inboxes/{inbox_id}/messages/send", inbox_id=inbox_id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
- async def set_policy(
- self,
- inbox_id: str,
- *,
- allowed_sender_patterns: SequenceNotStr[str] | Omit = omit,
- enforce_sender_allowlist: bool | Omit = omit,
- read_access_rules: SequenceNotStr[str] | Omit = omit,
- reply_access_rules: SequenceNotStr[str] | Omit = omit,
- send_access_rules: SequenceNotStr[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,
- ) -> None:
- """
- Set the sender allowlist and send/reply/read access rules for an inbox owned by
- the authenticated organization.
-
- Args:
- allowed_sender_patterns: Exact emails, @domain rules, or \\**
-
- read_access_rules: Rules like organization, operator, user:, api_key, api_key:,
- clerk_session, or \\**
-
- reply_access_rules: Rules like organization, operator, user:, api_key, api_key:,
- clerk_session, or \\**
-
- send_access_rules: Rules like organization, user:, api_key, api_key:, clerk_session, or \\**
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not inbox_id:
- raise ValueError(f"Expected a non-empty value for `inbox_id` but received {inbox_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return await self._put(
- path_template("/mail/v1/inboxes/{inbox_id}/policy", inbox_id=inbox_id),
- body=await async_maybe_transform(
- {
- "allowed_sender_patterns": allowed_sender_patterns,
- "enforce_sender_allowlist": enforce_sender_allowlist,
- "read_access_rules": read_access_rules,
- "reply_access_rules": reply_access_rules,
- "send_access_rules": send_access_rules,
- },
- inbox_set_policy_params.InboxSetPolicyParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
-
-class InboxesResourceWithRawResponse:
- def __init__(self, inboxes: InboxesResource) -> None:
- self._inboxes = inboxes
-
- self.create = to_raw_response_wrapper(
- inboxes.create,
- )
- self.retrieve = to_raw_response_wrapper(
- inboxes.retrieve,
- )
- self.list = to_raw_response_wrapper(
- inboxes.list,
- )
- self.delete = to_raw_response_wrapper(
- inboxes.delete,
- )
- self.get_attachment = to_raw_response_wrapper(
- inboxes.get_attachment,
- )
- self.get_message = to_raw_response_wrapper(
- inboxes.get_message,
- )
- self.get_policy = to_raw_response_wrapper(
- inboxes.get_policy,
- )
- self.list_messages = to_raw_response_wrapper(
- inboxes.list_messages,
- )
- self.reply = to_raw_response_wrapper(
- inboxes.reply,
- )
- self.send = to_raw_response_wrapper(
- inboxes.send,
- )
- self.set_policy = to_raw_response_wrapper(
- inboxes.set_policy,
- )
-
-
-class AsyncInboxesResourceWithRawResponse:
- def __init__(self, inboxes: AsyncInboxesResource) -> None:
- self._inboxes = inboxes
-
- self.create = async_to_raw_response_wrapper(
- inboxes.create,
- )
- self.retrieve = async_to_raw_response_wrapper(
- inboxes.retrieve,
- )
- self.list = async_to_raw_response_wrapper(
- inboxes.list,
- )
- self.delete = async_to_raw_response_wrapper(
- inboxes.delete,
- )
- self.get_attachment = async_to_raw_response_wrapper(
- inboxes.get_attachment,
- )
- self.get_message = async_to_raw_response_wrapper(
- inboxes.get_message,
- )
- self.get_policy = async_to_raw_response_wrapper(
- inboxes.get_policy,
- )
- self.list_messages = async_to_raw_response_wrapper(
- inboxes.list_messages,
- )
- self.reply = async_to_raw_response_wrapper(
- inboxes.reply,
- )
- self.send = async_to_raw_response_wrapper(
- inboxes.send,
- )
- self.set_policy = async_to_raw_response_wrapper(
- inboxes.set_policy,
- )
-
-
-class InboxesResourceWithStreamingResponse:
- def __init__(self, inboxes: InboxesResource) -> None:
- self._inboxes = inboxes
-
- self.create = to_streamed_response_wrapper(
- inboxes.create,
- )
- self.retrieve = to_streamed_response_wrapper(
- inboxes.retrieve,
- )
- self.list = to_streamed_response_wrapper(
- inboxes.list,
- )
- self.delete = to_streamed_response_wrapper(
- inboxes.delete,
- )
- self.get_attachment = to_streamed_response_wrapper(
- inboxes.get_attachment,
- )
- self.get_message = to_streamed_response_wrapper(
- inboxes.get_message,
- )
- self.get_policy = to_streamed_response_wrapper(
- inboxes.get_policy,
- )
- self.list_messages = to_streamed_response_wrapper(
- inboxes.list_messages,
- )
- self.reply = to_streamed_response_wrapper(
- inboxes.reply,
- )
- self.send = to_streamed_response_wrapper(
- inboxes.send,
- )
- self.set_policy = to_streamed_response_wrapper(
- inboxes.set_policy,
- )
-
-
-class AsyncInboxesResourceWithStreamingResponse:
- def __init__(self, inboxes: AsyncInboxesResource) -> None:
- self._inboxes = inboxes
-
- self.create = async_to_streamed_response_wrapper(
- inboxes.create,
- )
- self.retrieve = async_to_streamed_response_wrapper(
- inboxes.retrieve,
- )
- self.list = async_to_streamed_response_wrapper(
- inboxes.list,
- )
- self.delete = async_to_streamed_response_wrapper(
- inboxes.delete,
- )
- self.get_attachment = async_to_streamed_response_wrapper(
- inboxes.get_attachment,
- )
- self.get_message = async_to_streamed_response_wrapper(
- inboxes.get_message,
- )
- self.get_policy = async_to_streamed_response_wrapper(
- inboxes.get_policy,
- )
- self.list_messages = async_to_streamed_response_wrapper(
- inboxes.list_messages,
- )
- self.reply = async_to_streamed_response_wrapper(
- inboxes.reply,
- )
- self.send = async_to_streamed_response_wrapper(
- inboxes.send,
- )
- self.set_policy = async_to_streamed_response_wrapper(
- inboxes.set_policy,
- )
diff --git a/src/casedev/resources/matters/v1/work_items.py b/src/casedev/resources/matters/v1/work_items.py
index 9057488e..8a56f1fd 100644
--- a/src/casedev/resources/matters/v1/work_items.py
+++ b/src/casedev/resources/matters/v1/work_items.py
@@ -269,8 +269,7 @@ def decide(
work_item_id: str,
*,
id: str,
- decision: Literal["approve", "revise", "block", "reassign"],
- agent_type_id: Optional[str] | Omit = omit,
+ decision: Literal["approve", "block"],
metadata: Dict[str, object] | Omit = omit,
reason: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -280,10 +279,8 @@ def decide(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> None:
- """Approve, revise, block, or reassign a work item.
-
- Used by humans or agents to
- move work items through their lifecycle.
+ """
+ Approve or block a work item.
Args:
extra_headers: Send extra headers
@@ -304,7 +301,6 @@ def decide(
body=maybe_transform(
{
"decision": decision,
- "agent_type_id": agent_type_id,
"metadata": metadata,
"reason": reason,
},
@@ -316,43 +312,6 @@ def decide(
cast_to=NoneType,
)
- def list_executions(
- self,
- work_item_id: str,
- *,
- id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """
- List execution attempts for a work item, including agent and run linkage.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not id:
- raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- if not work_item_id:
- raise ValueError(f"Expected a non-empty value for `work_item_id` but received {work_item_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return self._get(
- path_template("/matters/v1/{id}/work-items/{work_item_id}/executions", id=id, work_item_id=work_item_id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
class AsyncWorkItemsResource(AsyncAPIResource):
"""Matter-native legal workspaces and orchestration primitives"""
@@ -594,8 +553,7 @@ async def decide(
work_item_id: str,
*,
id: str,
- decision: Literal["approve", "revise", "block", "reassign"],
- agent_type_id: Optional[str] | Omit = omit,
+ decision: Literal["approve", "block"],
metadata: Dict[str, object] | Omit = omit,
reason: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -605,10 +563,8 @@ async def decide(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> None:
- """Approve, revise, block, or reassign a work item.
-
- Used by humans or agents to
- move work items through their lifecycle.
+ """
+ Approve or block a work item.
Args:
extra_headers: Send extra headers
@@ -629,7 +585,6 @@ async def decide(
body=await async_maybe_transform(
{
"decision": decision,
- "agent_type_id": agent_type_id,
"metadata": metadata,
"reason": reason,
},
@@ -641,43 +596,6 @@ async def decide(
cast_to=NoneType,
)
- async def list_executions(
- self,
- work_item_id: str,
- *,
- id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """
- List execution attempts for a work item, including agent and run linkage.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not id:
- raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- if not work_item_id:
- raise ValueError(f"Expected a non-empty value for `work_item_id` but received {work_item_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
- return await self._get(
- path_template("/matters/v1/{id}/work-items/{work_item_id}/executions", id=id, work_item_id=work_item_id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=NoneType,
- )
-
class WorkItemsResourceWithRawResponse:
def __init__(self, work_items: WorkItemsResource) -> None:
@@ -698,9 +616,6 @@ def __init__(self, work_items: WorkItemsResource) -> None:
self.decide = to_raw_response_wrapper(
work_items.decide,
)
- self.list_executions = to_raw_response_wrapper(
- work_items.list_executions,
- )
class AsyncWorkItemsResourceWithRawResponse:
@@ -722,9 +637,6 @@ def __init__(self, work_items: AsyncWorkItemsResource) -> None:
self.decide = async_to_raw_response_wrapper(
work_items.decide,
)
- self.list_executions = async_to_raw_response_wrapper(
- work_items.list_executions,
- )
class WorkItemsResourceWithStreamingResponse:
@@ -746,9 +658,6 @@ def __init__(self, work_items: WorkItemsResource) -> None:
self.decide = to_streamed_response_wrapper(
work_items.decide,
)
- self.list_executions = to_streamed_response_wrapper(
- work_items.list_executions,
- )
class AsyncWorkItemsResourceWithStreamingResponse:
@@ -770,6 +679,3 @@ def __init__(self, work_items: AsyncWorkItemsResource) -> None:
self.decide = async_to_streamed_response_wrapper(
work_items.decide,
)
- self.list_executions = async_to_streamed_response_wrapper(
- work_items.list_executions,
- )
diff --git a/src/casedev/resources/media/v1/clips.py b/src/casedev/resources/media/v1/clips.py
index eb973be0..f8bfd21c 100644
--- a/src/casedev/resources/media/v1/clips.py
+++ b/src/casedev/resources/media/v1/clips.py
@@ -20,6 +20,8 @@
class ClipsResource(SyncAPIResource):
+ """Transcript retrieval and captioned media clip generation"""
+
@cached_property
def with_raw_response(self) -> ClipsResourceWithRawResponse:
"""
@@ -95,6 +97,8 @@ def retrieve(
class AsyncClipsResource(AsyncAPIResource):
+ """Transcript retrieval and captioned media clip generation"""
+
@cached_property
def with_raw_response(self) -> AsyncClipsResourceWithRawResponse:
"""
diff --git a/src/casedev/resources/media/v1/transcripts/__init__.py b/src/casedev/resources/media/v1/transcripts/__init__.py
index f957041b..33a94bae 100644
--- a/src/casedev/resources/media/v1/transcripts/__init__.py
+++ b/src/casedev/resources/media/v1/transcripts/__init__.py
@@ -8,6 +8,14 @@
SearchResourceWithStreamingResponse,
AsyncSearchResourceWithStreamingResponse,
)
+from .retrieve import (
+ RetrieveResource,
+ AsyncRetrieveResource,
+ RetrieveResourceWithRawResponse,
+ AsyncRetrieveResourceWithRawResponse,
+ RetrieveResourceWithStreamingResponse,
+ AsyncRetrieveResourceWithStreamingResponse,
+)
from .transcripts import (
TranscriptsResource,
AsyncTranscriptsResource,
@@ -24,6 +32,12 @@
"AsyncSearchResourceWithRawResponse",
"SearchResourceWithStreamingResponse",
"AsyncSearchResourceWithStreamingResponse",
+ "RetrieveResource",
+ "AsyncRetrieveResource",
+ "RetrieveResourceWithRawResponse",
+ "AsyncRetrieveResourceWithRawResponse",
+ "RetrieveResourceWithStreamingResponse",
+ "AsyncRetrieveResourceWithStreamingResponse",
"TranscriptsResource",
"AsyncTranscriptsResource",
"TranscriptsResourceWithRawResponse",
diff --git a/src/casedev/resources/media/v1/transcripts/retrieve.py b/src/casedev/resources/media/v1/transcripts/retrieve.py
new file mode 100644
index 00000000..72615a57
--- /dev/null
+++ b/src/casedev/resources/media/v1/transcripts/retrieve.py
@@ -0,0 +1,203 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from ....._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ....._utils import maybe_transform, async_maybe_transform
+from ....._compat import cached_property
+from ....._resource import SyncAPIResource, AsyncAPIResource
+from ....._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ....._base_client import make_request_options
+from .....types.media.v1.transcripts import retrieve_create_params
+from .....types.media.v1.transcripts.retrieve_create_response import RetrieveCreateResponse
+
+__all__ = ["RetrieveResource", "AsyncRetrieveResource"]
+
+
+class RetrieveResource(SyncAPIResource):
+ """Transcript retrieval and captioned media clip generation"""
+
+ @cached_property
+ def with_raw_response(self) -> RetrieveResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
+ """
+ return RetrieveResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> RetrieveResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
+ """
+ return RetrieveResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ object_id: str,
+ vault_id: str,
+ transcript: retrieve_create_params.Transcript | 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,
+ ) -> RetrieveCreateResponse:
+ """
+ Retrieves the full transcript text for a vault transcript object or an
+ audio/video source object with a completed transcription job. When object_id is
+ a source media object, access to that source object grants access to its
+ generated transcript artifact.
+
+ Args:
+ object_id: Object ID for either the source audio/video file or transcript artifact.
+
+ vault_id: Vault ID containing the source media or transcript object.
+
+ transcript: Alternative nested transcript object reference.
+
+ 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(
+ "/media/v1/transcripts/retrieve",
+ body=maybe_transform(
+ {
+ "object_id": object_id,
+ "vault_id": vault_id,
+ "transcript": transcript,
+ },
+ retrieve_create_params.RetrieveCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=RetrieveCreateResponse,
+ )
+
+
+class AsyncRetrieveResource(AsyncAPIResource):
+ """Transcript retrieval and captioned media clip generation"""
+
+ @cached_property
+ def with_raw_response(self) -> AsyncRetrieveResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncRetrieveResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncRetrieveResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
+ """
+ return AsyncRetrieveResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ *,
+ object_id: str,
+ vault_id: str,
+ transcript: retrieve_create_params.Transcript | 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,
+ ) -> RetrieveCreateResponse:
+ """
+ Retrieves the full transcript text for a vault transcript object or an
+ audio/video source object with a completed transcription job. When object_id is
+ a source media object, access to that source object grants access to its
+ generated transcript artifact.
+
+ Args:
+ object_id: Object ID for either the source audio/video file or transcript artifact.
+
+ vault_id: Vault ID containing the source media or transcript object.
+
+ transcript: Alternative nested transcript object reference.
+
+ 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(
+ "/media/v1/transcripts/retrieve",
+ body=await async_maybe_transform(
+ {
+ "object_id": object_id,
+ "vault_id": vault_id,
+ "transcript": transcript,
+ },
+ retrieve_create_params.RetrieveCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=RetrieveCreateResponse,
+ )
+
+
+class RetrieveResourceWithRawResponse:
+ def __init__(self, retrieve: RetrieveResource) -> None:
+ self._retrieve = retrieve
+
+ self.create = to_raw_response_wrapper(
+ retrieve.create,
+ )
+
+
+class AsyncRetrieveResourceWithRawResponse:
+ def __init__(self, retrieve: AsyncRetrieveResource) -> None:
+ self._retrieve = retrieve
+
+ self.create = async_to_raw_response_wrapper(
+ retrieve.create,
+ )
+
+
+class RetrieveResourceWithStreamingResponse:
+ def __init__(self, retrieve: RetrieveResource) -> None:
+ self._retrieve = retrieve
+
+ self.create = to_streamed_response_wrapper(
+ retrieve.create,
+ )
+
+
+class AsyncRetrieveResourceWithStreamingResponse:
+ def __init__(self, retrieve: AsyncRetrieveResource) -> None:
+ self._retrieve = retrieve
+
+ self.create = async_to_streamed_response_wrapper(
+ retrieve.create,
+ )
diff --git a/src/casedev/resources/media/v1/transcripts/search.py b/src/casedev/resources/media/v1/transcripts/search.py
index 6e5854ca..5375797c 100644
--- a/src/casedev/resources/media/v1/transcripts/search.py
+++ b/src/casedev/resources/media/v1/transcripts/search.py
@@ -19,6 +19,8 @@
class SearchResource(SyncAPIResource):
+ """Transcript retrieval and captioned media clip generation"""
+
@cached_property
def with_raw_response(self) -> SearchResourceWithRawResponse:
"""
@@ -60,6 +62,8 @@ def create(
class AsyncSearchResource(AsyncAPIResource):
+ """Transcript retrieval and captioned media clip generation"""
+
@cached_property
def with_raw_response(self) -> AsyncSearchResourceWithRawResponse:
"""
diff --git a/src/casedev/resources/media/v1/transcripts/transcripts.py b/src/casedev/resources/media/v1/transcripts/transcripts.py
index f5423428..f3a14fca 100644
--- a/src/casedev/resources/media/v1/transcripts/transcripts.py
+++ b/src/casedev/resources/media/v1/transcripts/transcripts.py
@@ -10,6 +10,14 @@
SearchResourceWithStreamingResponse,
AsyncSearchResourceWithStreamingResponse,
)
+from .retrieve import (
+ RetrieveResource,
+ AsyncRetrieveResource,
+ RetrieveResourceWithRawResponse,
+ AsyncRetrieveResourceWithRawResponse,
+ RetrieveResourceWithStreamingResponse,
+ AsyncRetrieveResourceWithStreamingResponse,
+)
from ....._compat import cached_property
from ....._resource import SyncAPIResource, AsyncAPIResource
@@ -19,8 +27,14 @@
class TranscriptsResource(SyncAPIResource):
@cached_property
def search(self) -> SearchResource:
+ """Transcript retrieval and captioned media clip generation"""
return SearchResource(self._client)
+ @cached_property
+ def retrieve(self) -> RetrieveResource:
+ """Transcript retrieval and captioned media clip generation"""
+ return RetrieveResource(self._client)
+
@cached_property
def with_raw_response(self) -> TranscriptsResourceWithRawResponse:
"""
@@ -44,8 +58,14 @@ def with_streaming_response(self) -> TranscriptsResourceWithStreamingResponse:
class AsyncTranscriptsResource(AsyncAPIResource):
@cached_property
def search(self) -> AsyncSearchResource:
+ """Transcript retrieval and captioned media clip generation"""
return AsyncSearchResource(self._client)
+ @cached_property
+ def retrieve(self) -> AsyncRetrieveResource:
+ """Transcript retrieval and captioned media clip generation"""
+ return AsyncRetrieveResource(self._client)
+
@cached_property
def with_raw_response(self) -> AsyncTranscriptsResourceWithRawResponse:
"""
@@ -72,8 +92,14 @@ def __init__(self, transcripts: TranscriptsResource) -> None:
@cached_property
def search(self) -> SearchResourceWithRawResponse:
+ """Transcript retrieval and captioned media clip generation"""
return SearchResourceWithRawResponse(self._transcripts.search)
+ @cached_property
+ def retrieve(self) -> RetrieveResourceWithRawResponse:
+ """Transcript retrieval and captioned media clip generation"""
+ return RetrieveResourceWithRawResponse(self._transcripts.retrieve)
+
class AsyncTranscriptsResourceWithRawResponse:
def __init__(self, transcripts: AsyncTranscriptsResource) -> None:
@@ -81,8 +107,14 @@ def __init__(self, transcripts: AsyncTranscriptsResource) -> None:
@cached_property
def search(self) -> AsyncSearchResourceWithRawResponse:
+ """Transcript retrieval and captioned media clip generation"""
return AsyncSearchResourceWithRawResponse(self._transcripts.search)
+ @cached_property
+ def retrieve(self) -> AsyncRetrieveResourceWithRawResponse:
+ """Transcript retrieval and captioned media clip generation"""
+ return AsyncRetrieveResourceWithRawResponse(self._transcripts.retrieve)
+
class TranscriptsResourceWithStreamingResponse:
def __init__(self, transcripts: TranscriptsResource) -> None:
@@ -90,8 +122,14 @@ def __init__(self, transcripts: TranscriptsResource) -> None:
@cached_property
def search(self) -> SearchResourceWithStreamingResponse:
+ """Transcript retrieval and captioned media clip generation"""
return SearchResourceWithStreamingResponse(self._transcripts.search)
+ @cached_property
+ def retrieve(self) -> RetrieveResourceWithStreamingResponse:
+ """Transcript retrieval and captioned media clip generation"""
+ return RetrieveResourceWithStreamingResponse(self._transcripts.retrieve)
+
class AsyncTranscriptsResourceWithStreamingResponse:
def __init__(self, transcripts: AsyncTranscriptsResource) -> None:
@@ -99,4 +137,10 @@ def __init__(self, transcripts: AsyncTranscriptsResource) -> None:
@cached_property
def search(self) -> AsyncSearchResourceWithStreamingResponse:
+ """Transcript retrieval and captioned media clip generation"""
return AsyncSearchResourceWithStreamingResponse(self._transcripts.search)
+
+ @cached_property
+ def retrieve(self) -> AsyncRetrieveResourceWithStreamingResponse:
+ """Transcript retrieval and captioned media clip generation"""
+ return AsyncRetrieveResourceWithStreamingResponse(self._transcripts.retrieve)
diff --git a/src/casedev/resources/media/v1/v1.py b/src/casedev/resources/media/v1/v1.py
index b506b4bc..b05a90d7 100644
--- a/src/casedev/resources/media/v1/v1.py
+++ b/src/casedev/resources/media/v1/v1.py
@@ -27,6 +27,7 @@
class V1Resource(SyncAPIResource):
@cached_property
def clips(self) -> ClipsResource:
+ """Transcript retrieval and captioned media clip generation"""
return ClipsResource(self._client)
@cached_property
@@ -56,6 +57,7 @@ def with_streaming_response(self) -> V1ResourceWithStreamingResponse:
class AsyncV1Resource(AsyncAPIResource):
@cached_property
def clips(self) -> AsyncClipsResource:
+ """Transcript retrieval and captioned media clip generation"""
return AsyncClipsResource(self._client)
@cached_property
@@ -88,6 +90,7 @@ def __init__(self, v1: V1Resource) -> None:
@cached_property
def clips(self) -> ClipsResourceWithRawResponse:
+ """Transcript retrieval and captioned media clip generation"""
return ClipsResourceWithRawResponse(self._v1.clips)
@cached_property
@@ -101,6 +104,7 @@ def __init__(self, v1: AsyncV1Resource) -> None:
@cached_property
def clips(self) -> AsyncClipsResourceWithRawResponse:
+ """Transcript retrieval and captioned media clip generation"""
return AsyncClipsResourceWithRawResponse(self._v1.clips)
@cached_property
@@ -114,6 +118,7 @@ def __init__(self, v1: V1Resource) -> None:
@cached_property
def clips(self) -> ClipsResourceWithStreamingResponse:
+ """Transcript retrieval and captioned media clip generation"""
return ClipsResourceWithStreamingResponse(self._v1.clips)
@cached_property
@@ -127,6 +132,7 @@ def __init__(self, v1: AsyncV1Resource) -> None:
@cached_property
def clips(self) -> AsyncClipsResourceWithStreamingResponse:
+ """Transcript retrieval and captioned media clip generation"""
return AsyncClipsResourceWithStreamingResponse(self._v1.clips)
@cached_property
diff --git a/src/casedev/resources/ocr/v1.py b/src/casedev/resources/ocr/v1.py
index 0b727b62..8ccb4e78 100644
--- a/src/casedev/resources/ocr/v1.py
+++ b/src/casedev/resources/ocr/v1.py
@@ -68,11 +68,11 @@ def retrieve(
) -> V1RetrieveResponse:
"""Retrieve the status and results of an OCR job.
- Returns job progress, extracted
- text, and metadata when processing is complete.
+ Returns job progress and
+ metadata; full extracted text is included only when include_text=true.
Args:
- include_text: Include full OCR text in completed responses (default: true)
+ include_text: Include full OCR text in completed responses (default: false)
extra_headers: Send extra headers
@@ -236,11 +236,11 @@ async def retrieve(
) -> V1RetrieveResponse:
"""Retrieve the status and results of an OCR job.
- Returns job progress, extracted
- text, and metadata when processing is complete.
+ Returns job progress and
+ metadata; full extracted text is included only when include_text=true.
Args:
- include_text: Include full OCR text in completed responses (default: true)
+ include_text: Include full OCR text in completed responses (default: false)
extra_headers: Send extra headers
diff --git a/src/casedev/resources/search/search.py b/src/casedev/resources/search/search.py
index d1cab2aa..28dbc2ba 100644
--- a/src/casedev/resources/search/search.py
+++ b/src/casedev/resources/search/search.py
@@ -19,7 +19,7 @@
class SearchResource(SyncAPIResource):
@cached_property
def v1(self) -> V1Resource:
- """Web search, AI answers, and deep research"""
+ """Web search and AI answers"""
return V1Resource(self._client)
@cached_property
@@ -45,7 +45,7 @@ def with_streaming_response(self) -> SearchResourceWithStreamingResponse:
class AsyncSearchResource(AsyncAPIResource):
@cached_property
def v1(self) -> AsyncV1Resource:
- """Web search, AI answers, and deep research"""
+ """Web search and AI answers"""
return AsyncV1Resource(self._client)
@cached_property
@@ -74,7 +74,7 @@ def __init__(self, search: SearchResource) -> None:
@cached_property
def v1(self) -> V1ResourceWithRawResponse:
- """Web search, AI answers, and deep research"""
+ """Web search and AI answers"""
return V1ResourceWithRawResponse(self._search.v1)
@@ -84,7 +84,7 @@ def __init__(self, search: AsyncSearchResource) -> None:
@cached_property
def v1(self) -> AsyncV1ResourceWithRawResponse:
- """Web search, AI answers, and deep research"""
+ """Web search and AI answers"""
return AsyncV1ResourceWithRawResponse(self._search.v1)
@@ -94,7 +94,7 @@ def __init__(self, search: SearchResource) -> None:
@cached_property
def v1(self) -> V1ResourceWithStreamingResponse:
- """Web search, AI answers, and deep research"""
+ """Web search and AI answers"""
return V1ResourceWithStreamingResponse(self._search.v1)
@@ -104,5 +104,5 @@ def __init__(self, search: AsyncSearchResource) -> None:
@cached_property
def v1(self) -> AsyncV1ResourceWithStreamingResponse:
- """Web search, AI answers, and deep research"""
+ """Web search and AI answers"""
return AsyncV1ResourceWithStreamingResponse(self._search.v1)
diff --git a/src/casedev/resources/search/v1.py b/src/casedev/resources/search/v1.py
index 2a55097f..a45aac49 100644
--- a/src/casedev/resources/search/v1.py
+++ b/src/casedev/resources/search/v1.py
@@ -9,7 +9,7 @@
import httpx
from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from ..._utils import path_template, maybe_transform, async_maybe_transform
+from ..._utils import maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import (
@@ -19,26 +19,17 @@
async_to_streamed_response_wrapper,
)
from ..._base_client import make_request_options
-from ...types.search import (
- v1_answer_params,
- v1_search_params,
- v1_similar_params,
- v1_contents_params,
- v1_research_params,
- v1_retrieve_research_params,
-)
+from ...types.search import v1_answer_params, v1_search_params, v1_similar_params, v1_contents_params
from ...types.search.v1_answer_response import V1AnswerResponse
from ...types.search.v1_search_response import V1SearchResponse
from ...types.search.v1_similar_response import V1SimilarResponse
from ...types.search.v1_contents_response import V1ContentsResponse
-from ...types.search.v1_research_response import V1ResearchResponse
-from ...types.search.v1_retrieve_research_response import V1RetrieveResearchResponse
__all__ = ["V1Resource", "AsyncV1Resource"]
class V1Resource(SyncAPIResource):
- """Web search, AI answers, and deep research"""
+ """Web search and AI answers"""
@cached_property
def with_raw_response(self) -> V1ResourceWithRawResponse:
@@ -220,112 +211,6 @@ def contents(
cast_to=V1ContentsResponse,
)
- def research(
- self,
- *,
- instructions: str,
- model: Literal["fast", "normal", "pro"] | Omit = omit,
- output_schema: object | Omit = omit,
- query: 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,
- ) -> V1ResearchResponse:
- """
- Performs deep research by conducting multi-step analysis, gathering information
- from multiple sources, and providing comprehensive insights. Ideal for legal
- research, case analysis, and due diligence investigations.
-
- Args:
- instructions: Research instructions or query
-
- model: Research quality level - fast (quick), normal (balanced), pro (comprehensive)
-
- output_schema: Optional JSON schema to structure the research output
-
- query: Alias for instructions (for convenience)
-
- 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(
- "/search/v1/research",
- body=maybe_transform(
- {
- "instructions": instructions,
- "model": model,
- "output_schema": output_schema,
- "query": query,
- },
- v1_research_params.V1ResearchParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=V1ResearchResponse,
- )
-
- def retrieve_research(
- self,
- id: str,
- *,
- events: str | Omit = omit,
- stream: bool | 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,
- ) -> V1RetrieveResearchResponse:
- """Retrieve the status and results of a deep research task by ID.
-
- Supports both
- standard JSON responses and streaming for real-time updates as the research
- progresses. Research tasks analyze topics comprehensively using web search and
- AI synthesis.
-
- Args:
- events: Filter specific event types for streaming
-
- stream: Enable streaming for real-time updates
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not id:
- raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return self._get(
- path_template("/search/v1/research/{id}", id=id),
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "events": events,
- "stream": stream,
- },
- v1_retrieve_research_params.V1RetrieveResearchParams,
- ),
- ),
- cast_to=V1RetrieveResearchResponse,
- )
-
def search(
self,
*,
@@ -499,7 +384,7 @@ def similar(
class AsyncV1Resource(AsyncAPIResource):
- """Web search, AI answers, and deep research"""
+ """Web search and AI answers"""
@cached_property
def with_raw_response(self) -> AsyncV1ResourceWithRawResponse:
@@ -681,112 +566,6 @@ async def contents(
cast_to=V1ContentsResponse,
)
- async def research(
- self,
- *,
- instructions: str,
- model: Literal["fast", "normal", "pro"] | Omit = omit,
- output_schema: object | Omit = omit,
- query: 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,
- ) -> V1ResearchResponse:
- """
- Performs deep research by conducting multi-step analysis, gathering information
- from multiple sources, and providing comprehensive insights. Ideal for legal
- research, case analysis, and due diligence investigations.
-
- Args:
- instructions: Research instructions or query
-
- model: Research quality level - fast (quick), normal (balanced), pro (comprehensive)
-
- output_schema: Optional JSON schema to structure the research output
-
- query: Alias for instructions (for convenience)
-
- 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(
- "/search/v1/research",
- body=await async_maybe_transform(
- {
- "instructions": instructions,
- "model": model,
- "output_schema": output_schema,
- "query": query,
- },
- v1_research_params.V1ResearchParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=V1ResearchResponse,
- )
-
- async def retrieve_research(
- self,
- id: str,
- *,
- events: str | Omit = omit,
- stream: bool | 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,
- ) -> V1RetrieveResearchResponse:
- """Retrieve the status and results of a deep research task by ID.
-
- Supports both
- standard JSON responses and streaming for real-time updates as the research
- progresses. Research tasks analyze topics comprehensively using web search and
- AI synthesis.
-
- Args:
- events: Filter specific event types for streaming
-
- stream: Enable streaming for real-time updates
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not id:
- raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return await self._get(
- path_template("/search/v1/research/{id}", id=id),
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {
- "events": events,
- "stream": stream,
- },
- v1_retrieve_research_params.V1RetrieveResearchParams,
- ),
- ),
- cast_to=V1RetrieveResearchResponse,
- )
-
async def search(
self,
*,
@@ -969,12 +748,6 @@ def __init__(self, v1: V1Resource) -> None:
self.contents = to_raw_response_wrapper(
v1.contents,
)
- self.research = to_raw_response_wrapper(
- v1.research,
- )
- self.retrieve_research = to_raw_response_wrapper(
- v1.retrieve_research,
- )
self.search = to_raw_response_wrapper(
v1.search,
)
@@ -993,12 +766,6 @@ def __init__(self, v1: AsyncV1Resource) -> None:
self.contents = async_to_raw_response_wrapper(
v1.contents,
)
- self.research = async_to_raw_response_wrapper(
- v1.research,
- )
- self.retrieve_research = async_to_raw_response_wrapper(
- v1.retrieve_research,
- )
self.search = async_to_raw_response_wrapper(
v1.search,
)
@@ -1017,12 +784,6 @@ def __init__(self, v1: V1Resource) -> None:
self.contents = to_streamed_response_wrapper(
v1.contents,
)
- self.research = to_streamed_response_wrapper(
- v1.research,
- )
- self.retrieve_research = to_streamed_response_wrapper(
- v1.retrieve_research,
- )
self.search = to_streamed_response_wrapper(
v1.search,
)
@@ -1041,12 +802,6 @@ def __init__(self, v1: AsyncV1Resource) -> None:
self.contents = async_to_streamed_response_wrapper(
v1.contents,
)
- self.research = async_to_streamed_response_wrapper(
- v1.research,
- )
- self.retrieve_research = async_to_streamed_response_wrapper(
- v1.retrieve_research,
- )
self.search = async_to_streamed_response_wrapper(
v1.search,
)
diff --git a/src/casedev/resources/superdoc/__init__.py b/src/casedev/resources/superdoc/__init__.py
deleted file mode 100644
index 18e3a98c..00000000
--- a/src/casedev/resources/superdoc/__init__.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from .v1 import (
- V1Resource,
- AsyncV1Resource,
- V1ResourceWithRawResponse,
- AsyncV1ResourceWithRawResponse,
- V1ResourceWithStreamingResponse,
- AsyncV1ResourceWithStreamingResponse,
-)
-from .superdoc import (
- SuperdocResource,
- AsyncSuperdocResource,
- SuperdocResourceWithRawResponse,
- AsyncSuperdocResourceWithRawResponse,
- SuperdocResourceWithStreamingResponse,
- AsyncSuperdocResourceWithStreamingResponse,
-)
-
-__all__ = [
- "V1Resource",
- "AsyncV1Resource",
- "V1ResourceWithRawResponse",
- "AsyncV1ResourceWithRawResponse",
- "V1ResourceWithStreamingResponse",
- "AsyncV1ResourceWithStreamingResponse",
- "SuperdocResource",
- "AsyncSuperdocResource",
- "SuperdocResourceWithRawResponse",
- "AsyncSuperdocResourceWithRawResponse",
- "SuperdocResourceWithStreamingResponse",
- "AsyncSuperdocResourceWithStreamingResponse",
-]
diff --git a/src/casedev/resources/superdoc/superdoc.py b/src/casedev/resources/superdoc/superdoc.py
deleted file mode 100644
index 560543a1..00000000
--- a/src/casedev/resources/superdoc/superdoc.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from .v1 import (
- V1Resource,
- AsyncV1Resource,
- V1ResourceWithRawResponse,
- AsyncV1ResourceWithRawResponse,
- V1ResourceWithStreamingResponse,
- AsyncV1ResourceWithStreamingResponse,
-)
-from ..._compat import cached_property
-from ..._resource import SyncAPIResource, AsyncAPIResource
-
-__all__ = ["SuperdocResource", "AsyncSuperdocResource"]
-
-
-class SuperdocResource(SyncAPIResource):
- @cached_property
- def v1(self) -> V1Resource:
- """Document conversion and template automation"""
- return V1Resource(self._client)
-
- @cached_property
- def with_raw_response(self) -> SuperdocResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
- """
- return SuperdocResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> SuperdocResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
- """
- return SuperdocResourceWithStreamingResponse(self)
-
-
-class AsyncSuperdocResource(AsyncAPIResource):
- @cached_property
- def v1(self) -> AsyncV1Resource:
- """Document conversion and template automation"""
- return AsyncV1Resource(self._client)
-
- @cached_property
- def with_raw_response(self) -> AsyncSuperdocResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
- """
- return AsyncSuperdocResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncSuperdocResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
- """
- return AsyncSuperdocResourceWithStreamingResponse(self)
-
-
-class SuperdocResourceWithRawResponse:
- def __init__(self, superdoc: SuperdocResource) -> None:
- self._superdoc = superdoc
-
- @cached_property
- def v1(self) -> V1ResourceWithRawResponse:
- """Document conversion and template automation"""
- return V1ResourceWithRawResponse(self._superdoc.v1)
-
-
-class AsyncSuperdocResourceWithRawResponse:
- def __init__(self, superdoc: AsyncSuperdocResource) -> None:
- self._superdoc = superdoc
-
- @cached_property
- def v1(self) -> AsyncV1ResourceWithRawResponse:
- """Document conversion and template automation"""
- return AsyncV1ResourceWithRawResponse(self._superdoc.v1)
-
-
-class SuperdocResourceWithStreamingResponse:
- def __init__(self, superdoc: SuperdocResource) -> None:
- self._superdoc = superdoc
-
- @cached_property
- def v1(self) -> V1ResourceWithStreamingResponse:
- """Document conversion and template automation"""
- return V1ResourceWithStreamingResponse(self._superdoc.v1)
-
-
-class AsyncSuperdocResourceWithStreamingResponse:
- def __init__(self, superdoc: AsyncSuperdocResource) -> None:
- self._superdoc = superdoc
-
- @cached_property
- def v1(self) -> AsyncV1ResourceWithStreamingResponse:
- """Document conversion and template automation"""
- return AsyncV1ResourceWithStreamingResponse(self._superdoc.v1)
diff --git a/src/casedev/resources/superdoc/v1.py b/src/casedev/resources/superdoc/v1.py
deleted file mode 100644
index 9192d6cb..00000000
--- a/src/casedev/resources/superdoc/v1.py
+++ /dev/null
@@ -1,356 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Mapping, Iterable, cast
-from typing_extensions import Literal
-
-import httpx
-
-from ..._files import deepcopy_with_paths
-from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import extract_files, maybe_transform, async_maybe_transform
-from ..._compat import cached_property
-from ..._resource import SyncAPIResource, AsyncAPIResource
-from ..._response import (
- BinaryAPIResponse,
- AsyncBinaryAPIResponse,
- StreamedBinaryAPIResponse,
- AsyncStreamedBinaryAPIResponse,
- to_custom_raw_response_wrapper,
- to_custom_streamed_response_wrapper,
- async_to_custom_raw_response_wrapper,
- async_to_custom_streamed_response_wrapper,
-)
-from ..._base_client import make_request_options
-from ...types.superdoc import v1_convert_params, v1_annotate_params
-
-__all__ = ["V1Resource", "AsyncV1Resource"]
-
-
-class V1Resource(SyncAPIResource):
- """Document conversion and template automation"""
-
- @cached_property
- def with_raw_response(self) -> V1ResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
- """
- return V1ResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> V1ResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
- """
- return V1ResourceWithStreamingResponse(self)
-
- def annotate(
- self,
- *,
- document: v1_annotate_params.Document,
- fields: Iterable[v1_annotate_params.Field],
- output_format: Literal["docx", "pdf"] | 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,
- ) -> BinaryAPIResponse:
- """Populate fields inside a DOCX template using SuperDoc annotations.
-
- Supports
- text, images, dates, and numbers. Can target individual fields by ID or multiple
- fields by group.
-
- Args:
- document: Document source - provide either URL or base64
-
- fields: Fields to populate in the template
-
- output_format: Output format for the annotated document
-
- 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
- """
- extra_headers = {"Accept": "application/pdf", **(extra_headers or {})}
- return self._post(
- "/superdoc/v1/annotate",
- body=maybe_transform(
- {
- "document": document,
- "fields": fields,
- "output_format": output_format,
- },
- v1_annotate_params.V1AnnotateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=BinaryAPIResponse,
- )
-
- def convert(
- self,
- *,
- from_: Literal["docx", "md", "html"],
- document_base64: str | Omit = omit,
- document_url: str | Omit = omit,
- to: Literal["pdf", "docx"] | 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,
- ) -> BinaryAPIResponse:
- """Convert documents between formats using SuperDoc.
-
- Supports DOCX to PDF, Markdown
- to DOCX, and HTML to DOCX conversions.
-
- Args:
- from_: Source format of the document
-
- document_base64: Base64-encoded document content
-
- document_url: URL to the document to convert
-
- to: Target format for conversion
-
- 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
- """
- extra_headers = {"Accept": "application/pdf", **(extra_headers or {})}
- body = deepcopy_with_paths(
- {
- "from_": from_,
- "document_base64": document_base64,
- "document_url": document_url,
- "to": to,
- },
- [["file"]],
- )
- files = extract_files(cast(Mapping[str, object], body), paths=[["file"]])
- if files:
- # It should be noted that the actual Content-Type header that will be
- # sent to the server will contain a `boundary` parameter, e.g.
- # multipart/form-data; boundary=---abc--
- extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
- return self._post(
- "/superdoc/v1/convert",
- body=maybe_transform(body, v1_convert_params.V1ConvertParams),
- files=files,
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=BinaryAPIResponse,
- )
-
-
-class AsyncV1Resource(AsyncAPIResource):
- """Document conversion and template automation"""
-
- @cached_property
- def with_raw_response(self) -> AsyncV1ResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#accessing-raw-response-data-eg-headers
- """
- return AsyncV1ResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncV1ResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/CaseMark/casedev-python#with_streaming_response
- """
- return AsyncV1ResourceWithStreamingResponse(self)
-
- async def annotate(
- self,
- *,
- document: v1_annotate_params.Document,
- fields: Iterable[v1_annotate_params.Field],
- output_format: Literal["docx", "pdf"] | 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,
- ) -> AsyncBinaryAPIResponse:
- """Populate fields inside a DOCX template using SuperDoc annotations.
-
- Supports
- text, images, dates, and numbers. Can target individual fields by ID or multiple
- fields by group.
-
- Args:
- document: Document source - provide either URL or base64
-
- fields: Fields to populate in the template
-
- output_format: Output format for the annotated document
-
- 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
- """
- extra_headers = {"Accept": "application/pdf", **(extra_headers or {})}
- return await self._post(
- "/superdoc/v1/annotate",
- body=await async_maybe_transform(
- {
- "document": document,
- "fields": fields,
- "output_format": output_format,
- },
- v1_annotate_params.V1AnnotateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=AsyncBinaryAPIResponse,
- )
-
- async def convert(
- self,
- *,
- from_: Literal["docx", "md", "html"],
- document_base64: str | Omit = omit,
- document_url: str | Omit = omit,
- to: Literal["pdf", "docx"] | 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,
- ) -> AsyncBinaryAPIResponse:
- """Convert documents between formats using SuperDoc.
-
- Supports DOCX to PDF, Markdown
- to DOCX, and HTML to DOCX conversions.
-
- Args:
- from_: Source format of the document
-
- document_base64: Base64-encoded document content
-
- document_url: URL to the document to convert
-
- to: Target format for conversion
-
- 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
- """
- extra_headers = {"Accept": "application/pdf", **(extra_headers or {})}
- body = deepcopy_with_paths(
- {
- "from_": from_,
- "document_base64": document_base64,
- "document_url": document_url,
- "to": to,
- },
- [["file"]],
- )
- files = extract_files(cast(Mapping[str, object], body), paths=[["file"]])
- if files:
- # It should be noted that the actual Content-Type header that will be
- # sent to the server will contain a `boundary` parameter, e.g.
- # multipart/form-data; boundary=---abc--
- extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
- return await self._post(
- "/superdoc/v1/convert",
- body=await async_maybe_transform(body, v1_convert_params.V1ConvertParams),
- files=files,
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=AsyncBinaryAPIResponse,
- )
-
-
-class V1ResourceWithRawResponse:
- def __init__(self, v1: V1Resource) -> None:
- self._v1 = v1
-
- self.annotate = to_custom_raw_response_wrapper(
- v1.annotate,
- BinaryAPIResponse,
- )
- self.convert = to_custom_raw_response_wrapper(
- v1.convert,
- BinaryAPIResponse,
- )
-
-
-class AsyncV1ResourceWithRawResponse:
- def __init__(self, v1: AsyncV1Resource) -> None:
- self._v1 = v1
-
- self.annotate = async_to_custom_raw_response_wrapper(
- v1.annotate,
- AsyncBinaryAPIResponse,
- )
- self.convert = async_to_custom_raw_response_wrapper(
- v1.convert,
- AsyncBinaryAPIResponse,
- )
-
-
-class V1ResourceWithStreamingResponse:
- def __init__(self, v1: V1Resource) -> None:
- self._v1 = v1
-
- self.annotate = to_custom_streamed_response_wrapper(
- v1.annotate,
- StreamedBinaryAPIResponse,
- )
- self.convert = to_custom_streamed_response_wrapper(
- v1.convert,
- StreamedBinaryAPIResponse,
- )
-
-
-class AsyncV1ResourceWithStreamingResponse:
- def __init__(self, v1: AsyncV1Resource) -> None:
- self._v1 = v1
-
- self.annotate = async_to_custom_streamed_response_wrapper(
- v1.annotate,
- AsyncStreamedBinaryAPIResponse,
- )
- self.convert = async_to_custom_streamed_response_wrapper(
- v1.convert,
- AsyncStreamedBinaryAPIResponse,
- )
diff --git a/src/casedev/resources/translate/translate.py b/src/casedev/resources/translate/translate.py
index 05d4e741..6a061c71 100644
--- a/src/casedev/resources/translate/translate.py
+++ b/src/casedev/resources/translate/translate.py
@@ -19,6 +19,7 @@
class TranslateResource(SyncAPIResource):
@cached_property
def v1(self) -> V1Resource:
+ """Language detection and translation for multilingual legal workflows"""
return V1Resource(self._client)
@cached_property
@@ -44,6 +45,7 @@ def with_streaming_response(self) -> TranslateResourceWithStreamingResponse:
class AsyncTranslateResource(AsyncAPIResource):
@cached_property
def v1(self) -> AsyncV1Resource:
+ """Language detection and translation for multilingual legal workflows"""
return AsyncV1Resource(self._client)
@cached_property
@@ -72,6 +74,7 @@ def __init__(self, translate: TranslateResource) -> None:
@cached_property
def v1(self) -> V1ResourceWithRawResponse:
+ """Language detection and translation for multilingual legal workflows"""
return V1ResourceWithRawResponse(self._translate.v1)
@@ -81,6 +84,7 @@ def __init__(self, translate: AsyncTranslateResource) -> None:
@cached_property
def v1(self) -> AsyncV1ResourceWithRawResponse:
+ """Language detection and translation for multilingual legal workflows"""
return AsyncV1ResourceWithRawResponse(self._translate.v1)
@@ -90,6 +94,7 @@ def __init__(self, translate: TranslateResource) -> None:
@cached_property
def v1(self) -> V1ResourceWithStreamingResponse:
+ """Language detection and translation for multilingual legal workflows"""
return V1ResourceWithStreamingResponse(self._translate.v1)
@@ -99,4 +104,5 @@ def __init__(self, translate: AsyncTranslateResource) -> None:
@cached_property
def v1(self) -> AsyncV1ResourceWithStreamingResponse:
+ """Language detection and translation for multilingual legal workflows"""
return AsyncV1ResourceWithStreamingResponse(self._translate.v1)
diff --git a/src/casedev/resources/translate/v1.py b/src/casedev/resources/translate/v1.py
index 9fc9b92e..a25eb671 100644
--- a/src/casedev/resources/translate/v1.py
+++ b/src/casedev/resources/translate/v1.py
@@ -2,23 +2,47 @@
from __future__ import annotations
-from typing import Union
+from typing import Union, Mapping, cast
from typing_extensions import Literal
import httpx
-from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._files import deepcopy_with_paths
+from ..._types import (
+ Body,
+ Omit,
+ Query,
+ Headers,
+ NotGiven,
+ FileTypes,
+ SequenceNotStr,
+ omit,
+ not_given,
+)
+from ..._utils import extract_files, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import (
+ BinaryAPIResponse,
+ AsyncBinaryAPIResponse,
+ StreamedBinaryAPIResponse,
+ AsyncStreamedBinaryAPIResponse,
to_raw_response_wrapper,
to_streamed_response_wrapper,
async_to_raw_response_wrapper,
+ to_custom_raw_response_wrapper,
async_to_streamed_response_wrapper,
+ to_custom_streamed_response_wrapper,
+ async_to_custom_raw_response_wrapper,
+ async_to_custom_streamed_response_wrapper,
)
from ..._base_client import make_request_options
-from ...types.translate import v1_detect_params, v1_translate_params, v1_list_languages_params
+from ...types.translate import (
+ v1_detect_params,
+ v1_translate_params,
+ v1_list_languages_params,
+ v1_translate_document_params,
+)
from ...types.translate.v1_detect_response import V1DetectResponse
from ...types.translate.v1_translate_response import V1TranslateResponse
from ...types.translate.v1_list_languages_response import V1ListLanguagesResponse
@@ -27,6 +51,8 @@
class V1Resource(SyncAPIResource):
+ """Language detection and translation for multilingual legal workflows"""
+
@cached_property
def with_raw_response(self) -> V1ResourceWithRawResponse:
"""
@@ -191,8 +217,68 @@ def translate(
cast_to=V1TranslateResponse,
)
+ def translate_document(
+ self,
+ *,
+ file: FileTypes,
+ target: str,
+ source: 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,
+ ) -> BinaryAPIResponse:
+ """Translate one TXT, DOCX, or searchable PDF document.
+
+ DOCX and PDF translations
+ preserve the source document format and retain as much layout and formatting as
+ possible.
+
+ Args:
+ file: TXT, DOCX, or searchable PDF document (max 20MB)
+
+ target: Target BCP-47 language code
+
+ source: Optional source BCP-47 language code. Auto-detected when omitted.
+
+ 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
+ """
+ extra_headers = {"Accept": "application/octet-stream", **(extra_headers or {})}
+ body = deepcopy_with_paths(
+ {
+ "file": file,
+ "target": target,
+ "source": source,
+ },
+ [["file"]],
+ )
+ files = extract_files(cast(Mapping[str, object], body), paths=[["file"]])
+ # It should be noted that the actual Content-Type header that will be
+ # sent to the server will contain a `boundary` parameter, e.g.
+ # multipart/form-data; boundary=---abc--
+ extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
+ return self._post(
+ "/translate/v1/document",
+ body=maybe_transform(body, v1_translate_document_params.V1TranslateDocumentParams),
+ files=files,
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=BinaryAPIResponse,
+ )
+
class AsyncV1Resource(AsyncAPIResource):
+ """Language detection and translation for multilingual legal workflows"""
+
@cached_property
def with_raw_response(self) -> AsyncV1ResourceWithRawResponse:
"""
@@ -357,6 +443,64 @@ async def translate(
cast_to=V1TranslateResponse,
)
+ async def translate_document(
+ self,
+ *,
+ file: FileTypes,
+ target: str,
+ source: 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,
+ ) -> AsyncBinaryAPIResponse:
+ """Translate one TXT, DOCX, or searchable PDF document.
+
+ DOCX and PDF translations
+ preserve the source document format and retain as much layout and formatting as
+ possible.
+
+ Args:
+ file: TXT, DOCX, or searchable PDF document (max 20MB)
+
+ target: Target BCP-47 language code
+
+ source: Optional source BCP-47 language code. Auto-detected when omitted.
+
+ 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
+ """
+ extra_headers = {"Accept": "application/octet-stream", **(extra_headers or {})}
+ body = deepcopy_with_paths(
+ {
+ "file": file,
+ "target": target,
+ "source": source,
+ },
+ [["file"]],
+ )
+ files = extract_files(cast(Mapping[str, object], body), paths=[["file"]])
+ # It should be noted that the actual Content-Type header that will be
+ # sent to the server will contain a `boundary` parameter, e.g.
+ # multipart/form-data; boundary=---abc--
+ extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
+ return await self._post(
+ "/translate/v1/document",
+ body=await async_maybe_transform(body, v1_translate_document_params.V1TranslateDocumentParams),
+ files=files,
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=AsyncBinaryAPIResponse,
+ )
+
class V1ResourceWithRawResponse:
def __init__(self, v1: V1Resource) -> None:
@@ -371,6 +515,10 @@ def __init__(self, v1: V1Resource) -> None:
self.translate = to_raw_response_wrapper(
v1.translate,
)
+ self.translate_document = to_custom_raw_response_wrapper(
+ v1.translate_document,
+ BinaryAPIResponse,
+ )
class AsyncV1ResourceWithRawResponse:
@@ -386,6 +534,10 @@ def __init__(self, v1: AsyncV1Resource) -> None:
self.translate = async_to_raw_response_wrapper(
v1.translate,
)
+ self.translate_document = async_to_custom_raw_response_wrapper(
+ v1.translate_document,
+ AsyncBinaryAPIResponse,
+ )
class V1ResourceWithStreamingResponse:
@@ -401,6 +553,10 @@ def __init__(self, v1: V1Resource) -> None:
self.translate = to_streamed_response_wrapper(
v1.translate,
)
+ self.translate_document = to_custom_streamed_response_wrapper(
+ v1.translate_document,
+ StreamedBinaryAPIResponse,
+ )
class AsyncV1ResourceWithStreamingResponse:
@@ -416,3 +572,7 @@ def __init__(self, v1: AsyncV1Resource) -> None:
self.translate = async_to_streamed_response_wrapper(
v1.translate,
)
+ self.translate_document = async_to_custom_streamed_response_wrapper(
+ v1.translate_document,
+ AsyncStreamedBinaryAPIResponse,
+ )
diff --git a/src/casedev/resources/usage/v1/v1.py b/src/casedev/resources/usage/v1/v1.py
index 2bf86174..f8e3571f 100644
--- a/src/casedev/resources/usage/v1/v1.py
+++ b/src/casedev/resources/usage/v1/v1.py
@@ -63,6 +63,8 @@ def retrieve(
self,
*,
granularity: Literal["summary", "daily"] | Omit = omit,
+ group_by: Literal["lincSessionId"] | Omit = omit,
+ linc_session_id: str | Omit = omit,
period_end: Union[str, datetime] | Omit = omit,
period_start: Union[str, datetime] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -81,6 +83,12 @@ def retrieve(
Args:
granularity: Whether to return period totals only or include daily buckets.
+ group_by: Optionally include usage groups keyed by native Linc session id. Only
+ Linc-session-attributable usage is grouped.
+
+ linc_session_id: Restrict usage to a native Linc session. The session must belong to the
+ authenticated organization.
+
period_end: Period end date. Defaults to now.
period_start: Period start date. Defaults to the start of the current calendar month.
@@ -104,6 +112,8 @@ def retrieve(
query=maybe_transform(
{
"granularity": granularity,
+ "group_by": group_by,
+ "linc_session_id": linc_session_id,
"period_end": period_end,
"period_start": period_start,
},
@@ -145,6 +155,8 @@ async def retrieve(
self,
*,
granularity: Literal["summary", "daily"] | Omit = omit,
+ group_by: Literal["lincSessionId"] | Omit = omit,
+ linc_session_id: str | Omit = omit,
period_end: Union[str, datetime] | Omit = omit,
period_start: Union[str, datetime] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -163,6 +175,12 @@ async def retrieve(
Args:
granularity: Whether to return period totals only or include daily buckets.
+ group_by: Optionally include usage groups keyed by native Linc session id. Only
+ Linc-session-attributable usage is grouped.
+
+ linc_session_id: Restrict usage to a native Linc session. The session must belong to the
+ authenticated organization.
+
period_end: Period end date. Defaults to now.
period_start: Period start date. Defaults to the start of the current calendar month.
@@ -186,6 +204,8 @@ async def retrieve(
query=await async_maybe_transform(
{
"granularity": granularity,
+ "group_by": group_by,
+ "linc_session_id": linc_session_id,
"period_end": period_end,
"period_start": period_start,
},
diff --git a/src/casedev/resources/vault/__init__.py b/src/casedev/resources/vault/__init__.py
index 89502278..228888f6 100644
--- a/src/casedev/resources/vault/__init__.py
+++ b/src/casedev/resources/vault/__init__.py
@@ -40,14 +40,6 @@
ObjectsResourceWithStreamingResponse,
AsyncObjectsResourceWithStreamingResponse,
)
-from .graphrag import (
- GraphragResource,
- AsyncGraphragResource,
- GraphragResourceWithRawResponse,
- AsyncGraphragResourceWithRawResponse,
- GraphragResourceWithStreamingResponse,
- AsyncGraphragResourceWithStreamingResponse,
-)
from .multipart import (
MultipartResource,
AsyncMultipartResource,
@@ -64,12 +56,6 @@
"AsyncEventsResourceWithRawResponse",
"EventsResourceWithStreamingResponse",
"AsyncEventsResourceWithStreamingResponse",
- "GraphragResource",
- "AsyncGraphragResource",
- "GraphragResourceWithRawResponse",
- "AsyncGraphragResourceWithRawResponse",
- "GraphragResourceWithStreamingResponse",
- "AsyncGraphragResourceWithStreamingResponse",
"GroupsResource",
"AsyncGroupsResource",
"GroupsResourceWithRawResponse",
diff --git a/src/casedev/resources/vault/events/events.py b/src/casedev/resources/vault/events/events.py
index 99f36d96..e4e9be8e 100644
--- a/src/casedev/resources/vault/events/events.py
+++ b/src/casedev/resources/vault/events/events.py
@@ -19,7 +19,7 @@
class EventsResource(SyncAPIResource):
@cached_property
def subscriptions(self) -> SubscriptionsResource:
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault-scoped event subscriptions and delivery testing"""
return SubscriptionsResource(self._client)
@cached_property
@@ -45,7 +45,7 @@ def with_streaming_response(self) -> EventsResourceWithStreamingResponse:
class AsyncEventsResource(AsyncAPIResource):
@cached_property
def subscriptions(self) -> AsyncSubscriptionsResource:
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault-scoped event subscriptions and delivery testing"""
return AsyncSubscriptionsResource(self._client)
@cached_property
@@ -74,7 +74,7 @@ def __init__(self, events: EventsResource) -> None:
@cached_property
def subscriptions(self) -> SubscriptionsResourceWithRawResponse:
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault-scoped event subscriptions and delivery testing"""
return SubscriptionsResourceWithRawResponse(self._events.subscriptions)
@@ -84,7 +84,7 @@ def __init__(self, events: AsyncEventsResource) -> None:
@cached_property
def subscriptions(self) -> AsyncSubscriptionsResourceWithRawResponse:
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault-scoped event subscriptions and delivery testing"""
return AsyncSubscriptionsResourceWithRawResponse(self._events.subscriptions)
@@ -94,7 +94,7 @@ def __init__(self, events: EventsResource) -> None:
@cached_property
def subscriptions(self) -> SubscriptionsResourceWithStreamingResponse:
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault-scoped event subscriptions and delivery testing"""
return SubscriptionsResourceWithStreamingResponse(self._events.subscriptions)
@@ -104,5 +104,5 @@ def __init__(self, events: AsyncEventsResource) -> None:
@cached_property
def subscriptions(self) -> AsyncSubscriptionsResourceWithStreamingResponse:
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault-scoped event subscriptions and delivery testing"""
return AsyncSubscriptionsResourceWithStreamingResponse(self._events.subscriptions)
diff --git a/src/casedev/resources/vault/events/subscriptions.py b/src/casedev/resources/vault/events/subscriptions.py
index 8dd48cdd..22d1a550 100644
--- a/src/casedev/resources/vault/events/subscriptions.py
+++ b/src/casedev/resources/vault/events/subscriptions.py
@@ -23,7 +23,7 @@
class SubscriptionsResource(SyncAPIResource):
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault-scoped event subscriptions and delivery testing"""
@cached_property
def with_raw_response(self) -> SubscriptionsResourceWithRawResponse:
@@ -301,7 +301,7 @@ def test(
class AsyncSubscriptionsResource(AsyncAPIResource):
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault-scoped event subscriptions and delivery testing"""
@cached_property
def with_raw_response(self) -> AsyncSubscriptionsResourceWithRawResponse:
diff --git a/src/casedev/resources/vault/memory.py b/src/casedev/resources/vault/memory.py
index 96f66bc5..051458a5 100644
--- a/src/casedev/resources/vault/memory.py
+++ b/src/casedev/resources/vault/memory.py
@@ -27,7 +27,7 @@
class MemoryResource(SyncAPIResource):
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault-scoped persistent memory and semantic retrieval"""
@cached_property
def with_raw_response(self) -> MemoryResourceWithRawResponse:
@@ -261,7 +261,7 @@ def search(
class AsyncMemoryResource(AsyncAPIResource):
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault-scoped persistent memory and semantic retrieval"""
@cached_property
def with_raw_response(self) -> AsyncMemoryResourceWithRawResponse:
diff --git a/src/casedev/resources/vault/multipart.py b/src/casedev/resources/vault/multipart.py
index 04a8989a..208a0c44 100644
--- a/src/casedev/resources/vault/multipart.py
+++ b/src/casedev/resources/vault/multipart.py
@@ -6,7 +6,7 @@
import httpx
-from ..._types import Body, Query, Headers, NoneType, NotGiven, not_given
+from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
@@ -16,8 +16,14 @@
async_to_raw_response_wrapper,
async_to_streamed_response_wrapper,
)
-from ...types.vault import multipart_abort_params, multipart_get_part_urls_params
+from ...types.vault import (
+ multipart_init_params,
+ multipart_abort_params,
+ multipart_complete_params,
+ multipart_get_part_urls_params,
+)
from ..._base_client import make_request_options
+from ...types.vault.multipart_init_response import MultipartInitResponse
from ...types.vault.multipart_get_part_urls_response import MultipartGetPartURLsResponse
__all__ = ["MultipartResource", "AsyncMultipartResource"]
@@ -92,6 +98,58 @@ def abort(
cast_to=NoneType,
)
+ def complete(
+ self,
+ id: str,
+ *,
+ object_id: str,
+ parts: Iterable[multipart_complete_params.Part],
+ size_bytes: int,
+ upload_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> None:
+ """
+ Complete a multipart upload by providing the list of part numbers and ETags
+ (live). Single PUT uploads are capped at 5GB; multipart default max is 16GB
+ (configurable).
+
+ Args:
+ size_bytes: File size in bytes (default max 16GB). Configure via
+ VAULT_MULTIPART_MAX_FILE_SIZE_BYTES.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._post(
+ path_template("/vault/{id}/multipart/complete", id=id),
+ body=maybe_transform(
+ {
+ "object_id": object_id,
+ "parts": parts,
+ "size_bytes": size_bytes,
+ "upload_id": upload_id,
+ },
+ multipart_complete_params.MultipartCompleteParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
def get_part_urls(
self,
id: str,
@@ -142,6 +200,83 @@ def get_part_urls(
cast_to=MultipartGetPartURLsResponse,
)
+ def init(
+ self,
+ id: str,
+ *,
+ content_type: str,
+ filename: str,
+ size_bytes: int,
+ auto_index: bool | Omit = omit,
+ is_ai_generated: bool | Omit = omit,
+ metadata: object | Omit = omit,
+ part_size_bytes: int | Omit = omit,
+ path: 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,
+ ) -> MultipartInitResponse:
+ """Initiate a multipart upload for large files (>5GB).
+
+ Single PUT uploads are
+ capped at 5GB; multipart default max is 16GB (configurable). Multipart uploads
+ are supported in production. Returns an uploadId and object metadata. Use part
+ URLs endpoint to upload parts and complete endpoint to finalize.
+
+ Args:
+ content_type: MIME type of the file
+
+ filename: Name of the file to upload
+
+ size_bytes: File size in bytes (required, default max 16GB). Configure via
+ VAULT_MULTIPART_MAX_FILE_SIZE_BYTES.
+
+ auto_index: Whether to automatically process and index the file for search
+
+ is_ai_generated: Marks the file as AI-generated work product (e.g. uploaded by an agent) rather
+ than a user-provided source document. Persisted on the object and returned by
+ object listings so clients can distinguish provenance.
+
+ metadata: Additional metadata to associate with the file
+
+ part_size_bytes: Multipart part size in bytes (min 5MB, max 5GB). Defaults to 64MB.
+
+ path: Optional folder path for hierarchy preservation
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._post(
+ path_template("/vault/{id}/multipart/init", id=id),
+ body=maybe_transform(
+ {
+ "content_type": content_type,
+ "filename": filename,
+ "size_bytes": size_bytes,
+ "auto_index": auto_index,
+ "is_ai_generated": is_ai_generated,
+ "metadata": metadata,
+ "part_size_bytes": part_size_bytes,
+ "path": path,
+ },
+ multipart_init_params.MultipartInitParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=MultipartInitResponse,
+ )
+
class AsyncMultipartResource(AsyncAPIResource):
"""Secure document storage with semantic search and GraphRAG"""
@@ -212,6 +347,58 @@ async def abort(
cast_to=NoneType,
)
+ async def complete(
+ self,
+ id: str,
+ *,
+ object_id: str,
+ parts: Iterable[multipart_complete_params.Part],
+ size_bytes: int,
+ upload_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> None:
+ """
+ Complete a multipart upload by providing the list of part numbers and ETags
+ (live). Single PUT uploads are capped at 5GB; multipart default max is 16GB
+ (configurable).
+
+ Args:
+ size_bytes: File size in bytes (default max 16GB). Configure via
+ VAULT_MULTIPART_MAX_FILE_SIZE_BYTES.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._post(
+ path_template("/vault/{id}/multipart/complete", id=id),
+ body=await async_maybe_transform(
+ {
+ "object_id": object_id,
+ "parts": parts,
+ "size_bytes": size_bytes,
+ "upload_id": upload_id,
+ },
+ multipart_complete_params.MultipartCompleteParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
async def get_part_urls(
self,
id: str,
@@ -262,6 +449,83 @@ async def get_part_urls(
cast_to=MultipartGetPartURLsResponse,
)
+ async def init(
+ self,
+ id: str,
+ *,
+ content_type: str,
+ filename: str,
+ size_bytes: int,
+ auto_index: bool | Omit = omit,
+ is_ai_generated: bool | Omit = omit,
+ metadata: object | Omit = omit,
+ part_size_bytes: int | Omit = omit,
+ path: 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,
+ ) -> MultipartInitResponse:
+ """Initiate a multipart upload for large files (>5GB).
+
+ Single PUT uploads are
+ capped at 5GB; multipart default max is 16GB (configurable). Multipart uploads
+ are supported in production. Returns an uploadId and object metadata. Use part
+ URLs endpoint to upload parts and complete endpoint to finalize.
+
+ Args:
+ content_type: MIME type of the file
+
+ filename: Name of the file to upload
+
+ size_bytes: File size in bytes (required, default max 16GB). Configure via
+ VAULT_MULTIPART_MAX_FILE_SIZE_BYTES.
+
+ auto_index: Whether to automatically process and index the file for search
+
+ is_ai_generated: Marks the file as AI-generated work product (e.g. uploaded by an agent) rather
+ than a user-provided source document. Persisted on the object and returned by
+ object listings so clients can distinguish provenance.
+
+ metadata: Additional metadata to associate with the file
+
+ part_size_bytes: Multipart part size in bytes (min 5MB, max 5GB). Defaults to 64MB.
+
+ path: Optional folder path for hierarchy preservation
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return await self._post(
+ path_template("/vault/{id}/multipart/init", id=id),
+ body=await async_maybe_transform(
+ {
+ "content_type": content_type,
+ "filename": filename,
+ "size_bytes": size_bytes,
+ "auto_index": auto_index,
+ "is_ai_generated": is_ai_generated,
+ "metadata": metadata,
+ "part_size_bytes": part_size_bytes,
+ "path": path,
+ },
+ multipart_init_params.MultipartInitParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=MultipartInitResponse,
+ )
+
class MultipartResourceWithRawResponse:
def __init__(self, multipart: MultipartResource) -> None:
@@ -270,9 +534,15 @@ def __init__(self, multipart: MultipartResource) -> None:
self.abort = to_raw_response_wrapper(
multipart.abort,
)
+ self.complete = to_raw_response_wrapper(
+ multipart.complete,
+ )
self.get_part_urls = to_raw_response_wrapper(
multipart.get_part_urls,
)
+ self.init = to_raw_response_wrapper(
+ multipart.init,
+ )
class AsyncMultipartResourceWithRawResponse:
@@ -282,9 +552,15 @@ def __init__(self, multipart: AsyncMultipartResource) -> None:
self.abort = async_to_raw_response_wrapper(
multipart.abort,
)
+ self.complete = async_to_raw_response_wrapper(
+ multipart.complete,
+ )
self.get_part_urls = async_to_raw_response_wrapper(
multipart.get_part_urls,
)
+ self.init = async_to_raw_response_wrapper(
+ multipart.init,
+ )
class MultipartResourceWithStreamingResponse:
@@ -294,9 +570,15 @@ def __init__(self, multipart: MultipartResource) -> None:
self.abort = to_streamed_response_wrapper(
multipart.abort,
)
+ self.complete = to_streamed_response_wrapper(
+ multipart.complete,
+ )
self.get_part_urls = to_streamed_response_wrapper(
multipart.get_part_urls,
)
+ self.init = to_streamed_response_wrapper(
+ multipart.init,
+ )
class AsyncMultipartResourceWithStreamingResponse:
@@ -306,6 +588,12 @@ def __init__(self, multipart: AsyncMultipartResource) -> None:
self.abort = async_to_streamed_response_wrapper(
multipart.abort,
)
+ self.complete = async_to_streamed_response_wrapper(
+ multipart.complete,
+ )
self.get_part_urls = async_to_streamed_response_wrapper(
multipart.get_part_urls,
)
+ self.init = async_to_streamed_response_wrapper(
+ multipart.init,
+ )
diff --git a/src/casedev/resources/vault/objects.py b/src/casedev/resources/vault/objects.py
index 91c0f099..159a8f62 100644
--- a/src/casedev/resources/vault/objects.py
+++ b/src/casedev/resources/vault/objects.py
@@ -7,7 +7,7 @@
import httpx
-from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
@@ -26,6 +26,9 @@
async_to_custom_streamed_response_wrapper,
)
from ...types.vault import (
+ object_list_params,
+ object_merge_params,
+ object_append_params,
object_delete_params,
object_update_params,
object_get_pages_params,
@@ -35,6 +38,8 @@
)
from ..._base_client import make_request_options
from ...types.vault.object_list_response import ObjectListResponse
+from ...types.vault.object_merge_response import ObjectMergeResponse
+from ...types.vault.object_append_response import ObjectAppendResponse
from ...types.vault.object_delete_response import ObjectDeleteResponse
from ...types.vault.object_update_response import ObjectUpdateResponse
from ...types.vault.object_get_text_response import ObjectGetTextResponse
@@ -42,14 +47,13 @@
from ...types.vault.object_get_pages_response import ObjectGetPagesResponse
from ...types.vault.object_get_chunks_response import ObjectGetChunksResponse
from ...types.vault.object_get_ocr_words_response import ObjectGetOcrWordsResponse
-from ...types.vault.object_get_summarize_job_response import ObjectGetSummarizeJobResponse
from ...types.vault.object_create_presigned_url_response import ObjectCreatePresignedURLResponse
__all__ = ["ObjectsResource", "AsyncObjectsResource"]
class ObjectsResource(SyncAPIResource):
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault object management, content access, and document operations"""
@cached_property
def with_raw_response(self) -> ObjectsResourceWithRawResponse:
@@ -169,6 +173,7 @@ def list(
self,
id: str,
*,
+ include_unconfirmed: bool | 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,
@@ -181,6 +186,9 @@ def list(
ingestion status, and processing statistics.
Args:
+ include_unconfirmed: Include placeholders for uploads that were never completed (awaiting_upload) or
+ were cancelled (aborted). Excluded by default.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -194,7 +202,13 @@ def list(
return self._get(
path_template("/vault/{id}/objects", id=id),
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {"include_unconfirmed": include_unconfirmed}, object_list_params.ObjectListParams
+ ),
),
cast_to=ObjectListResponse,
)
@@ -244,6 +258,76 @@ def delete(
cast_to=ObjectDeleteResponse,
)
+ def append(
+ self,
+ object_id: str,
+ *,
+ id: str,
+ append_object_ids: SequenceNotStr[str],
+ back_links: bool | Omit = omit,
+ back_links_text: str | Omit = omit,
+ bates: object_append_params.Bates | Omit = omit,
+ rewrite_links: bool | 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,
+ ) -> ObjectAppendResponse:
+ """
+ Merges one or more PDF vault objects onto the end of an existing PDF vault
+ object, overwriting the target in place before returning. Optionally rewrites
+ citation links in the original target into internal PDF jumps and adds back
+ links on appended pages. The target object’s ingestion state is not affected;
+ appended pages are not searchable.
+
+ Args:
+ append_object_ids: Vault object IDs whose pages will be appended onto the target object, in order.
+ Must not include the target object itself.
+
+ back_links: Adds back links on appended pages
+
+ back_links_text: Label text for the back link. Used only when backLinks is true and rendered
+ centered at the bottom of each appended page.
+
+ bates: Optional Bates stamping for appended source PDFs. Numbering is deterministic
+ across appendObjectIds order and does not stamp the target report pages.
+
+ rewrite_links: When true, rewrites links in the target object to internal PDF jumps when the
+ URL contains exactly one appended object ID as a standalone query parameter
+ value or decoded path segment.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ if not object_id:
+ raise ValueError(f"Expected a non-empty value for `object_id` but received {object_id!r}")
+ return self._post(
+ path_template("/vault/{id}/objects/{object_id}/append", id=id, object_id=object_id),
+ body=maybe_transform(
+ {
+ "append_object_ids": append_object_ids,
+ "back_links": back_links,
+ "back_links_text": back_links_text,
+ "bates": bates,
+ "rewrite_links": rewrite_links,
+ },
+ object_append_params.ObjectAppendParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ObjectAppendResponse,
+ )
+
def create_presigned_url(
self,
object_id: str,
@@ -529,21 +613,23 @@ def get_pages(
cast_to=ObjectGetPagesResponse,
)
- def get_summarize_job(
+ def get_text(
self,
- job_id: str,
+ object_id: str,
*,
id: str,
- object_id: str,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ObjectGetSummarizeJobResponse:
+ ) -> ObjectGetTextResponse:
"""
- Get the status of a CaseMark summary workflow job.
+ Retrieves the full extracted text content from a processed vault object,
+ page-numbered (--- Page N --- markers) when the source document is paginated.
+ Useful for document review, analysis, or export. The object must have completed
+ processing before text can be retrieved.
Args:
extra_headers: Send extra headers
@@ -558,37 +644,42 @@ def get_summarize_job(
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
if not object_id:
raise ValueError(f"Expected a non-empty value for `object_id` but received {object_id!r}")
- if not job_id:
- raise ValueError(f"Expected a non-empty value for `job_id` but received {job_id!r}")
return self._get(
- path_template(
- "/vault/{id}/objects/{object_id}/summarize/{job_id}", id=id, object_id=object_id, job_id=job_id
- ),
+ path_template("/vault/{id}/objects/{object_id}/text", id=id, object_id=object_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=ObjectGetSummarizeJobResponse,
+ cast_to=ObjectGetTextResponse,
)
- def get_text(
+ def merge(
self,
- object_id: str,
- *,
id: str,
+ *,
+ filename: str,
+ source_object_ids: SequenceNotStr[str],
+ source_rendition: Literal["original", "searchable_pdf"],
+ idempotency_key: str,
+ bates: object_merge_params.Bates | Omit = omit,
+ client_reference: 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,
- ) -> ObjectGetTextResponse:
- """Retrieves the full extracted text content from a processed vault object.
+ ) -> ObjectMergeResponse:
+ """Starts an asynchronous merge that creates a new PDF vault object.
- Returns
- the concatenated text from all chunks, useful for document review, analysis, or
- export. The object must have completed processing before text can be retrieved.
+ Source objects
+ are unchanged. Missing searchable PDF renditions are generated on demand before
+ combining. Completion is reported through vault.object.merge webhooks.
Args:
+ filename: Output PDF filename
+
+ source_object_ids: Source object IDs in output order
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -599,19 +690,28 @@ def get_text(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- if not object_id:
- raise ValueError(f"Expected a non-empty value for `object_id` but received {object_id!r}")
- return self._get(
- path_template("/vault/{id}/objects/{object_id}/text", id=id, object_id=object_id),
+ extra_headers = {"Idempotency-Key": idempotency_key, **(extra_headers or {})}
+ return self._post(
+ path_template("/vault/{id}/objects/merge", id=id),
+ body=maybe_transform(
+ {
+ "filename": filename,
+ "source_object_ids": source_object_ids,
+ "source_rendition": source_rendition,
+ "bates": bates,
+ "client_reference": client_reference,
+ },
+ object_merge_params.ObjectMergeParams,
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=ObjectGetTextResponse,
+ cast_to=ObjectMergeResponse,
)
class AsyncObjectsResource(AsyncAPIResource):
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault object management, content access, and document operations"""
@cached_property
def with_raw_response(self) -> AsyncObjectsResourceWithRawResponse:
@@ -731,6 +831,7 @@ async def list(
self,
id: str,
*,
+ include_unconfirmed: bool | 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,
@@ -743,6 +844,9 @@ async def list(
ingestion status, and processing statistics.
Args:
+ include_unconfirmed: Include placeholders for uploads that were never completed (awaiting_upload) or
+ were cancelled (aborted). Excluded by default.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -756,7 +860,13 @@ async def list(
return await self._get(
path_template("/vault/{id}/objects", id=id),
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {"include_unconfirmed": include_unconfirmed}, object_list_params.ObjectListParams
+ ),
),
cast_to=ObjectListResponse,
)
@@ -806,6 +916,76 @@ async def delete(
cast_to=ObjectDeleteResponse,
)
+ async def append(
+ self,
+ object_id: str,
+ *,
+ id: str,
+ append_object_ids: SequenceNotStr[str],
+ back_links: bool | Omit = omit,
+ back_links_text: str | Omit = omit,
+ bates: object_append_params.Bates | Omit = omit,
+ rewrite_links: bool | 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,
+ ) -> ObjectAppendResponse:
+ """
+ Merges one or more PDF vault objects onto the end of an existing PDF vault
+ object, overwriting the target in place before returning. Optionally rewrites
+ citation links in the original target into internal PDF jumps and adds back
+ links on appended pages. The target object’s ingestion state is not affected;
+ appended pages are not searchable.
+
+ Args:
+ append_object_ids: Vault object IDs whose pages will be appended onto the target object, in order.
+ Must not include the target object itself.
+
+ back_links: Adds back links on appended pages
+
+ back_links_text: Label text for the back link. Used only when backLinks is true and rendered
+ centered at the bottom of each appended page.
+
+ bates: Optional Bates stamping for appended source PDFs. Numbering is deterministic
+ across appendObjectIds order and does not stamp the target report pages.
+
+ rewrite_links: When true, rewrites links in the target object to internal PDF jumps when the
+ URL contains exactly one appended object ID as a standalone query parameter
+ value or decoded path segment.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ if not object_id:
+ raise ValueError(f"Expected a non-empty value for `object_id` but received {object_id!r}")
+ return await self._post(
+ path_template("/vault/{id}/objects/{object_id}/append", id=id, object_id=object_id),
+ body=await async_maybe_transform(
+ {
+ "append_object_ids": append_object_ids,
+ "back_links": back_links,
+ "back_links_text": back_links_text,
+ "bates": bates,
+ "rewrite_links": rewrite_links,
+ },
+ object_append_params.ObjectAppendParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ObjectAppendResponse,
+ )
+
async def create_presigned_url(
self,
object_id: str,
@@ -1091,21 +1271,23 @@ async def get_pages(
cast_to=ObjectGetPagesResponse,
)
- async def get_summarize_job(
+ async def get_text(
self,
- job_id: str,
+ object_id: str,
*,
id: str,
- object_id: str,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ObjectGetSummarizeJobResponse:
+ ) -> ObjectGetTextResponse:
"""
- Get the status of a CaseMark summary workflow job.
+ Retrieves the full extracted text content from a processed vault object,
+ page-numbered (--- Page N --- markers) when the source document is paginated.
+ Useful for document review, analysis, or export. The object must have completed
+ processing before text can be retrieved.
Args:
extra_headers: Send extra headers
@@ -1120,37 +1302,42 @@ async def get_summarize_job(
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
if not object_id:
raise ValueError(f"Expected a non-empty value for `object_id` but received {object_id!r}")
- if not job_id:
- raise ValueError(f"Expected a non-empty value for `job_id` but received {job_id!r}")
return await self._get(
- path_template(
- "/vault/{id}/objects/{object_id}/summarize/{job_id}", id=id, object_id=object_id, job_id=job_id
- ),
+ path_template("/vault/{id}/objects/{object_id}/text", id=id, object_id=object_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=ObjectGetSummarizeJobResponse,
+ cast_to=ObjectGetTextResponse,
)
- async def get_text(
+ async def merge(
self,
- object_id: str,
- *,
id: str,
+ *,
+ filename: str,
+ source_object_ids: SequenceNotStr[str],
+ source_rendition: Literal["original", "searchable_pdf"],
+ idempotency_key: str,
+ bates: object_merge_params.Bates | Omit = omit,
+ client_reference: 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,
- ) -> ObjectGetTextResponse:
- """Retrieves the full extracted text content from a processed vault object.
+ ) -> ObjectMergeResponse:
+ """Starts an asynchronous merge that creates a new PDF vault object.
- Returns
- the concatenated text from all chunks, useful for document review, analysis, or
- export. The object must have completed processing before text can be retrieved.
+ Source objects
+ are unchanged. Missing searchable PDF renditions are generated on demand before
+ combining. Completion is reported through vault.object.merge webhooks.
Args:
+ filename: Output PDF filename
+
+ source_object_ids: Source object IDs in output order
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1161,14 +1348,23 @@ async def get_text(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- if not object_id:
- raise ValueError(f"Expected a non-empty value for `object_id` but received {object_id!r}")
- return await self._get(
- path_template("/vault/{id}/objects/{object_id}/text", id=id, object_id=object_id),
+ extra_headers = {"Idempotency-Key": idempotency_key, **(extra_headers or {})}
+ return await self._post(
+ path_template("/vault/{id}/objects/merge", id=id),
+ body=await async_maybe_transform(
+ {
+ "filename": filename,
+ "source_object_ids": source_object_ids,
+ "source_rendition": source_rendition,
+ "bates": bates,
+ "client_reference": client_reference,
+ },
+ object_merge_params.ObjectMergeParams,
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=ObjectGetTextResponse,
+ cast_to=ObjectMergeResponse,
)
@@ -1188,6 +1384,9 @@ def __init__(self, objects: ObjectsResource) -> None:
self.delete = to_raw_response_wrapper(
objects.delete,
)
+ self.append = to_raw_response_wrapper(
+ objects.append,
+ )
self.create_presigned_url = to_raw_response_wrapper(
objects.create_presigned_url,
)
@@ -1204,12 +1403,12 @@ def __init__(self, objects: ObjectsResource) -> None:
self.get_pages = to_raw_response_wrapper(
objects.get_pages,
)
- self.get_summarize_job = to_raw_response_wrapper(
- objects.get_summarize_job,
- )
self.get_text = to_raw_response_wrapper(
objects.get_text,
)
+ self.merge = to_raw_response_wrapper(
+ objects.merge,
+ )
class AsyncObjectsResourceWithRawResponse:
@@ -1228,6 +1427,9 @@ def __init__(self, objects: AsyncObjectsResource) -> None:
self.delete = async_to_raw_response_wrapper(
objects.delete,
)
+ self.append = async_to_raw_response_wrapper(
+ objects.append,
+ )
self.create_presigned_url = async_to_raw_response_wrapper(
objects.create_presigned_url,
)
@@ -1244,12 +1446,12 @@ def __init__(self, objects: AsyncObjectsResource) -> None:
self.get_pages = async_to_raw_response_wrapper(
objects.get_pages,
)
- self.get_summarize_job = async_to_raw_response_wrapper(
- objects.get_summarize_job,
- )
self.get_text = async_to_raw_response_wrapper(
objects.get_text,
)
+ self.merge = async_to_raw_response_wrapper(
+ objects.merge,
+ )
class ObjectsResourceWithStreamingResponse:
@@ -1268,6 +1470,9 @@ def __init__(self, objects: ObjectsResource) -> None:
self.delete = to_streamed_response_wrapper(
objects.delete,
)
+ self.append = to_streamed_response_wrapper(
+ objects.append,
+ )
self.create_presigned_url = to_streamed_response_wrapper(
objects.create_presigned_url,
)
@@ -1284,12 +1489,12 @@ def __init__(self, objects: ObjectsResource) -> None:
self.get_pages = to_streamed_response_wrapper(
objects.get_pages,
)
- self.get_summarize_job = to_streamed_response_wrapper(
- objects.get_summarize_job,
- )
self.get_text = to_streamed_response_wrapper(
objects.get_text,
)
+ self.merge = to_streamed_response_wrapper(
+ objects.merge,
+ )
class AsyncObjectsResourceWithStreamingResponse:
@@ -1308,6 +1513,9 @@ def __init__(self, objects: AsyncObjectsResource) -> None:
self.delete = async_to_streamed_response_wrapper(
objects.delete,
)
+ self.append = async_to_streamed_response_wrapper(
+ objects.append,
+ )
self.create_presigned_url = async_to_streamed_response_wrapper(
objects.create_presigned_url,
)
@@ -1324,9 +1532,9 @@ def __init__(self, objects: AsyncObjectsResource) -> None:
self.get_pages = async_to_streamed_response_wrapper(
objects.get_pages,
)
- self.get_summarize_job = async_to_streamed_response_wrapper(
- objects.get_summarize_job,
- )
self.get_text = async_to_streamed_response_wrapper(
objects.get_text,
)
+ self.merge = async_to_streamed_response_wrapper(
+ objects.merge,
+ )
diff --git a/src/casedev/resources/vault/vault.py b/src/casedev/resources/vault/vault.py
index cd252ba8..3298dd52 100644
--- a/src/casedev/resources/vault/vault.py
+++ b/src/casedev/resources/vault/vault.py
@@ -3,7 +3,7 @@
from __future__ import annotations
from typing import Optional
-from typing_extensions import Literal, overload
+from typing_extensions import Literal
import httpx
@@ -40,15 +40,7 @@
AsyncObjectsResourceWithStreamingResponse,
)
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import path_template, required_args, maybe_transform, async_maybe_transform
-from .graphrag import (
- GraphragResource,
- AsyncGraphragResource,
- GraphragResourceWithRawResponse,
- AsyncGraphragResourceWithRawResponse,
- GraphragResourceWithStreamingResponse,
- AsyncGraphragResourceWithStreamingResponse,
-)
+from ..._utils import path_template, maybe_transform, strip_not_given, async_maybe_transform
from ..._compat import cached_property
from .multipart import (
MultipartResource,
@@ -94,11 +86,6 @@ class VaultResource(SyncAPIResource):
def events(self) -> EventsResource:
return EventsResource(self._client)
- @cached_property
- def graphrag(self) -> GraphragResource:
- """Secure document storage with semantic search and GraphRAG"""
- return GraphragResource(self._client)
-
@cached_property
def groups(self) -> GroupsResource:
"""Secure document storage with semantic search and GraphRAG"""
@@ -111,12 +98,12 @@ def multipart(self) -> MultipartResource:
@cached_property
def objects(self) -> ObjectsResource:
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault object management, content access, and document operations"""
return ObjectsResource(self._client)
@cached_property
def memory(self) -> MemoryResource:
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault-scoped persistent memory and semantic retrieval"""
return MemoryResource(self._client)
@cached_property
@@ -383,15 +370,17 @@ def delete(
cast_to=VaultDeleteResponse,
)
- @overload
def confirm_upload(
self,
object_id: str,
*,
id: str,
- size_bytes: int,
- success: Literal[True],
+ success: bool,
+ auto_ingest: bool | Omit = omit,
+ error_code: str | Omit = omit,
+ error_message: str | Omit = omit,
etag: str | Omit = omit,
+ size_bytes: 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,
@@ -403,53 +392,26 @@ def confirm_upload(
This endpoint
emits vault.upload.completed or vault.upload.failed events and is idempotent for
- repeated confirmations.
+ repeated confirmations. Conditional fields: when success=true, sizeBytes is
+ required; when success=false, errorCode and errorMessage are required. These
+ rules are enforced server-side with specific 400 responses.
Args:
- size_bytes: Uploaded file size in bytes
-
success: Whether the upload succeeded
- etag: S3 ETag for the uploaded object (optional if client cannot access ETag header)
+ auto_ingest: When true and the object was uploaded with auto_index, trigger ingestion
+ immediately after a successful confirmation (no separate ingest call needed).
+ The ingest outcome is reported in the `ingest` response field; an ingest failure
+ does not fail the confirmation.
- extra_headers: Send extra headers
+ error_code: Client-side error code. Required when success=false.
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
+ error_message: Client-side error message. Required when success=false.
- timeout: Override the client-level default timeout for this request, in seconds
- """
- ...
-
- @overload
- def confirm_upload(
- self,
- object_id: str,
- *,
- id: str,
- error_code: str,
- error_message: str,
- success: Literal[False],
- # 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,
- ) -> VaultConfirmUploadResponse:
- """Confirm whether a direct-to-S3 vault upload succeeded or failed.
-
- This endpoint
- emits vault.upload.completed or vault.upload.failed events and is idempotent for
- repeated confirmations.
-
- Args:
- error_code: Client-side error code
+ etag: S3 ETag for the uploaded object (optional if client cannot access ETag header).
+ Only meaningful when success=true.
- error_message: Client-side error message
-
- success: Whether the upload succeeded
+ size_bytes: Uploaded file size in bytes. Required when success=true.
extra_headers: Send extra headers
@@ -459,26 +421,6 @@ def confirm_upload(
timeout: Override the client-level default timeout for this request, in seconds
"""
- ...
-
- @required_args(["id", "size_bytes", "success"], ["id", "error_code", "error_message", "success"])
- def confirm_upload(
- self,
- object_id: str,
- *,
- id: str,
- size_bytes: int | Omit = omit,
- success: Literal[True] | Literal[False],
- etag: str | Omit = omit,
- error_code: str | Omit = omit,
- error_message: 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,
- ) -> VaultConfirmUploadResponse:
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
if not object_id:
@@ -487,11 +429,12 @@ def confirm_upload(
path_template("/vault/{id}/upload/{object_id}/confirm", id=id, object_id=object_id),
body=maybe_transform(
{
- "size_bytes": size_bytes,
"success": success,
- "etag": etag,
+ "auto_ingest": auto_ingest,
"error_code": error_code,
"error_message": error_message,
+ "etag": etag,
+ "size_bytes": size_bytes,
},
vault_confirm_upload_params.VaultConfirmUploadParams,
),
@@ -515,14 +458,13 @@ def ingest(
) -> VaultIngestResponse:
"""
Triggers ingestion workflow for a vault object to extract text, generate chunks,
- and create embeddings. For supported file types (PDF, DOCX, PPTX, TXT, RTF, XML,
- HTML, Markdown, CSV/TSV, JSON/YAML/TOML, common source code files, ZIP, audio,
- video), processing happens asynchronously. ZIP archives are unpacked recursively
- up to 5 levels, and each extracted file is created as an independent vault
- object and ingested via the normal pipeline. For unsupported types (images,
- etc.), the file is marked as completed immediately without text extraction.
- GraphRAG indexing must be triggered separately via POST
- /vault/:id/graphrag/:objectId.
+ and create embeddings. For supported file types (PDF, DOCX, PPTX, XLSX, TXT,
+ RTF, XML, HTML, Markdown, CSV/TSV, JSON/YAML/TOML, common source code files,
+ ZIP, audio, video), processing happens asynchronously. ZIP archives are unpacked
+ recursively up to 5 levels, and each extracted file is created as an independent
+ vault object and ingested via the normal pipeline. For unsupported types
+ (images, etc.), the file is marked as completed immediately without text
+ extraction.
Args:
extra_headers: Send extra headers
@@ -611,9 +553,11 @@ def upload(
content_type: str,
filename: str,
auto_index: bool | Omit = omit,
+ is_ai_generated: bool | Omit = omit,
metadata: object | Omit = omit,
path: str | Omit = omit,
size_bytes: int | Omit = omit,
+ idempotency_key: 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,
@@ -633,6 +577,10 @@ def upload(
auto_index: Whether to automatically process and index the file for search
+ is_ai_generated: Marks the file as AI-generated work product (e.g. uploaded by an agent) rather
+ than a user-provided source document. Persisted on the object and returned by
+ object listings so clients can distinguish provenance.
+
metadata: Additional metadata to associate with the file
path: Optional folder path for hierarchy preservation. Allows integrations to maintain
@@ -652,6 +600,7 @@ def upload(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {**strip_not_given({"Idempotency-Key": idempotency_key}), **(extra_headers or {})}
return self._post(
path_template("/vault/{id}/upload", id=id),
body=maybe_transform(
@@ -659,6 +608,7 @@ def upload(
"content_type": content_type,
"filename": filename,
"auto_index": auto_index,
+ "is_ai_generated": is_ai_generated,
"metadata": metadata,
"path": path,
"size_bytes": size_bytes,
@@ -679,11 +629,6 @@ class AsyncVaultResource(AsyncAPIResource):
def events(self) -> AsyncEventsResource:
return AsyncEventsResource(self._client)
- @cached_property
- def graphrag(self) -> AsyncGraphragResource:
- """Secure document storage with semantic search and GraphRAG"""
- return AsyncGraphragResource(self._client)
-
@cached_property
def groups(self) -> AsyncGroupsResource:
"""Secure document storage with semantic search and GraphRAG"""
@@ -696,12 +641,12 @@ def multipart(self) -> AsyncMultipartResource:
@cached_property
def objects(self) -> AsyncObjectsResource:
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault object management, content access, and document operations"""
return AsyncObjectsResource(self._client)
@cached_property
def memory(self) -> AsyncMemoryResource:
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault-scoped persistent memory and semantic retrieval"""
return AsyncMemoryResource(self._client)
@cached_property
@@ -968,15 +913,17 @@ async def delete(
cast_to=VaultDeleteResponse,
)
- @overload
async def confirm_upload(
self,
object_id: str,
*,
id: str,
- size_bytes: int,
- success: Literal[True],
+ success: bool,
+ auto_ingest: bool | Omit = omit,
+ error_code: str | Omit = omit,
+ error_message: str | Omit = omit,
etag: str | Omit = omit,
+ size_bytes: 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,
@@ -988,53 +935,26 @@ async def confirm_upload(
This endpoint
emits vault.upload.completed or vault.upload.failed events and is idempotent for
- repeated confirmations.
+ repeated confirmations. Conditional fields: when success=true, sizeBytes is
+ required; when success=false, errorCode and errorMessage are required. These
+ rules are enforced server-side with specific 400 responses.
Args:
- size_bytes: Uploaded file size in bytes
-
success: Whether the upload succeeded
- etag: S3 ETag for the uploaded object (optional if client cannot access ETag header)
+ auto_ingest: When true and the object was uploaded with auto_index, trigger ingestion
+ immediately after a successful confirmation (no separate ingest call needed).
+ The ingest outcome is reported in the `ingest` response field; an ingest failure
+ does not fail the confirmation.
- extra_headers: Send extra headers
+ error_code: Client-side error code. Required when success=false.
- 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
- """
- ...
-
- @overload
- async def confirm_upload(
- self,
- object_id: str,
- *,
- id: str,
- error_code: str,
- error_message: str,
- success: Literal[False],
- # 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,
- ) -> VaultConfirmUploadResponse:
- """Confirm whether a direct-to-S3 vault upload succeeded or failed.
+ error_message: Client-side error message. Required when success=false.
- This endpoint
- emits vault.upload.completed or vault.upload.failed events and is idempotent for
- repeated confirmations.
+ etag: S3 ETag for the uploaded object (optional if client cannot access ETag header).
+ Only meaningful when success=true.
- Args:
- error_code: Client-side error code
-
- error_message: Client-side error message
-
- success: Whether the upload succeeded
+ size_bytes: Uploaded file size in bytes. Required when success=true.
extra_headers: Send extra headers
@@ -1044,26 +964,6 @@ async def confirm_upload(
timeout: Override the client-level default timeout for this request, in seconds
"""
- ...
-
- @required_args(["id", "size_bytes", "success"], ["id", "error_code", "error_message", "success"])
- async def confirm_upload(
- self,
- object_id: str,
- *,
- id: str,
- size_bytes: int | Omit = omit,
- success: Literal[True] | Literal[False],
- etag: str | Omit = omit,
- error_code: str | Omit = omit,
- error_message: 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,
- ) -> VaultConfirmUploadResponse:
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
if not object_id:
@@ -1072,11 +972,12 @@ async def confirm_upload(
path_template("/vault/{id}/upload/{object_id}/confirm", id=id, object_id=object_id),
body=await async_maybe_transform(
{
- "size_bytes": size_bytes,
"success": success,
- "etag": etag,
+ "auto_ingest": auto_ingest,
"error_code": error_code,
"error_message": error_message,
+ "etag": etag,
+ "size_bytes": size_bytes,
},
vault_confirm_upload_params.VaultConfirmUploadParams,
),
@@ -1100,14 +1001,13 @@ async def ingest(
) -> VaultIngestResponse:
"""
Triggers ingestion workflow for a vault object to extract text, generate chunks,
- and create embeddings. For supported file types (PDF, DOCX, PPTX, TXT, RTF, XML,
- HTML, Markdown, CSV/TSV, JSON/YAML/TOML, common source code files, ZIP, audio,
- video), processing happens asynchronously. ZIP archives are unpacked recursively
- up to 5 levels, and each extracted file is created as an independent vault
- object and ingested via the normal pipeline. For unsupported types (images,
- etc.), the file is marked as completed immediately without text extraction.
- GraphRAG indexing must be triggered separately via POST
- /vault/:id/graphrag/:objectId.
+ and create embeddings. For supported file types (PDF, DOCX, PPTX, XLSX, TXT,
+ RTF, XML, HTML, Markdown, CSV/TSV, JSON/YAML/TOML, common source code files,
+ ZIP, audio, video), processing happens asynchronously. ZIP archives are unpacked
+ recursively up to 5 levels, and each extracted file is created as an independent
+ vault object and ingested via the normal pipeline. For unsupported types
+ (images, etc.), the file is marked as completed immediately without text
+ extraction.
Args:
extra_headers: Send extra headers
@@ -1196,9 +1096,11 @@ async def upload(
content_type: str,
filename: str,
auto_index: bool | Omit = omit,
+ is_ai_generated: bool | Omit = omit,
metadata: object | Omit = omit,
path: str | Omit = omit,
size_bytes: int | Omit = omit,
+ idempotency_key: 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,
@@ -1218,6 +1120,10 @@ async def upload(
auto_index: Whether to automatically process and index the file for search
+ is_ai_generated: Marks the file as AI-generated work product (e.g. uploaded by an agent) rather
+ than a user-provided source document. Persisted on the object and returned by
+ object listings so clients can distinguish provenance.
+
metadata: Additional metadata to associate with the file
path: Optional folder path for hierarchy preservation. Allows integrations to maintain
@@ -1237,6 +1143,7 @@ async def upload(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {**strip_not_given({"Idempotency-Key": idempotency_key}), **(extra_headers or {})}
return await self._post(
path_template("/vault/{id}/upload", id=id),
body=await async_maybe_transform(
@@ -1244,6 +1151,7 @@ async def upload(
"content_type": content_type,
"filename": filename,
"auto_index": auto_index,
+ "is_ai_generated": is_ai_generated,
"metadata": metadata,
"path": path,
"size_bytes": size_bytes,
@@ -1293,11 +1201,6 @@ def __init__(self, vault: VaultResource) -> None:
def events(self) -> EventsResourceWithRawResponse:
return EventsResourceWithRawResponse(self._vault.events)
- @cached_property
- def graphrag(self) -> GraphragResourceWithRawResponse:
- """Secure document storage with semantic search and GraphRAG"""
- return GraphragResourceWithRawResponse(self._vault.graphrag)
-
@cached_property
def groups(self) -> GroupsResourceWithRawResponse:
"""Secure document storage with semantic search and GraphRAG"""
@@ -1310,12 +1213,12 @@ def multipart(self) -> MultipartResourceWithRawResponse:
@cached_property
def objects(self) -> ObjectsResourceWithRawResponse:
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault object management, content access, and document operations"""
return ObjectsResourceWithRawResponse(self._vault.objects)
@cached_property
def memory(self) -> MemoryResourceWithRawResponse:
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault-scoped persistent memory and semantic retrieval"""
return MemoryResourceWithRawResponse(self._vault.memory)
@@ -1355,11 +1258,6 @@ def __init__(self, vault: AsyncVaultResource) -> None:
def events(self) -> AsyncEventsResourceWithRawResponse:
return AsyncEventsResourceWithRawResponse(self._vault.events)
- @cached_property
- def graphrag(self) -> AsyncGraphragResourceWithRawResponse:
- """Secure document storage with semantic search and GraphRAG"""
- return AsyncGraphragResourceWithRawResponse(self._vault.graphrag)
-
@cached_property
def groups(self) -> AsyncGroupsResourceWithRawResponse:
"""Secure document storage with semantic search and GraphRAG"""
@@ -1372,12 +1270,12 @@ def multipart(self) -> AsyncMultipartResourceWithRawResponse:
@cached_property
def objects(self) -> AsyncObjectsResourceWithRawResponse:
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault object management, content access, and document operations"""
return AsyncObjectsResourceWithRawResponse(self._vault.objects)
@cached_property
def memory(self) -> AsyncMemoryResourceWithRawResponse:
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault-scoped persistent memory and semantic retrieval"""
return AsyncMemoryResourceWithRawResponse(self._vault.memory)
@@ -1417,11 +1315,6 @@ def __init__(self, vault: VaultResource) -> None:
def events(self) -> EventsResourceWithStreamingResponse:
return EventsResourceWithStreamingResponse(self._vault.events)
- @cached_property
- def graphrag(self) -> GraphragResourceWithStreamingResponse:
- """Secure document storage with semantic search and GraphRAG"""
- return GraphragResourceWithStreamingResponse(self._vault.graphrag)
-
@cached_property
def groups(self) -> GroupsResourceWithStreamingResponse:
"""Secure document storage with semantic search and GraphRAG"""
@@ -1434,12 +1327,12 @@ def multipart(self) -> MultipartResourceWithStreamingResponse:
@cached_property
def objects(self) -> ObjectsResourceWithStreamingResponse:
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault object management, content access, and document operations"""
return ObjectsResourceWithStreamingResponse(self._vault.objects)
@cached_property
def memory(self) -> MemoryResourceWithStreamingResponse:
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault-scoped persistent memory and semantic retrieval"""
return MemoryResourceWithStreamingResponse(self._vault.memory)
@@ -1479,11 +1372,6 @@ def __init__(self, vault: AsyncVaultResource) -> None:
def events(self) -> AsyncEventsResourceWithStreamingResponse:
return AsyncEventsResourceWithStreamingResponse(self._vault.events)
- @cached_property
- def graphrag(self) -> AsyncGraphragResourceWithStreamingResponse:
- """Secure document storage with semantic search and GraphRAG"""
- return AsyncGraphragResourceWithStreamingResponse(self._vault.graphrag)
-
@cached_property
def groups(self) -> AsyncGroupsResourceWithStreamingResponse:
"""Secure document storage with semantic search and GraphRAG"""
@@ -1496,10 +1384,10 @@ def multipart(self) -> AsyncMultipartResourceWithStreamingResponse:
@cached_property
def objects(self) -> AsyncObjectsResourceWithStreamingResponse:
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault object management, content access, and document operations"""
return AsyncObjectsResourceWithStreamingResponse(self._vault.objects)
@cached_property
def memory(self) -> AsyncMemoryResourceWithStreamingResponse:
- """Secure document storage with semantic search and GraphRAG"""
+ """Vault-scoped persistent memory and semantic retrieval"""
return AsyncMemoryResourceWithStreamingResponse(self._vault.memory)
diff --git a/src/casedev/resources/voice/transcription.py b/src/casedev/resources/voice/transcription.py
index b59a94e1..5abd518d 100644
--- a/src/casedev/resources/voice/transcription.py
+++ b/src/casedev/resources/voice/transcription.py
@@ -71,13 +71,15 @@ def create(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> TranscriptionCreateResponse:
- """Creates an asynchronous transcription job for audio files.
+ """Creates an asynchronous transcription job for audio or video files.
- Supports two modes:
+ Supports two
+ modes:
**Vault-based (recommended)**: Pass `vault_id` and `object_id` to transcribe
- audio from your vault. The transcript will automatically be saved back to the
- vault when complete.
+ media from your vault. Large videos are converted to an internal MP3 derivative
+ before transcription while the original video remains the transcript source. The
+ transcript is automatically saved back to the vault when complete.
**Direct URL (legacy)**: Pass `audio_url` for direct transcription without
automatic storage.
@@ -280,13 +282,15 @@ async def create(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> TranscriptionCreateResponse:
- """Creates an asynchronous transcription job for audio files.
+ """Creates an asynchronous transcription job for audio or video files.
- Supports two modes:
+ Supports two
+ modes:
**Vault-based (recommended)**: Pass `vault_id` and `object_id` to transcribe
- audio from your vault. The transcript will automatically be saved back to the
- vault when complete.
+ media from your vault. Large videos are converted to an internal MP3 derivative
+ before transcription while the original video remains the transcript source. The
+ transcript is automatically saved back to the vault when complete.
**Direct URL (legacy)**: Pass `audio_url` for direct transcription without
automatic storage.
diff --git a/src/casedev/types/agent/v1/__init__.py b/src/casedev/types/agent/v1/__init__.py
deleted file mode 100644
index 0945cf54..00000000
--- a/src/casedev/types/agent/v1/__init__.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from .run_list_params import RunListParams as RunListParams
-from .run_watch_params import RunWatchParams as RunWatchParams
-from .agent_list_params import AgentListParams as AgentListParams
-from .run_create_params import RunCreateParams as RunCreateParams
-from .run_events_params import RunEventsParams as RunEventsParams
-from .run_exec_response import RunExecResponse as RunExecResponse
-from .run_list_response import RunListResponse as RunListResponse
-from .run_watch_response import RunWatchResponse as RunWatchResponse
-from .agent_create_params import AgentCreateParams as AgentCreateParams
-from .agent_list_response import AgentListResponse as AgentListResponse
-from .agent_update_params import AgentUpdateParams as AgentUpdateParams
-from .run_cancel_response import RunCancelResponse as RunCancelResponse
-from .run_create_response import RunCreateResponse as RunCreateResponse
-from .run_events_response import RunEventsResponse as RunEventsResponse
-from .agent_create_response import AgentCreateResponse as AgentCreateResponse
-from .agent_delete_response import AgentDeleteResponse as AgentDeleteResponse
-from .agent_update_response import AgentUpdateResponse as AgentUpdateResponse
-from .execute_create_params import ExecuteCreateParams as ExecuteCreateParams
-from .agent_retrieve_response import AgentRetrieveResponse as AgentRetrieveResponse
-from .execute_create_response import ExecuteCreateResponse as ExecuteCreateResponse
-from .run_get_status_response import RunGetStatusResponse as RunGetStatusResponse
-from .run_get_details_response import RunGetDetailsResponse as RunGetDetailsResponse
diff --git a/src/casedev/types/agent/v1/agent_create_params.py b/src/casedev/types/agent/v1/agent_create_params.py
deleted file mode 100644
index 35829b58..00000000
--- a/src/casedev/types/agent/v1/agent_create_params.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Optional
-from typing_extensions import Required, Annotated, TypedDict
-
-from ...._types import SequenceNotStr
-from ...._utils import PropertyInfo
-
-__all__ = ["AgentCreateParams", "Sandbox"]
-
-
-class AgentCreateParams(TypedDict, total=False):
- instructions: Required[str]
- """System instructions that define agent behavior"""
-
- name: Required[str]
- """Display name for the agent"""
-
- description: str
- """Optional description of the agent"""
-
- disabled_tools: Annotated[Optional[SequenceNotStr[str]], PropertyInfo(alias="disabledTools")]
- """Denylist of tools the agent cannot use.
-
- Mutually exclusive with enabledTools — set one or the other, not both.
- """
-
- enabled_tools: Annotated[Optional[SequenceNotStr[str]], PropertyInfo(alias="enabledTools")]
- """Allowlist of tools the agent can use.
-
- Mutually exclusive with disabledTools — set one or the other, not both.
- """
-
- model: str
- """LLM model identifier (e.g.
-
- anthropic/claude-sonnet-4.6). Defaults to anthropic/claude-sonnet-4.6
- """
-
- sandbox: Optional[Sandbox]
- """Custom sandbox configuration (cpu, memoryMiB)"""
-
- vault_groups: Annotated[Optional[SequenceNotStr[str]], PropertyInfo(alias="vaultGroups")]
- """Restrict agent to vaults within specific vault group IDs"""
-
- vault_ids: Annotated[Optional[SequenceNotStr[str]], PropertyInfo(alias="vaultIds")]
- """Restrict agent to specific vault IDs"""
-
-
-class Sandbox(TypedDict, total=False):
- """Custom sandbox configuration (cpu, memoryMiB)"""
-
- cpu: int
- """Number of CPUs"""
-
- memory_mi_b: Annotated[int, PropertyInfo(alias="memoryMiB")]
- """Memory in MiB"""
diff --git a/src/casedev/types/agent/v1/agent_create_response.py b/src/casedev/types/agent/v1/agent_create_response.py
deleted file mode 100644
index e905bb0c..00000000
--- a/src/casedev/types/agent/v1/agent_create_response.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-
-from pydantic import Field as FieldInfo
-
-from ...._models import BaseModel
-
-__all__ = ["AgentCreateResponse"]
-
-
-class AgentCreateResponse(BaseModel):
- id: Optional[str] = None
-
- created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None)
-
- description: Optional[str] = None
-
- disabled_tools: Optional[List[str]] = FieldInfo(alias="disabledTools", default=None)
-
- enabled_tools: Optional[List[str]] = FieldInfo(alias="enabledTools", default=None)
-
- instructions: Optional[str] = None
-
- model: Optional[str] = None
-
- name: Optional[str] = None
-
- sandbox: Optional[object] = None
-
- updated_at: Optional[datetime] = FieldInfo(alias="updatedAt", default=None)
-
- vault_ids: Optional[List[str]] = FieldInfo(alias="vaultIds", default=None)
diff --git a/src/casedev/types/agent/v1/agent_delete_response.py b/src/casedev/types/agent/v1/agent_delete_response.py
deleted file mode 100644
index 148d8f52..00000000
--- a/src/casedev/types/agent/v1/agent_delete_response.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-
-from ...._models import BaseModel
-
-__all__ = ["AgentDeleteResponse"]
-
-
-class AgentDeleteResponse(BaseModel):
- ok: Optional[bool] = None
diff --git a/src/casedev/types/agent/v1/agent_list_params.py b/src/casedev/types/agent/v1/agent_list_params.py
deleted file mode 100644
index f41fc45d..00000000
--- a/src/casedev/types/agent/v1/agent_list_params.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import TypedDict
-
-__all__ = ["AgentListParams"]
-
-
-class AgentListParams(TypedDict, total=False):
- cursor: str
- """Pagination cursor (agent ID from previous page).
-
- Returns agents created before this agent.
- """
-
- limit: int
- """Maximum number of agents to return (default 50, max 250)"""
diff --git a/src/casedev/types/agent/v1/agent_list_response.py b/src/casedev/types/agent/v1/agent_list_response.py
deleted file mode 100644
index cba2c4b1..00000000
--- a/src/casedev/types/agent/v1/agent_list_response.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-
-from pydantic import Field as FieldInfo
-
-from ...._models import BaseModel
-
-__all__ = ["AgentListResponse", "Agent"]
-
-
-class Agent(BaseModel):
- id: Optional[str] = None
-
- created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None)
-
- description: Optional[str] = None
-
- is_active: Optional[bool] = FieldInfo(alias="isActive", default=None)
-
- model: Optional[str] = None
-
- name: Optional[str] = None
-
- updated_at: Optional[datetime] = FieldInfo(alias="updatedAt", default=None)
-
- vault_ids: Optional[List[str]] = FieldInfo(alias="vaultIds", default=None)
-
-
-class AgentListResponse(BaseModel):
- agents: Optional[List[Agent]] = None
-
- has_more: Optional[bool] = FieldInfo(alias="hasMore", default=None)
-
- next_cursor: Optional[str] = FieldInfo(alias="nextCursor", default=None)
- """Pass as cursor to fetch the next page"""
diff --git a/src/casedev/types/agent/v1/agent_retrieve_response.py b/src/casedev/types/agent/v1/agent_retrieve_response.py
deleted file mode 100644
index 4c8fc445..00000000
--- a/src/casedev/types/agent/v1/agent_retrieve_response.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-
-from pydantic import Field as FieldInfo
-
-from ...._models import BaseModel
-
-__all__ = ["AgentRetrieveResponse"]
-
-
-class AgentRetrieveResponse(BaseModel):
- id: Optional[str] = None
-
- created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None)
-
- description: Optional[str] = None
-
- disabled_tools: Optional[List[str]] = FieldInfo(alias="disabledTools", default=None)
-
- enabled_tools: Optional[List[str]] = FieldInfo(alias="enabledTools", default=None)
-
- instructions: Optional[str] = None
-
- is_active: Optional[bool] = FieldInfo(alias="isActive", default=None)
-
- model: Optional[str] = None
-
- name: Optional[str] = None
-
- sandbox: Optional[object] = None
-
- updated_at: Optional[datetime] = FieldInfo(alias="updatedAt", default=None)
-
- vault_ids: Optional[List[str]] = FieldInfo(alias="vaultIds", default=None)
diff --git a/src/casedev/types/agent/v1/agent_update_params.py b/src/casedev/types/agent/v1/agent_update_params.py
deleted file mode 100644
index 5084402d..00000000
--- a/src/casedev/types/agent/v1/agent_update_params.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Optional
-from typing_extensions import Annotated, TypedDict
-
-from ...._types import SequenceNotStr
-from ...._utils import PropertyInfo
-
-__all__ = ["AgentUpdateParams"]
-
-
-class AgentUpdateParams(TypedDict, total=False):
- description: Optional[str]
- """Updated agent description. Pass null to clear if supported by the client."""
-
- disabled_tools: Annotated[Optional[SequenceNotStr[str]], PropertyInfo(alias="disabledTools")]
- """Denylist of tools the agent cannot use.
-
- Mutually exclusive with enabledTools — set one or the other, not both. Pass null
- to clear.
- """
-
- enabled_tools: Annotated[Optional[SequenceNotStr[str]], PropertyInfo(alias="enabledTools")]
- """Allowlist of tools the agent can use.
-
- Mutually exclusive with disabledTools — set one or the other, not both. Pass
- null to clear.
- """
-
- instructions: str
- """Updated system instructions that guide agent behavior"""
-
- model: str
- """Model identifier the agent should use for future runs"""
-
- name: str
- """Updated agent display name"""
-
- sandbox: Optional[object]
- """Sandbox configuration override for future agent runs. Pass null to clear."""
-
- vault_groups: Annotated[Optional[SequenceNotStr[str]], PropertyInfo(alias="vaultGroups")]
- """Vault group IDs the agent can access. Pass null to clear."""
-
- vault_ids: Annotated[Optional[SequenceNotStr[str]], PropertyInfo(alias="vaultIds")]
- """Vault IDs the agent can access directly. Pass null to clear."""
diff --git a/src/casedev/types/agent/v1/agent_update_response.py b/src/casedev/types/agent/v1/agent_update_response.py
deleted file mode 100644
index 8f6ddb17..00000000
--- a/src/casedev/types/agent/v1/agent_update_response.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-
-from pydantic import Field as FieldInfo
-
-from ...._models import BaseModel
-
-__all__ = ["AgentUpdateResponse"]
-
-
-class AgentUpdateResponse(BaseModel):
- id: Optional[str] = None
-
- created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None)
-
- description: Optional[str] = None
-
- disabled_tools: Optional[List[str]] = FieldInfo(alias="disabledTools", default=None)
-
- enabled_tools: Optional[List[str]] = FieldInfo(alias="enabledTools", default=None)
-
- instructions: Optional[str] = None
-
- is_active: Optional[bool] = FieldInfo(alias="isActive", default=None)
-
- model: Optional[str] = None
-
- name: Optional[str] = None
-
- sandbox: Optional[object] = None
-
- updated_at: Optional[datetime] = FieldInfo(alias="updatedAt", default=None)
-
- vault_groups: Optional[List[str]] = FieldInfo(alias="vaultGroups", default=None)
-
- vault_ids: Optional[List[str]] = FieldInfo(alias="vaultIds", default=None)
diff --git a/src/casedev/types/agent/v1/execute_create_params.py b/src/casedev/types/agent/v1/execute_create_params.py
deleted file mode 100644
index de00ee22..00000000
--- a/src/casedev/types/agent/v1/execute_create_params.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Optional
-from typing_extensions import Required, Annotated, TypedDict
-
-from ...._types import SequenceNotStr
-from ...._utils import PropertyInfo
-
-__all__ = ["ExecuteCreateParams", "Sandbox"]
-
-
-class ExecuteCreateParams(TypedDict, total=False):
- prompt: Required[str]
- """Task prompt for the agent"""
-
- disabled_tools: Annotated[Optional[SequenceNotStr[str]], PropertyInfo(alias="disabledTools")]
- """Denylist of tools the agent cannot use.
-
- Mutually exclusive with enabledTools — set one or the other, not both.
- """
-
- enabled_tools: Annotated[Optional[SequenceNotStr[str]], PropertyInfo(alias="enabledTools")]
- """Allowlist of tools the agent can use.
-
- Mutually exclusive with disabledTools — set one or the other, not both.
- """
-
- guidance: Optional[str]
- """Additional context or constraints for this run"""
-
- instructions: str
- """System instructions.
-
- Defaults to a general-purpose legal assistant prompt if not provided.
- """
-
- model: str
- """LLM model identifier. Defaults to anthropic/claude-sonnet-4.6"""
-
- object_ids: Annotated[Optional[SequenceNotStr[str]], PropertyInfo(alias="objectIds")]
- """Scope this run to specific vault object IDs.
-
- The agent will only access these objects.
- """
-
- sandbox: Optional[Sandbox]
- """Custom sandbox resources (cpu, memoryMiB)"""
-
- vault_ids: Annotated[Optional[SequenceNotStr[str]], PropertyInfo(alias="vaultIds")]
- """Restrict agent to specific vault IDs"""
-
-
-class Sandbox(TypedDict, total=False):
- """Custom sandbox resources (cpu, memoryMiB)"""
-
- cpu: int
- """Number of CPUs"""
-
- memory_mi_b: Annotated[int, PropertyInfo(alias="memoryMiB")]
- """Memory in MiB"""
diff --git a/src/casedev/types/agent/v1/execute_create_response.py b/src/casedev/types/agent/v1/execute_create_response.py
deleted file mode 100644
index 018d200a..00000000
--- a/src/casedev/types/agent/v1/execute_create_response.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from typing_extensions import Literal
-
-from pydantic import Field as FieldInfo
-
-from ...._models import BaseModel
-
-__all__ = ["ExecuteCreateResponse"]
-
-
-class ExecuteCreateResponse(BaseModel):
- agent_id: Optional[str] = FieldInfo(alias="agentId", default=None)
- """Ephemeral agent ID (auto-created).
-
- This agent is soft-deleted when the run completes and should not be stored for
- reuse.
- """
-
- message: Optional[str] = None
-
- run_id: Optional[str] = FieldInfo(alias="runId", default=None)
- """Run ID — poll /agent/v1/run/:id/status"""
-
- status: Optional[Literal["running"]] = None
diff --git a/src/casedev/types/agent/v1/run_cancel_response.py b/src/casedev/types/agent/v1/run_cancel_response.py
deleted file mode 100644
index bffdcd26..00000000
--- a/src/casedev/types/agent/v1/run_cancel_response.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from typing_extensions import Literal
-
-from ...._models import BaseModel
-
-__all__ = ["RunCancelResponse"]
-
-
-class RunCancelResponse(BaseModel):
- id: Optional[str] = None
-
- message: Optional[str] = None
- """Present if run was already finished"""
-
- status: Optional[Literal["cancelled", "completed", "failed"]] = None
diff --git a/src/casedev/types/agent/v1/run_create_params.py b/src/casedev/types/agent/v1/run_create_params.py
deleted file mode 100644
index d6a462f1..00000000
--- a/src/casedev/types/agent/v1/run_create_params.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Optional
-from typing_extensions import Required, Annotated, TypedDict
-
-from ...._types import SequenceNotStr
-from ...._utils import PropertyInfo
-
-__all__ = ["RunCreateParams"]
-
-
-class RunCreateParams(TypedDict, total=False):
- agent_id: Required[Annotated[str, PropertyInfo(alias="agentId")]]
- """ID of the agent to run"""
-
- prompt: Required[str]
- """Task prompt for the agent"""
-
- callback_url: Annotated[Optional[str], PropertyInfo(alias="callbackUrl")]
- """HTTPS callback URL to receive a notification when the run completes.
-
- Registered atomically with the run — eliminates the race condition of calling
- /watch after /exec. Additional watchers can still be added via POST
- /run/:id/watch.
- """
-
- guidance: Optional[str]
- """Additional guidance for this run"""
-
- model: Optional[str]
- """Override the agent default model for this run"""
-
- object_ids: Annotated[Optional[SequenceNotStr[str]], PropertyInfo(alias="objectIds")]
- """Scope this run to specific vault object IDs.
-
- The agent will only be able to access these objects during execution.
- """
diff --git a/src/casedev/types/agent/v1/run_create_response.py b/src/casedev/types/agent/v1/run_create_response.py
deleted file mode 100644
index 94c9e9c9..00000000
--- a/src/casedev/types/agent/v1/run_create_response.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from pydantic import Field as FieldInfo
-
-from ...._models import BaseModel
-
-__all__ = ["RunCreateResponse"]
-
-
-class RunCreateResponse(BaseModel):
- id: Optional[str] = None
-
- agent_id: Optional[str] = FieldInfo(alias="agentId", default=None)
-
- created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None)
-
- object_ids: Optional[List[str]] = FieldInfo(alias="objectIds", default=None)
-
- status: Optional[Literal["queued"]] = None
diff --git a/src/casedev/types/agent/v1/run_events_params.py b/src/casedev/types/agent/v1/run_events_params.py
deleted file mode 100644
index d84c2f53..00000000
--- a/src/casedev/types/agent/v1/run_events_params.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Annotated, TypedDict
-
-from ...._utils import PropertyInfo
-
-__all__ = ["RunEventsParams"]
-
-
-class RunEventsParams(TypedDict, total=False):
- last_event_id: Annotated[int, PropertyInfo(alias="lastEventId")]
- """Replay events after this sequence number"""
diff --git a/src/casedev/types/agent/v1/run_events_response.py b/src/casedev/types/agent/v1/run_events_response.py
deleted file mode 100644
index 2f6d8654..00000000
--- a/src/casedev/types/agent/v1/run_events_response.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing_extensions import TypeAlias
-
-__all__ = ["RunEventsResponse"]
-
-RunEventsResponse: TypeAlias = str
diff --git a/src/casedev/types/agent/v1/run_exec_response.py b/src/casedev/types/agent/v1/run_exec_response.py
deleted file mode 100644
index 75d7a5f0..00000000
--- a/src/casedev/types/agent/v1/run_exec_response.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from typing_extensions import Literal
-
-from pydantic import Field as FieldInfo
-
-from ...._models import BaseModel
-
-__all__ = ["RunExecResponse"]
-
-
-class RunExecResponse(BaseModel):
- id: Optional[str] = None
-
- message: Optional[str] = None
-
- status: Optional[Literal["running"]] = None
-
- workflow_id: Optional[str] = FieldInfo(alias="workflowId", default=None)
- """Durable workflow run ID"""
diff --git a/src/casedev/types/agent/v1/run_get_details_response.py b/src/casedev/types/agent/v1/run_get_details_response.py
deleted file mode 100644
index eb56113f..00000000
--- a/src/casedev/types/agent/v1/run_get_details_response.py
+++ /dev/null
@@ -1,176 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from pydantic import Field as FieldInfo
-
-from ...._models import BaseModel
-
-__all__ = [
- "RunGetDetailsResponse",
- "Result",
- "ResultFinalResponse",
- "ResultLogs",
- "Step",
- "Usage",
- "UsageEntry",
- "UsageSummary",
-]
-
-
-class ResultFinalResponse(BaseModel):
- """Compact agent-facing result summary and execution issues"""
-
- created_object_ids: Optional[List[str]] = FieldInfo(alias="createdObjectIds", default=None)
-
- issues: Optional[List[str]] = None
-
- summary: Optional[str] = None
-
-
-class ResultLogs(BaseModel):
- """Sandbox execution logs (runtime server + runner script)"""
-
- opencode: Optional[str] = None
- """Legacy runtime server stdout/stderr"""
-
- runner: Optional[str] = None
- """Runner script stdout/stderr"""
-
- runtime: Optional[str] = None
- """Runtime server stdout/stderr"""
-
-
-class Result(BaseModel):
- """Final output from the agent"""
-
- final_response: Optional[ResultFinalResponse] = FieldInfo(alias="finalResponse", default=None)
- """Compact agent-facing result summary and execution issues"""
-
- logs: Optional[ResultLogs] = None
- """Sandbox execution logs (runtime server + runner script)"""
-
- output: Optional[str] = None
-
- output_object_ids: Optional[List[str]] = FieldInfo(alias="outputObjectIds", default=None)
-
-
-class Step(BaseModel):
- id: Optional[str] = None
-
- content: Optional[str] = None
-
- duration_ms: Optional[int] = FieldInfo(alias="durationMs", default=None)
-
- timestamp: Optional[datetime] = None
-
- tool_input: Optional[object] = FieldInfo(alias="toolInput", default=None)
-
- tool_name: Optional[str] = FieldInfo(alias="toolName", default=None)
-
- tool_output: Optional[object] = FieldInfo(alias="toolOutput", default=None)
-
- type: Optional[Literal["output", "thinking", "tool_call", "tool_result"]] = None
-
-
-class UsageEntry(BaseModel):
- id: Optional[str] = None
-
- completion_tokens: Optional[int] = FieldInfo(alias="completionTokens", default=None)
-
- cost_micros: Optional[int] = FieldInfo(alias="costMicros", default=None)
-
- endpoint: Optional[str] = None
-
- kind: Optional[Literal["llm", "api"]] = None
-
- metadata: Optional[object] = None
-
- method: Optional[str] = None
-
- model: Optional[str] = None
-
- prompt_tokens: Optional[int] = FieldInfo(alias="promptTokens", default=None)
-
- service: Optional[str] = None
-
- status_code: Optional[int] = FieldInfo(alias="statusCode", default=None)
-
- timestamp: Optional[datetime] = None
-
- total_tokens: Optional[int] = FieldInfo(alias="totalTokens", default=None)
-
-
-class UsageSummary(BaseModel):
- cost_micros: Optional[int] = FieldInfo(alias="costMicros", default=None)
-
- total_input_tokens: Optional[int] = FieldInfo(alias="totalInputTokens", default=None)
-
- total_output_tokens: Optional[int] = FieldInfo(alias="totalOutputTokens", default=None)
-
- total_tokens: Optional[int] = FieldInfo(alias="totalTokens", default=None)
-
-
-class Usage(BaseModel):
- """Token usage statistics"""
-
- duration_ms: Optional[int] = FieldInfo(alias="durationMs", default=None)
-
- entries: Optional[List[UsageEntry]] = None
-
- input_tokens: Optional[int] = FieldInfo(alias="inputTokens", default=None)
-
- model: Optional[str] = None
-
- output_tokens: Optional[int] = FieldInfo(alias="outputTokens", default=None)
-
- summary: Optional[UsageSummary] = None
-
- tool_calls: Optional[int] = FieldInfo(alias="toolCalls", default=None)
-
-
-class RunGetDetailsResponse(BaseModel):
- id: Optional[str] = None
-
- agent_id: Optional[str] = FieldInfo(alias="agentId", default=None)
-
- completed_at: Optional[datetime] = FieldInfo(alias="completedAt", default=None)
-
- created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None)
-
- guidance: Optional[str] = None
-
- modal_sandbox_id: Optional[str] = FieldInfo(alias="modalSandboxId", default=None)
- """Deprecated legacy Modal sandbox ID. Prefer `provider` and `runtimeId`."""
-
- model: Optional[str] = None
-
- prompt: Optional[str] = None
-
- provider: Optional[Literal["daytona", "vercel"]] = None
- """Runtime provider for this run"""
-
- result: Optional[Result] = None
- """Final output from the agent"""
-
- runtime_id: Optional[str] = FieldInfo(alias="runtimeId", default=None)
- """Provider-specific runtime identifier"""
-
- runtime_state: Optional[Literal["running", "stopped", "archived", "ended", "error"]] = FieldInfo(
- alias="runtimeState", default=None
- )
- """Current runtime state, when available"""
-
- started_at: Optional[datetime] = FieldInfo(alias="startedAt", default=None)
-
- status: Optional[Literal["queued", "running", "completed", "failed", "cancelled"]] = None
-
- steps: Optional[List[Step]] = None
-
- usage: Optional[Usage] = None
- """Token usage statistics"""
-
- workflow_id: Optional[str] = FieldInfo(alias="workflowId", default=None)
- """Durable workflow run ID"""
diff --git a/src/casedev/types/agent/v1/run_get_status_response.py b/src/casedev/types/agent/v1/run_get_status_response.py
deleted file mode 100644
index 4bb9a677..00000000
--- a/src/casedev/types/agent/v1/run_get_status_response.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from pydantic import Field as FieldInfo
-
-from ...._models import BaseModel
-
-__all__ = ["RunGetStatusResponse"]
-
-
-class RunGetStatusResponse(BaseModel):
- id: Optional[str] = None
-
- completed_at: Optional[datetime] = FieldInfo(alias="completedAt", default=None)
-
- duration_ms: Optional[int] = FieldInfo(alias="durationMs", default=None)
- """Elapsed time in milliseconds"""
-
- started_at: Optional[datetime] = FieldInfo(alias="startedAt", default=None)
-
- status: Optional[Literal["queued", "running", "completed", "failed", "cancelled"]] = None
diff --git a/src/casedev/types/agent/v1/run_list_params.py b/src/casedev/types/agent/v1/run_list_params.py
deleted file mode 100644
index b38a400b..00000000
--- a/src/casedev/types/agent/v1/run_list_params.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal, Annotated, TypedDict
-
-from ...._utils import PropertyInfo
-
-__all__ = ["RunListParams"]
-
-
-class RunListParams(TypedDict, total=False):
- agent_id: Annotated[str, PropertyInfo(alias="agentId")]
- """Filter by agent ID"""
-
- cursor: str
- """Pagination cursor (run ID from previous page).
-
- Returns runs created before this run.
- """
-
- limit: int
- """Maximum number of runs to return (default 50, max 250)"""
-
- status: Literal["queued", "running", "completed", "failed", "cancelled"]
- """Filter by run status"""
diff --git a/src/casedev/types/agent/v1/run_list_response.py b/src/casedev/types/agent/v1/run_list_response.py
deleted file mode 100644
index 94ce4842..00000000
--- a/src/casedev/types/agent/v1/run_list_response.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from pydantic import Field as FieldInfo
-
-from ...._models import BaseModel
-
-__all__ = ["RunListResponse", "Run"]
-
-
-class Run(BaseModel):
- id: Optional[str] = None
-
- agent_id: Optional[str] = FieldInfo(alias="agentId", default=None)
-
- completed_at: Optional[datetime] = FieldInfo(alias="completedAt", default=None)
-
- created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None)
-
- model: Optional[str] = None
-
- prompt: Optional[str] = None
- """Truncated to first 200 characters"""
-
- started_at: Optional[datetime] = FieldInfo(alias="startedAt", default=None)
-
- status: Optional[Literal["queued", "running", "completed", "failed", "cancelled"]] = None
-
-
-class RunListResponse(BaseModel):
- has_more: Optional[bool] = FieldInfo(alias="hasMore", default=None)
-
- next_cursor: Optional[str] = FieldInfo(alias="nextCursor", default=None)
- """Pass as cursor to fetch the next page"""
-
- runs: Optional[List[Run]] = None
diff --git a/src/casedev/types/agent/v1/run_watch_params.py b/src/casedev/types/agent/v1/run_watch_params.py
deleted file mode 100644
index 8b80a795..00000000
--- a/src/casedev/types/agent/v1/run_watch_params.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Required, Annotated, TypedDict
-
-from ...._utils import PropertyInfo
-
-__all__ = ["RunWatchParams"]
-
-
-class RunWatchParams(TypedDict, total=False):
- callback_url: Required[Annotated[str, PropertyInfo(alias="callbackUrl")]]
- """HTTPS URL to receive completion callback"""
diff --git a/src/casedev/types/agent/v1/run_watch_response.py b/src/casedev/types/agent/v1/run_watch_response.py
deleted file mode 100644
index bf336e5d..00000000
--- a/src/casedev/types/agent/v1/run_watch_response.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-
-from pydantic import Field as FieldInfo
-
-from ...._models import BaseModel
-
-__all__ = ["RunWatchResponse"]
-
-
-class RunWatchResponse(BaseModel):
- callback_url: Optional[str] = FieldInfo(alias="callbackUrl", default=None)
-
- ok: Optional[bool] = None
diff --git a/src/casedev/types/connectors/__init__.py b/src/casedev/types/connectors/__init__.py
new file mode 100644
index 00000000..bac598e1
--- /dev/null
+++ b/src/casedev/types/connectors/__init__.py
@@ -0,0 +1,8 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .v1_transfer_params import V1TransferParams as V1TransferParams
+from .v1_sync_link_params import V1SyncLinkParams as V1SyncLinkParams
+from .v1_transfer_response import V1TransferResponse as V1TransferResponse
+from .v1_sync_link_response import V1SyncLinkResponse as V1SyncLinkResponse
diff --git a/src/casedev/types/connectors/v1/__init__.py b/src/casedev/types/connectors/v1/__init__.py
new file mode 100644
index 00000000..70a6e820
--- /dev/null
+++ b/src/casedev/types/connectors/v1/__init__.py
@@ -0,0 +1,17 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .link_list_params import LinkListParams as LinkListParams
+from .link_delete_params import LinkDeleteParams as LinkDeleteParams
+from .link_update_params import LinkUpdateParams as LinkUpdateParams
+from .connection_list_params import ConnectionListParams as ConnectionListParams
+from .connection_browse_params import ConnectionBrowseParams as ConnectionBrowseParams
+from .connection_create_params import ConnectionCreateParams as ConnectionCreateParams
+from .connection_delete_params import ConnectionDeleteParams as ConnectionDeleteParams
+from .connection_list_response import ConnectionListResponse as ConnectionListResponse
+from .installation_list_params import InstallationListParams as InstallationListParams
+from .link_list_objects_params import LinkListObjectsParams as LinkListObjectsParams
+from .connection_browse_response import ConnectionBrowseResponse as ConnectionBrowseResponse
+from .connection_create_response import ConnectionCreateResponse as ConnectionCreateResponse
+from .installation_ensure_params import InstallationEnsureParams as InstallationEnsureParams
diff --git a/src/casedev/types/connectors/v1/connection_browse_params.py b/src/casedev/types/connectors/v1/connection_browse_params.py
new file mode 100644
index 00000000..a59e7886
--- /dev/null
+++ b/src/casedev/types/connectors/v1/connection_browse_params.py
@@ -0,0 +1,25 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypedDict
+
+__all__ = ["ConnectionBrowseParams"]
+
+
+class ConnectionBrowseParams(TypedDict, total=False):
+ container: str
+ """Container id to list, or the container containing parent"""
+
+ cursor: str
+
+ page_size: int
+
+ parent: str
+ """Folder id to list"""
+
+ query: str
+ """Optional provider-supported search text"""
+
+ site: str
+ """Site id to list"""
diff --git a/src/casedev/types/connectors/v1/connection_browse_response.py b/src/casedev/types/connectors/v1/connection_browse_response.py
new file mode 100644
index 00000000..e6f59a9b
--- /dev/null
+++ b/src/casedev/types/connectors/v1/connection_browse_response.py
@@ -0,0 +1,36 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from typing_extensions import Literal
+
+from ...._models import BaseModel
+
+__all__ = ["ConnectionBrowseResponse", "Item"]
+
+
+class Item(BaseModel):
+ id: Optional[str] = None
+
+ browse_ref: Optional[object] = None
+
+ container_id: Optional[str] = None
+
+ kind: Optional[Literal["my_drive", "shared_drive", "matter", "site", "document_library", "folder", "file"]] = None
+
+ mime_type: Optional[str] = None
+
+ modified_at: Optional[str] = None
+
+ name: Optional[str] = None
+
+ parent_ids: Optional[List[str]] = None
+
+ path: Optional[str] = None
+
+ size_bytes: Optional[int] = None
+
+
+class ConnectionBrowseResponse(BaseModel):
+ cursor: Optional[str] = None
+
+ items: Optional[List[Item]] = None
diff --git a/src/casedev/types/connectors/v1/connection_create_params.py b/src/casedev/types/connectors/v1/connection_create_params.py
new file mode 100644
index 00000000..3a497030
--- /dev/null
+++ b/src/casedev/types/connectors/v1/connection_create_params.py
@@ -0,0 +1,17 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, Required, TypedDict
+
+__all__ = ["ConnectionCreateParams"]
+
+
+class ConnectionCreateParams(TypedDict, total=False):
+ provider: Required[Literal["clio", "gdrive", "microsoft"]]
+
+ return_url: Required[str]
+ """HTTPS URL the user is sent back to after consent."""
+
+ scope_tier: Literal["clio.us", "drive", "microsoft.read"]
+ """Provider-specific OAuth permission tier. Omit to use the provider's default."""
diff --git a/src/casedev/types/connectors/v1/connection_create_response.py b/src/casedev/types/connectors/v1/connection_create_response.py
new file mode 100644
index 00000000..35cb8354
--- /dev/null
+++ b/src/casedev/types/connectors/v1/connection_create_response.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from ...._models import BaseModel
+
+__all__ = ["ConnectionCreateResponse"]
+
+
+class ConnectionCreateResponse(BaseModel):
+ connect_url: Optional[str] = None
+
+ connection_id: Optional[str] = None
+
+ expires_at: Optional[str] = None
diff --git a/src/casedev/types/connectors/v1/connection_delete_params.py b/src/casedev/types/connectors/v1/connection_delete_params.py
new file mode 100644
index 00000000..3d9393fc
--- /dev/null
+++ b/src/casedev/types/connectors/v1/connection_delete_params.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypedDict
+
+__all__ = ["ConnectionDeleteParams"]
+
+
+class ConnectionDeleteParams(TypedDict, total=False):
+ purge: bool
diff --git a/src/casedev/types/connectors/v1/connection_list_params.py b/src/casedev/types/connectors/v1/connection_list_params.py
new file mode 100644
index 00000000..499dad23
--- /dev/null
+++ b/src/casedev/types/connectors/v1/connection_list_params.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, TypedDict
+
+__all__ = ["ConnectionListParams"]
+
+
+class ConnectionListParams(TypedDict, total=False):
+ provider: str
+
+ status: Literal["pending", "healthy", "reauth_required", "revoked", "throttled"]
diff --git a/src/casedev/types/connectors/v1/connection_list_response.py b/src/casedev/types/connectors/v1/connection_list_response.py
new file mode 100644
index 00000000..b757da49
--- /dev/null
+++ b/src/casedev/types/connectors/v1/connection_list_response.py
@@ -0,0 +1,19 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+
+from ...._models import BaseModel
+
+__all__ = ["ConnectionListResponse", "Capabilities"]
+
+
+class Capabilities(BaseModel):
+ google_drive_folder_mirroring: Optional[bool] = None
+
+
+class ConnectionListResponse(BaseModel):
+ capabilities: Optional[Capabilities] = None
+
+ connections: Optional[List[object]] = None
+
+ cursor: Optional[str] = None
diff --git a/src/casedev/types/connectors/v1/installation_ensure_params.py b/src/casedev/types/connectors/v1/installation_ensure_params.py
new file mode 100644
index 00000000..67838149
--- /dev/null
+++ b/src/casedev/types/connectors/v1/installation_ensure_params.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["InstallationEnsureParams"]
+
+
+class InstallationEnsureParams(TypedDict, total=False):
+ application: Required[str]
+ """Consuming application key (e.g. "p3")."""
+
+ external_tenant_id: Required[str]
+ """The application's own tenant identifier (e.g. a P3 organization id)."""
diff --git a/src/casedev/types/connectors/v1/installation_list_params.py b/src/casedev/types/connectors/v1/installation_list_params.py
new file mode 100644
index 00000000..127b7ef9
--- /dev/null
+++ b/src/casedev/types/connectors/v1/installation_list_params.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypedDict
+
+__all__ = ["InstallationListParams"]
+
+
+class InstallationListParams(TypedDict, total=False):
+ application: str
+
+ external_tenant_id: str
diff --git a/src/casedev/types/mail/__init__.py b/src/casedev/types/connectors/v1/installations/__init__.py
similarity index 63%
rename from src/casedev/types/mail/__init__.py
rename to src/casedev/types/connectors/v1/installations/__init__.py
index f8ee8b14..c5bb68eb 100644
--- a/src/casedev/types/mail/__init__.py
+++ b/src/casedev/types/connectors/v1/installations/__init__.py
@@ -1,3 +1,5 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from __future__ import annotations
+
+from .vault_grant_params import VaultGrantParams as VaultGrantParams
diff --git a/src/casedev/types/connectors/v1/installations/vault_grant_params.py b/src/casedev/types/connectors/v1/installations/vault_grant_params.py
new file mode 100644
index 00000000..8080f447
--- /dev/null
+++ b/src/casedev/types/connectors/v1/installations/vault_grant_params.py
@@ -0,0 +1,21 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, Required, TypedDict
+
+__all__ = ["VaultGrantParams"]
+
+
+class VaultGrantParams(TypedDict, total=False):
+ id: Required[str]
+
+ can_manage: bool
+
+ can_read: bool
+
+ can_write: bool
+
+ relationship: Literal["owned", "shared"]
+
+ source: Literal["provisioning", "lazy_reconcile", "explicit_share"]
diff --git a/src/casedev/types/connectors/v1/link_delete_params.py b/src/casedev/types/connectors/v1/link_delete_params.py
new file mode 100644
index 00000000..d8261f30
--- /dev/null
+++ b/src/casedev/types/connectors/v1/link_delete_params.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, TypedDict
+
+__all__ = ["LinkDeleteParams"]
+
+
+class LinkDeleteParams(TypedDict, total=False):
+ vault_docs: Literal["keep", "delete"]
diff --git a/src/casedev/types/connectors/v1/link_list_objects_params.py b/src/casedev/types/connectors/v1/link_list_objects_params.py
new file mode 100644
index 00000000..fac7dcde
--- /dev/null
+++ b/src/casedev/types/connectors/v1/link_list_objects_params.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, TypedDict
+
+__all__ = ["LinkListObjectsParams"]
+
+
+class LinkListObjectsParams(TypedDict, total=False):
+ cursor: str
+
+ state: Literal["pending", "transferring", "ingesting", "synced", "skipped", "failed", "tombstoned"]
diff --git a/src/casedev/types/connectors/v1/link_list_params.py b/src/casedev/types/connectors/v1/link_list_params.py
new file mode 100644
index 00000000..2e82a4ff
--- /dev/null
+++ b/src/casedev/types/connectors/v1/link_list_params.py
@@ -0,0 +1,21 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, TypedDict
+
+__all__ = ["LinkListParams"]
+
+
+class LinkListParams(TypedDict, total=False):
+ connection_id: str
+
+ direction: Literal["import", "export"]
+
+ mode: Literal["once", "synced"]
+
+ pair_id: str
+
+ state: Literal["ready", "running", "active", "paused", "orphaned", "error"]
+
+ vault_id: str
diff --git a/src/casedev/types/connectors/v1/link_update_params.py b/src/casedev/types/connectors/v1/link_update_params.py
new file mode 100644
index 00000000..4221a094
--- /dev/null
+++ b/src/casedev/types/connectors/v1/link_update_params.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, TypedDict
+
+__all__ = ["LinkUpdateParams"]
+
+
+class LinkUpdateParams(TypedDict, total=False):
+ mode: Literal["once", "synced"]
+
+ policy: object
+
+ state: Literal["paused", "ready"]
diff --git a/src/casedev/types/connectors/v1_sync_link_params.py b/src/casedev/types/connectors/v1_sync_link_params.py
new file mode 100644
index 00000000..2e2bf0fd
--- /dev/null
+++ b/src/casedev/types/connectors/v1_sync_link_params.py
@@ -0,0 +1,48 @@
+# 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 Literal, Required, TypedDict
+
+from ..._types import SequenceNotStr
+
+__all__ = ["V1SyncLinkParams", "Remote", "Policy", "PolicyFilters"]
+
+
+class V1SyncLinkParams(TypedDict, total=False):
+ connection_id: Required[str]
+
+ direction: Required[Literal["import", "export"]]
+
+ remote: Required[Remote]
+
+ vault_id: Required[str]
+
+ matter_id: Optional[str]
+
+ policy: Policy
+
+
+class Remote(TypedDict, total=False):
+ folder_id: Required[str]
+
+ container_id: str
+
+ path: str
+
+ site_id: str
+
+
+class PolicyFilters(TypedDict, total=False):
+ exclude_mime: SequenceNotStr[str]
+
+ max_size_bytes: int
+
+
+class Policy(TypedDict, total=False):
+ collisions: Literal["version", "overwrite", "skip"]
+
+ deletes: Literal["mirror", "preserve"]
+
+ filters: PolicyFilters
diff --git a/src/casedev/types/connectors/v1_sync_link_response.py b/src/casedev/types/connectors/v1_sync_link_response.py
new file mode 100644
index 00000000..fcf33cfb
--- /dev/null
+++ b/src/casedev/types/connectors/v1_sync_link_response.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+
+from ..._models import BaseModel
+
+__all__ = ["V1SyncLinkResponse"]
+
+
+class V1SyncLinkResponse(BaseModel):
+ links: Optional[List[object]] = None
diff --git a/src/casedev/types/connectors/v1_transfer_params.py b/src/casedev/types/connectors/v1_transfer_params.py
new file mode 100644
index 00000000..638e7f88
--- /dev/null
+++ b/src/casedev/types/connectors/v1_transfer_params.py
@@ -0,0 +1,50 @@
+# 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 Literal, Required, TypedDict
+
+from ..._types import SequenceNotStr
+
+__all__ = ["V1TransferParams", "Remote", "Policy", "PolicyFilters"]
+
+
+class V1TransferParams(TypedDict, total=False):
+ connection_id: Required[str]
+
+ direction: Required[Literal["import", "export"]]
+
+ remote: Required[Remote]
+
+ vault_id: Required[str]
+
+ matter_id: Optional[str]
+
+ policy: Policy
+
+ run_mode: Literal["auto", "full_reconcile"]
+
+
+class Remote(TypedDict, total=False):
+ folder_id: Required[str]
+
+ container_id: str
+
+ path: str
+
+ site_id: str
+
+
+class PolicyFilters(TypedDict, total=False):
+ exclude_mime: SequenceNotStr[str]
+
+ max_size_bytes: int
+
+
+class Policy(TypedDict, total=False):
+ collisions: Literal["version", "overwrite", "skip"]
+
+ deletes: Literal["mirror", "preserve"]
+
+ filters: PolicyFilters
diff --git a/src/casedev/types/connectors/v1_transfer_response.py b/src/casedev/types/connectors/v1_transfer_response.py
new file mode 100644
index 00000000..c8fd8844
--- /dev/null
+++ b/src/casedev/types/connectors/v1_transfer_response.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+
+from ..._models import BaseModel
+
+__all__ = ["V1TransferResponse"]
+
+
+class V1TransferResponse(BaseModel):
+ links: Optional[List[object]] = None
diff --git a/src/casedev/types/database/__init__.py b/src/casedev/types/database/__init__.py
deleted file mode 100644
index 60ca5082..00000000
--- a/src/casedev/types/database/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from .v1_get_usage_response import V1GetUsageResponse as V1GetUsageResponse
diff --git a/src/casedev/types/database/v1/__init__.py b/src/casedev/types/database/v1/__init__.py
deleted file mode 100644
index 7281d0bc..00000000
--- a/src/casedev/types/database/v1/__init__.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from .project_create_params import ProjectCreateParams as ProjectCreateParams
-from .project_list_response import ProjectListResponse as ProjectListResponse
-from .project_create_response import ProjectCreateResponse as ProjectCreateResponse
-from .project_delete_response import ProjectDeleteResponse as ProjectDeleteResponse
-from .project_retrieve_response import ProjectRetrieveResponse as ProjectRetrieveResponse
-from .project_create_branch_params import ProjectCreateBranchParams as ProjectCreateBranchParams
-from .project_get_connection_params import ProjectGetConnectionParams as ProjectGetConnectionParams
-from .project_create_branch_response import ProjectCreateBranchResponse as ProjectCreateBranchResponse
-from .project_list_branches_response import ProjectListBranchesResponse as ProjectListBranchesResponse
-from .project_get_connection_response import ProjectGetConnectionResponse as ProjectGetConnectionResponse
diff --git a/src/casedev/types/database/v1/project_create_branch_params.py b/src/casedev/types/database/v1/project_create_branch_params.py
deleted file mode 100644
index 859540a7..00000000
--- a/src/casedev/types/database/v1/project_create_branch_params.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Required, Annotated, TypedDict
-
-from ...._utils import PropertyInfo
-
-__all__ = ["ProjectCreateBranchParams"]
-
-
-class ProjectCreateBranchParams(TypedDict, total=False):
- name: Required[str]
- """Branch name (letters, numbers, hyphens, underscores only)"""
-
- parent_branch_id: Annotated[str, PropertyInfo(alias="parentBranchId")]
- """Parent branch ID to clone from (defaults to main branch)"""
diff --git a/src/casedev/types/database/v1/project_create_branch_response.py b/src/casedev/types/database/v1/project_create_branch_response.py
deleted file mode 100644
index d05ea15c..00000000
--- a/src/casedev/types/database/v1/project_create_branch_response.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from datetime import datetime
-
-from pydantic import Field as FieldInfo
-
-from ...._models import BaseModel
-
-__all__ = ["ProjectCreateBranchResponse"]
-
-
-class ProjectCreateBranchResponse(BaseModel):
- id: str
- """Branch ID"""
-
- created_at: datetime = FieldInfo(alias="createdAt")
- """Branch creation timestamp"""
-
- is_default: bool = FieldInfo(alias="isDefault")
- """Whether this is the default branch (always false for new branches)"""
-
- name: str
- """Branch name"""
-
- parent_branch_id: Optional[str] = FieldInfo(alias="parentBranchId", default=None)
- """Parent branch ID"""
-
- status: str
- """Branch status"""
diff --git a/src/casedev/types/database/v1/project_create_params.py b/src/casedev/types/database/v1/project_create_params.py
deleted file mode 100644
index b713f720..00000000
--- a/src/casedev/types/database/v1/project_create_params.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal, Required, TypedDict
-
-__all__ = ["ProjectCreateParams"]
-
-
-class ProjectCreateParams(TypedDict, total=False):
- name: Required[str]
- """Project name (letters, numbers, hyphens, underscores only)"""
-
- description: str
- """Optional project description"""
-
- region: Literal[
- "aws-us-east-1",
- "aws-us-east-2",
- "aws-us-west-2",
- "aws-eu-central-1",
- "aws-eu-west-1",
- "aws-eu-west-2",
- "aws-ap-southeast-1",
- "aws-ap-southeast-2",
- ]
- """AWS region for database deployment"""
diff --git a/src/casedev/types/database/v1/project_create_response.py b/src/casedev/types/database/v1/project_create_response.py
deleted file mode 100644
index e2a04e93..00000000
--- a/src/casedev/types/database/v1/project_create_response.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from pydantic import Field as FieldInfo
-
-from ...._models import BaseModel
-
-__all__ = ["ProjectCreateResponse", "DefaultBranch"]
-
-
-class DefaultBranch(BaseModel):
- """Default 'main' branch details"""
-
- id: Optional[str] = None
- """Branch ID"""
-
- name: Optional[str] = None
- """Branch name"""
-
-
-class ProjectCreateResponse(BaseModel):
- id: str
- """Project ID"""
-
- created_at: datetime = FieldInfo(alias="createdAt")
- """Project creation timestamp"""
-
- default_branch: DefaultBranch = FieldInfo(alias="defaultBranch")
- """Default 'main' branch details"""
-
- name: str
- """Project name"""
-
- pg_version: int = FieldInfo(alias="pgVersion")
- """PostgreSQL major version"""
-
- region: str
- """AWS region"""
-
- status: Literal["active", "suspended", "deleted"]
- """Project status"""
-
- description: Optional[str] = None
- """Project description"""
diff --git a/src/casedev/types/database/v1/project_delete_response.py b/src/casedev/types/database/v1/project_delete_response.py
deleted file mode 100644
index 2b1640fa..00000000
--- a/src/casedev/types/database/v1/project_delete_response.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from ...._models import BaseModel
-
-__all__ = ["ProjectDeleteResponse"]
-
-
-class ProjectDeleteResponse(BaseModel):
- message: str
- """Confirmation message"""
-
- success: bool
- """Deletion success indicator"""
diff --git a/src/casedev/types/database/v1/project_get_connection_params.py b/src/casedev/types/database/v1/project_get_connection_params.py
deleted file mode 100644
index a4c7c895..00000000
--- a/src/casedev/types/database/v1/project_get_connection_params.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import TypedDict
-
-__all__ = ["ProjectGetConnectionParams"]
-
-
-class ProjectGetConnectionParams(TypedDict, total=False):
- branch: str
- """Branch name (defaults to 'main')"""
-
- pooled: bool
- """Use pooled connection (PgBouncer)"""
diff --git a/src/casedev/types/database/v1/project_get_connection_response.py b/src/casedev/types/database/v1/project_get_connection_response.py
deleted file mode 100644
index 1d0cbf20..00000000
--- a/src/casedev/types/database/v1/project_get_connection_response.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from pydantic import Field as FieldInfo
-
-from ...._models import BaseModel
-
-__all__ = ["ProjectGetConnectionResponse"]
-
-
-class ProjectGetConnectionResponse(BaseModel):
- branch: str
- """Branch name for this connection"""
-
- connection_uri: str = FieldInfo(alias="connectionUri")
- """PostgreSQL connection string (includes credentials)"""
-
- pooled: bool
- """Whether this is a pooled connection"""
diff --git a/src/casedev/types/database/v1/project_list_branches_response.py b/src/casedev/types/database/v1/project_list_branches_response.py
deleted file mode 100644
index 66c12778..00000000
--- a/src/casedev/types/database/v1/project_list_branches_response.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-
-from pydantic import Field as FieldInfo
-
-from ...._models import BaseModel
-
-__all__ = ["ProjectListBranchesResponse", "Branch"]
-
-
-class Branch(BaseModel):
- id: Optional[str] = None
- """Branch ID"""
-
- created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None)
- """Branch creation timestamp"""
-
- is_default: Optional[bool] = FieldInfo(alias="isDefault", default=None)
- """Whether this is the default branch"""
-
- name: Optional[str] = None
- """Branch name"""
-
- parent_branch_id: Optional[str] = FieldInfo(alias="parentBranchId", default=None)
- """Parent branch ID (null for default branch)"""
-
- status: Optional[str] = None
- """Branch status"""
-
- updated_at: Optional[datetime] = FieldInfo(alias="updatedAt", default=None)
- """Branch last update timestamp"""
-
-
-class ProjectListBranchesResponse(BaseModel):
- branches: List[Branch]
diff --git a/src/casedev/types/database/v1/project_list_response.py b/src/casedev/types/database/v1/project_list_response.py
deleted file mode 100644
index 18af984c..00000000
--- a/src/casedev/types/database/v1/project_list_response.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from pydantic import Field as FieldInfo
-
-from ...._models import BaseModel
-
-__all__ = ["ProjectListResponse", "Project", "ProjectLinkedDeployment"]
-
-
-class ProjectLinkedDeployment(BaseModel):
- id: Optional[str] = None
- """Deployment ID"""
-
- name: Optional[str] = None
- """Deployment name"""
-
- type: Optional[Literal["compute"]] = None
- """Type of deployment"""
-
- url: Optional[str] = None
- """Deployment URL"""
-
-
-class Project(BaseModel):
- id: Optional[str] = None
- """Project ID"""
-
- compute_time_seconds: Optional[float] = FieldInfo(alias="computeTimeSeconds", default=None)
- """Total compute time consumed in seconds"""
-
- created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None)
- """Project creation timestamp"""
-
- description: Optional[str] = None
- """Project description"""
-
- linked_deployments: Optional[List[ProjectLinkedDeployment]] = FieldInfo(alias="linkedDeployments", default=None)
- """Linked application deployments using this database"""
-
- name: Optional[str] = None
- """Project name"""
-
- pg_version: Optional[int] = FieldInfo(alias="pgVersion", default=None)
- """PostgreSQL major version"""
-
- region: Optional[str] = None
- """AWS region where database is deployed"""
-
- status: Optional[Literal["active", "suspended", "deleted"]] = None
- """Current project status"""
-
- storage_size_bytes: Optional[float] = FieldInfo(alias="storageSizeBytes", default=None)
- """Current storage usage in bytes"""
-
- updated_at: Optional[datetime] = FieldInfo(alias="updatedAt", default=None)
- """Project last update timestamp"""
-
-
-class ProjectListResponse(BaseModel):
- projects: List[Project]
diff --git a/src/casedev/types/database/v1/project_retrieve_response.py b/src/casedev/types/database/v1/project_retrieve_response.py
deleted file mode 100644
index 789cd9c0..00000000
--- a/src/casedev/types/database/v1/project_retrieve_response.py
+++ /dev/null
@@ -1,100 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from pydantic import Field as FieldInfo
-
-from ...._models import BaseModel
-
-__all__ = ["ProjectRetrieveResponse", "Branch", "Database", "LinkedDeployment"]
-
-
-class Branch(BaseModel):
- id: Optional[str] = None
- """Branch ID"""
-
- created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None)
- """Branch creation timestamp"""
-
- is_default: Optional[bool] = FieldInfo(alias="isDefault", default=None)
- """Whether this is the default branch"""
-
- name: Optional[str] = None
- """Branch name"""
-
- status: Optional[str] = None
- """Branch status"""
-
-
-class Database(BaseModel):
- id: Optional[str] = None
- """Database ID"""
-
- name: Optional[str] = None
- """Database name"""
-
- owner_name: Optional[str] = FieldInfo(alias="ownerName", default=None)
- """Database owner role name"""
-
-
-class LinkedDeployment(BaseModel):
- id: Optional[str] = None
- """Deployment ID"""
-
- env_var_name: Optional[str] = FieldInfo(alias="envVarName", default=None)
- """Environment variable name for connection string"""
-
- name: Optional[str] = None
- """Deployment name"""
-
- type: Optional[Literal["compute"]] = None
- """Deployment type"""
-
- url: Optional[str] = None
- """Deployment URL"""
-
-
-class ProjectRetrieveResponse(BaseModel):
- id: str
- """Project ID"""
-
- branches: List[Branch]
- """All branches in this project"""
-
- compute_time_seconds: float = FieldInfo(alias="computeTimeSeconds")
- """Total compute time consumed in seconds"""
-
- connection_host: str = FieldInfo(alias="connectionHost")
- """Database connection hostname (masked for security)"""
-
- created_at: datetime = FieldInfo(alias="createdAt")
- """Project creation timestamp"""
-
- databases: List[Database]
- """Databases in the default branch"""
-
- linked_deployments: List[LinkedDeployment] = FieldInfo(alias="linkedDeployments")
- """Linked deployments using this database"""
-
- name: str
- """Project name"""
-
- pg_version: int = FieldInfo(alias="pgVersion")
- """PostgreSQL major version"""
-
- region: str
- """AWS region"""
-
- status: Literal["active", "suspended", "deleted"]
- """Project status"""
-
- storage_size_bytes: float = FieldInfo(alias="storageSizeBytes")
- """Current storage usage in bytes"""
-
- updated_at: datetime = FieldInfo(alias="updatedAt")
- """Project last update timestamp"""
-
- description: Optional[str] = None
- """Project description"""
diff --git a/src/casedev/types/database/v1_get_usage_response.py b/src/casedev/types/database/v1_get_usage_response.py
deleted file mode 100644
index dc44fec6..00000000
--- a/src/casedev/types/database/v1_get_usage_response.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-
-from pydantic import Field as FieldInfo
-
-from ..._models import BaseModel
-
-__all__ = ["V1GetUsageResponse", "Period", "Pricing", "Project", "ProjectCosts", "Totals"]
-
-
-class Period(BaseModel):
- end: Optional[datetime] = None
- """End of the billing period"""
-
- start: Optional[datetime] = None
- """Start of the billing period"""
-
-
-class Pricing(BaseModel):
- """Current pricing rates"""
-
- branch_per_month: Optional[float] = FieldInfo(alias="branchPerMonth", default=None)
- """Cost per branch per month in dollars"""
-
- compute_per_cu_hour: Optional[float] = FieldInfo(alias="computePerCuHour", default=None)
- """Cost per compute unit hour in dollars"""
-
- free_branches: Optional[int] = FieldInfo(alias="freeBranches", default=None)
- """Number of free branches included"""
-
- storage_per_gb_month: Optional[float] = FieldInfo(alias="storagePerGbMonth", default=None)
- """Cost per GB of storage per month in dollars"""
-
- transfer_per_gb: Optional[float] = FieldInfo(alias="transferPerGb", default=None)
- """Cost per GB of data transfer in dollars"""
-
-
-class ProjectCosts(BaseModel):
- branches: Optional[str] = None
-
- compute: Optional[str] = None
-
- storage: Optional[str] = None
-
- total: Optional[str] = None
-
- transfer: Optional[str] = None
-
-
-class Project(BaseModel):
- id: Optional[str] = None
-
- branch_count: Optional[int] = FieldInfo(alias="branchCount", default=None)
-
- compute_cu_hours: Optional[float] = FieldInfo(alias="computeCuHours", default=None)
-
- costs: Optional[ProjectCosts] = None
-
- last_updated: Optional[datetime] = FieldInfo(alias="lastUpdated", default=None)
-
- project_id: Optional[str] = FieldInfo(alias="projectId", default=None)
-
- project_name: Optional[str] = FieldInfo(alias="projectName", default=None)
-
- storage_gb_months: Optional[float] = FieldInfo(alias="storageGbMonths", default=None)
-
- transfer_gb: Optional[float] = FieldInfo(alias="transferGb", default=None)
-
-
-class Totals(BaseModel):
- """Aggregated totals across all projects"""
-
- branch_cost_dollars: Optional[str] = FieldInfo(alias="branchCostDollars", default=None)
- """Total branch cost formatted as dollars"""
-
- compute_cost_dollars: Optional[str] = FieldInfo(alias="computeCostDollars", default=None)
- """Total compute cost formatted as dollars"""
-
- compute_cu_hours: Optional[float] = FieldInfo(alias="computeCuHours", default=None)
- """Total compute unit hours"""
-
- storage_cost_dollars: Optional[str] = FieldInfo(alias="storageCostDollars", default=None)
- """Total storage cost formatted as dollars"""
-
- storage_gb_months: Optional[float] = FieldInfo(alias="storageGbMonths", default=None)
- """Total storage in GB-months"""
-
- total_branches: Optional[int] = FieldInfo(alias="totalBranches", default=None)
- """Total number of branches"""
-
- total_cost_dollars: Optional[str] = FieldInfo(alias="totalCostDollars", default=None)
- """Total cost formatted as dollars"""
-
- transfer_cost_dollars: Optional[str] = FieldInfo(alias="transferCostDollars", default=None)
- """Total transfer cost formatted as dollars"""
-
- transfer_gb: Optional[float] = FieldInfo(alias="transferGb", default=None)
- """Total data transfer in GB"""
-
-
-class V1GetUsageResponse(BaseModel):
- period: Optional[Period] = None
-
- pricing: Optional[Pricing] = None
- """Current pricing rates"""
-
- project_count: Optional[int] = FieldInfo(alias="projectCount", default=None)
- """Total number of projects with usage"""
-
- projects: Optional[List[Project]] = None
- """Usage breakdown by project"""
-
- totals: Optional[Totals] = None
- """Aggregated totals across all projects"""
diff --git a/src/casedev/types/format/__init__.py b/src/casedev/types/format/__init__.py
deleted file mode 100644
index 287e51d3..00000000
--- a/src/casedev/types/format/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from .v1_create_document_params import V1CreateDocumentParams as V1CreateDocumentParams
diff --git a/src/casedev/types/format/v1/__init__.py b/src/casedev/types/format/v1/__init__.py
deleted file mode 100644
index 351ac658..00000000
--- a/src/casedev/types/format/v1/__init__.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from .template_list_params import TemplateListParams as TemplateListParams
-from .template_create_params import TemplateCreateParams as TemplateCreateParams
-from .template_list_response import TemplateListResponse as TemplateListResponse
-from .template_create_response import TemplateCreateResponse as TemplateCreateResponse
-from .template_retrieve_response import TemplateRetrieveResponse as TemplateRetrieveResponse
diff --git a/src/casedev/types/format/v1/template_create_params.py b/src/casedev/types/format/v1/template_create_params.py
deleted file mode 100644
index f8316608..00000000
--- a/src/casedev/types/format/v1/template_create_params.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal, Required, TypedDict
-
-from ...._types import SequenceNotStr
-
-__all__ = ["TemplateCreateParams"]
-
-
-class TemplateCreateParams(TypedDict, total=False):
- content: Required[str]
- """Template content with {{variable}} placeholders"""
-
- name: Required[str]
- """Template name"""
-
- type: Required[Literal["caption", "signature", "letterhead", "certificate", "footer", "custom"]]
- """Template type"""
-
- description: str
- """Template description"""
-
- styles: object
- """CSS styles for the template"""
-
- tags: SequenceNotStr[str]
- """Template tags for organization"""
-
- variables: SequenceNotStr[str]
- """Template variables (auto-detected if not provided)"""
diff --git a/src/casedev/types/format/v1/template_create_response.py b/src/casedev/types/format/v1/template_create_response.py
deleted file mode 100644
index ee7c7a6d..00000000
--- a/src/casedev/types/format/v1/template_create_response.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-
-from pydantic import Field as FieldInfo
-
-from ...._models import BaseModel
-
-__all__ = ["TemplateCreateResponse"]
-
-
-class TemplateCreateResponse(BaseModel):
- id: Optional[str] = None
- """Template ID"""
-
- created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None)
- """Creation timestamp"""
-
- name: Optional[str] = None
- """Template name"""
-
- type: Optional[str] = None
- """Template type"""
-
- variables: Optional[List[str]] = None
- """Detected template variables"""
diff --git a/src/casedev/types/format/v1/template_list_params.py b/src/casedev/types/format/v1/template_list_params.py
deleted file mode 100644
index a134cd7e..00000000
--- a/src/casedev/types/format/v1/template_list_params.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import TypedDict
-
-__all__ = ["TemplateListParams"]
-
-
-class TemplateListParams(TypedDict, total=False):
- type: str
- """Filter templates by type (e.g., contract, pleading, letter)"""
diff --git a/src/casedev/types/format/v1/template_list_response.py b/src/casedev/types/format/v1/template_list_response.py
deleted file mode 100644
index b5efddfc..00000000
--- a/src/casedev/types/format/v1/template_list_response.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-
-from pydantic import Field as FieldInfo
-
-from ...._models import BaseModel
-
-__all__ = ["TemplateListResponse", "Template"]
-
-
-class Template(BaseModel):
- id: Optional[str] = None
- """Unique template identifier"""
-
- created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None)
- """Template creation timestamp"""
-
- description: Optional[str] = None
- """Template description"""
-
- name: Optional[str] = None
- """Template name"""
-
- tags: Optional[List[object]] = None
- """Template tags for organization"""
-
- type: Optional[str] = None
- """Template type/category"""
-
- usage_count: Optional[int] = FieldInfo(alias="usageCount", default=None)
- """Number of times template has been used"""
-
- variables: Optional[List[object]] = None
- """Template variables for customization"""
-
-
-class TemplateListResponse(BaseModel):
- templates: Optional[List[Template]] = None
diff --git a/src/casedev/types/format/v1/template_retrieve_response.py b/src/casedev/types/format/v1/template_retrieve_response.py
deleted file mode 100644
index e51ca387..00000000
--- a/src/casedev/types/format/v1/template_retrieve_response.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from datetime import datetime
-
-from pydantic import Field as FieldInfo
-
-from ...._models import BaseModel
-
-__all__ = ["TemplateRetrieveResponse"]
-
-
-class TemplateRetrieveResponse(BaseModel):
- id: Optional[str] = None
- """Unique template identifier"""
-
- content: Optional[object] = None
- """Template formatting rules and structure"""
-
- created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None)
- """Template creation timestamp"""
-
- description: Optional[str] = None
- """Template description"""
-
- name: Optional[str] = None
- """Template name"""
-
- organization_id: Optional[str] = FieldInfo(alias="organizationId", default=None)
- """Organization ID that owns the template"""
-
- updated_at: Optional[datetime] = FieldInfo(alias="updatedAt", default=None)
- """Template last modification timestamp"""
diff --git a/src/casedev/types/format/v1_create_document_params.py b/src/casedev/types/format/v1_create_document_params.py
deleted file mode 100644
index 462456ab..00000000
--- a/src/casedev/types/format/v1_create_document_params.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Iterable
-from typing_extensions import Literal, Required, Annotated, TypedDict
-
-from ..._utils import PropertyInfo
-
-__all__ = ["V1CreateDocumentParams", "Options", "OptionsComponent"]
-
-
-class V1CreateDocumentParams(TypedDict, total=False):
- content: Required[str]
- """The source content to format"""
-
- output_format: Required[Literal["pdf", "docx", "html_preview"]]
- """Desired output format"""
-
- input_format: Literal["md", "json", "text"]
- """Format of the input content"""
-
- options: Options
- """
- Optional template composition and styling settings used during document
- generation
- """
-
-
-class OptionsComponent(TypedDict, total=False):
- content: str
- """Inline template content"""
-
- styles: object
- """Custom styling options"""
-
- template_id: Annotated[str, PropertyInfo(alias="templateId")]
- """ID of saved template component"""
-
- variables: object
- """Variables for template interpolation"""
-
-
-class Options(TypedDict, total=False):
- """
- Optional template composition and styling settings used during document generation
- """
-
- components: Iterable[OptionsComponent]
- """Template components with variables"""
diff --git a/src/casedev/types/legal/__init__.py b/src/casedev/types/legal/__init__.py
index 57bc1a81..e4b2d87b 100644
--- a/src/casedev/types/legal/__init__.py
+++ b/src/casedev/types/legal/__init__.py
@@ -4,11 +4,9 @@
from .docket_detail import DocketDetail as DocketDetail
from .v1_find_params import V1FindParams as V1FindParams
-from .v1_draft_params import V1DraftParams as V1DraftParams
from .v1_docket_params import V1DocketParams as V1DocketParams
from .v1_find_response import V1FindResponse as V1FindResponse
from .v1_verify_params import V1VerifyParams as V1VerifyParams
-from .v1_draft_response import V1DraftResponse as V1DraftResponse
from .v1_similar_params import V1SimilarParams as V1SimilarParams
from .v1_docket_response import V1DocketResponse as V1DocketResponse
from .v1_research_params import V1ResearchParams as V1ResearchParams
diff --git a/src/casedev/types/legal/v1_docket_params.py b/src/casedev/types/legal/v1_docket_params.py
index 523a7ee0..893ca6d3 100644
--- a/src/casedev/types/legal/v1_docket_params.py
+++ b/src/casedev/types/legal/v1_docket_params.py
@@ -54,7 +54,10 @@ class V1DocketParams(TypedDict, total=False):
"""
offset: int
- """Offset for search results or entry list"""
+ """
+ Offset for search results or entry list (maximum 200 when including lookup
+ entries)
+ """
query: str
"""Case name or party name search query (required for search)"""
diff --git a/src/casedev/types/legal/v1_draft_params.py b/src/casedev/types/legal/v1_draft_params.py
deleted file mode 100644
index 83711fbb..00000000
--- a/src/casedev/types/legal/v1_draft_params.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Optional
-from typing_extensions import Literal, Required, TypedDict
-
-from ..._types import SequenceNotStr
-
-__all__ = ["V1DraftParams", "Length"]
-
-
-class V1DraftParams(TypedDict, total=False):
- instructions: Required[str]
- """What to draft — the core task.
-
- E.g., "Motion to compel defendant to produce discovery responses"
- """
-
- vault_id: Required[str]
- """Vault ID where the final document will be uploaded"""
-
- citations: bool
- """Research and include legal citations"""
-
- format: Optional[str]
- """Court or jurisdiction formatting hint.
-
- Triggers a legal-skills search. E.g., "California Superior Court", "SDNY",
- "federal pleading"
- """
-
- length: Optional[Length]
- """Target document length"""
-
- model: Optional[str]
- """LLM model override. Defaults to anthropic/claude-sonnet-4.6"""
-
- object_ids: Optional[SequenceNotStr[str]]
- """Vault object IDs to use as source/reference documents"""
-
- output_name: Optional[str]
- """Filename for the output document. Auto-generated if omitted."""
-
- output_type: Literal["pdf", "docx", "xlsx", "pptx", "md"]
- """Output file format"""
-
- verified: bool
- """
- Verify all citations in a loop — re-run verification and repair bad citations
- until they pass
- """
-
-
-class Length(TypedDict, total=False):
- """Target document length"""
-
- target: float
- """Target value (e.g., 2000 words or 5 pages)"""
-
- unit: Literal["words", "pages"]
- """Whether the target length is measured in words or pages"""
diff --git a/src/casedev/types/legal/v1_draft_response.py b/src/casedev/types/legal/v1_draft_response.py
deleted file mode 100644
index b462f709..00000000
--- a/src/casedev/types/legal/v1_draft_response.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from typing_extensions import Literal
-
-from ..._models import BaseModel
-
-__all__ = ["V1DraftResponse"]
-
-
-class V1DraftResponse(BaseModel):
- agent_id: Optional[str] = None
- """Ephemeral agent ID"""
-
- message: Optional[str] = None
-
- run_id: Optional[str] = None
- """Run ID — poll /agent/v1/run/:id/status for progress"""
-
- status: Optional[Literal["running"]] = None
diff --git a/src/casedev/types/agent/__init__.py b/src/casedev/types/linc/__init__.py
similarity index 100%
rename from src/casedev/types/agent/__init__.py
rename to src/casedev/types/linc/__init__.py
diff --git a/src/casedev/types/linc/v1/__init__.py b/src/casedev/types/linc/v1/__init__.py
new file mode 100644
index 00000000..3629df9e
--- /dev/null
+++ b/src/casedev/types/linc/v1/__init__.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .session_cancel_params import SessionCancelParams as SessionCancelParams
+from .session_create_params import SessionCreateParams as SessionCreateParams
+from .session_send_rpc_params import SessionSendRpcParams as SessionSendRpcParams
+from .session_ingest_events_params import SessionIngestEventsParams as SessionIngestEventsParams
+from .session_retrieve_events_params import SessionRetrieveEventsParams as SessionRetrieveEventsParams
+from .session_retrieve_messages_params import SessionRetrieveMessagesParams as SessionRetrieveMessagesParams
diff --git a/src/casedev/types/linc/v1/session_cancel_params.py b/src/casedev/types/linc/v1/session_cancel_params.py
new file mode 100644
index 00000000..aea535a3
--- /dev/null
+++ b/src/casedev/types/linc/v1/session_cancel_params.py
@@ -0,0 +1,21 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Annotated, TypedDict
+
+from ...._utils import PropertyInfo
+
+__all__ = ["SessionCancelParams"]
+
+
+class SessionCancelParams(TypedDict, total=False):
+ clear_queue: Annotated[bool, PropertyInfo(alias="clearQueue")]
+ """
+ Also clear queued steering/follow-up messages so the abort leaves the agent
+ fully idle. Cleared texts are returned in the `response.data.clearedQueue` field
+ of the response body. Without it, messages still queued when the abort settles
+ are auto-continued as a new run. Runtimes older than the Linc release that
+ supports this flag ignore it: the abort still happens but the queue is left
+ untouched.
+ """
diff --git a/src/casedev/types/linc/v1/session_create_params.py b/src/casedev/types/linc/v1/session_create_params.py
new file mode 100644
index 00000000..2d58fd18
--- /dev/null
+++ b/src/casedev/types/linc/v1/session_create_params.py
@@ -0,0 +1,51 @@
+# 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 Literal, Annotated, TypedDict
+
+from ...._types import SequenceNotStr
+from ...._utils import PropertyInfo
+
+__all__ = ["SessionCreateParams"]
+
+
+class SessionCreateParams(TypedDict, total=False):
+ document_template_slugs: Annotated[Optional[SequenceNotStr[str]], PropertyInfo(alias="documentTemplateSlugs")]
+ """
+ Specific document template slugs to inject into the using-document-templates
+ skill.
+ """
+
+ idle_timeout_ms: Annotated[Optional[int], PropertyInfo(alias="idleTimeoutMs")]
+
+ include_document_templates: Annotated[Optional[bool], PropertyInfo(alias="includeDocumentTemplates")]
+ """
+ When true, inject all active org document templates into the
+ using-document-templates skill.
+ """
+
+ instructions: Optional[str]
+ """Privileged C3-only hidden app instructions to append to the sandbox AGENTS.md."""
+
+ model: Optional[str]
+
+ scoped_api_key: Annotated[Optional[str], PropertyInfo(alias="scopedApiKey")]
+ """Optional caller-provided scoped Case.dev API key for the runtime."""
+
+ service_tier: Annotated[Literal["default", "priority"], PropertyInfo(alias="serviceTier")]
+ """Processing tier for eligible OpenAI GPT models.
+
+ Priority provides lower latency at premium cost.
+ """
+
+ skill_slugs: Annotated[Optional[SequenceNotStr[str]], PropertyInfo(alias="skillSlugs")]
+ """
+ Skills API slugs to install into the runtime sandbox before the native session
+ starts.
+ """
+
+ title: str
+
+ vault_ids: Annotated[Optional[SequenceNotStr[str]], PropertyInfo(alias="vaultIds")]
diff --git a/src/casedev/types/linc/v1/session_ingest_events_params.py b/src/casedev/types/linc/v1/session_ingest_events_params.py
new file mode 100644
index 00000000..d2bcc9a4
--- /dev/null
+++ b/src/casedev/types/linc/v1/session_ingest_events_params.py
@@ -0,0 +1,24 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Dict, Iterable
+from typing_extensions import Required, TypedDict
+
+__all__ = ["SessionIngestEventsParams", "Frame"]
+
+
+class SessionIngestEventsParams(TypedDict, total=False):
+ frames: Required[Iterable[Frame]]
+ """Native Linc event frames to persist for replay."""
+
+
+class Frame(TypedDict, total=False):
+ event: Required[Dict[str, object]]
+ """Native Linc event payload."""
+
+ seq: Required[int]
+ """Monotonic native event sequence number."""
+
+ type: Required[str]
+ """Native Linc event type."""
diff --git a/src/casedev/types/linc/v1/session_retrieve_events_params.py b/src/casedev/types/linc/v1/session_retrieve_events_params.py
new file mode 100644
index 00000000..290bb90d
--- /dev/null
+++ b/src/casedev/types/linc/v1/session_retrieve_events_params.py
@@ -0,0 +1,24 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Annotated, TypedDict
+
+from ...._types import SequenceNotStr
+from ...._utils import PropertyInfo
+
+__all__ = ["SessionRetrieveEventsParams"]
+
+
+class SessionRetrieveEventsParams(TypedDict, total=False):
+ after_seq: Annotated[int, PropertyInfo(alias="afterSeq")]
+ """Alias for cursor. Ignored when cursor is also provided."""
+
+ cursor: int
+ """Replay events with a sequence number greater than this cursor."""
+
+ exclude_event_types: Annotated[SequenceNotStr[str], PropertyInfo(alias="excludeEventTypes")]
+ """Comma-separated Linc event types to omit from replay."""
+
+ limit: int
+ """Maximum number of events to return."""
diff --git a/src/casedev/types/linc/v1/session_retrieve_messages_params.py b/src/casedev/types/linc/v1/session_retrieve_messages_params.py
new file mode 100644
index 00000000..5135b75b
--- /dev/null
+++ b/src/casedev/types/linc/v1/session_retrieve_messages_params.py
@@ -0,0 +1,20 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Annotated, TypedDict
+
+from ...._utils import PropertyInfo
+
+__all__ = ["SessionRetrieveMessagesParams"]
+
+
+class SessionRetrieveMessagesParams(TypedDict, total=False):
+ after_seq: Annotated[int, PropertyInfo(alias="afterSeq")]
+ """Alias for cursor. Ignored when cursor is also provided."""
+
+ cursor: int
+ """Replay messages with a source event sequence number greater than this cursor."""
+
+ limit: int
+ """Maximum number of source events to scan for completed messages."""
diff --git a/src/casedev/types/linc/v1/session_send_rpc_params.py b/src/casedev/types/linc/v1/session_send_rpc_params.py
new file mode 100644
index 00000000..1abe5398
--- /dev/null
+++ b/src/casedev/types/linc/v1/session_send_rpc_params.py
@@ -0,0 +1,20 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, Annotated, TypedDict
+
+from ...._utils import PropertyInfo
+
+__all__ = ["SessionSendRpcParams"]
+
+
+class SessionSendRpcParams(TypedDict, total=False):
+ type: Required[str]
+ """Native Pi/Linc RPC command type.
+
+ Prompt commands also require a string id for idempotency.
+ """
+
+ body_id: Annotated[str, PropertyInfo(alias="id")]
+ """Command idempotency key. Required when type is prompt."""
diff --git a/src/casedev/types/llm/v1/chat_create_completion_params.py b/src/casedev/types/llm/v1/chat_create_completion_params.py
index ea53c526..47093d9a 100644
--- a/src/casedev/types/llm/v1/chat_create_completion_params.py
+++ b/src/casedev/types/llm/v1/chat_create_completion_params.py
@@ -13,9 +13,10 @@ class ChatCreateCompletionParams(TypedDict, total=False):
"""List of messages comprising the conversation"""
casemark_show_reasoning: bool
- """CaseMark-only: when true, allows reasoning fields in responses.
+ """CaseMark-only: controls whether reasoning fields appear in responses.
- Defaults to false (reasoning is suppressed).
+ Defaults to false (suppressed) for most CaseMark models; defaults to true for
+ casemark/core-potassium.
"""
frequency_penalty: float
diff --git a/src/casedev/types/mail/v1/__init__.py b/src/casedev/types/mail/v1/__init__.py
deleted file mode 100644
index edd97ad1..00000000
--- a/src/casedev/types/mail/v1/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from .inbox_create_params import InboxCreateParams as InboxCreateParams
-from .inbox_set_policy_params import InboxSetPolicyParams as InboxSetPolicyParams
diff --git a/src/casedev/types/mail/v1/inbox_create_params.py b/src/casedev/types/mail/v1/inbox_create_params.py
deleted file mode 100644
index 405bd5fa..00000000
--- a/src/casedev/types/mail/v1/inbox_create_params.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Annotated, TypedDict
-
-from ...._utils import PropertyInfo
-
-__all__ = ["InboxCreateParams"]
-
-
-class InboxCreateParams(TypedDict, total=False):
- address: str
-
- display_name: Annotated[str, PropertyInfo(alias="displayName")]
diff --git a/src/casedev/types/mail/v1/inbox_set_policy_params.py b/src/casedev/types/mail/v1/inbox_set_policy_params.py
deleted file mode 100644
index 743ad80a..00000000
--- a/src/casedev/types/mail/v1/inbox_set_policy_params.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Annotated, TypedDict
-
-from ...._types import SequenceNotStr
-from ...._utils import PropertyInfo
-
-__all__ = ["InboxSetPolicyParams"]
-
-
-class InboxSetPolicyParams(TypedDict, total=False):
- allowed_sender_patterns: Annotated[SequenceNotStr[str], PropertyInfo(alias="allowedSenderPatterns")]
- """Exact emails, @domain rules, or \\**"""
-
- enforce_sender_allowlist: Annotated[bool, PropertyInfo(alias="enforceSenderAllowlist")]
-
- read_access_rules: Annotated[SequenceNotStr[str], PropertyInfo(alias="readAccessRules")]
- """
- Rules like organization, operator, user:, api_key, api_key:,
- clerk_session, or \\**
- """
-
- reply_access_rules: Annotated[SequenceNotStr[str], PropertyInfo(alias="replyAccessRules")]
- """
- Rules like organization, operator, user:, api_key, api_key:,
- clerk_session, or \\**
- """
-
- send_access_rules: Annotated[SequenceNotStr[str], PropertyInfo(alias="sendAccessRules")]
- """Rules like organization, user:, api_key, api_key:, clerk_session, or \\**"""
diff --git a/src/casedev/types/matters/v1/work_item_decide_params.py b/src/casedev/types/matters/v1/work_item_decide_params.py
index 1f6e042f..dc78435b 100644
--- a/src/casedev/types/matters/v1/work_item_decide_params.py
+++ b/src/casedev/types/matters/v1/work_item_decide_params.py
@@ -11,9 +11,7 @@
class WorkItemDecideParams(TypedDict, total=False):
id: Required[str]
- decision: Required[Literal["approve", "revise", "block", "reassign"]]
-
- agent_type_id: Optional[str]
+ decision: Required[Literal["approve", "block"]]
metadata: Dict[str, object]
diff --git a/src/casedev/types/media/v1/transcripts/__init__.py b/src/casedev/types/media/v1/transcripts/__init__.py
index f8ee8b14..ad7efe60 100644
--- a/src/casedev/types/media/v1/transcripts/__init__.py
+++ b/src/casedev/types/media/v1/transcripts/__init__.py
@@ -1,3 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from __future__ import annotations
+
+from .retrieve_create_params import RetrieveCreateParams as RetrieveCreateParams
+from .retrieve_create_response import RetrieveCreateResponse as RetrieveCreateResponse
diff --git a/src/casedev/types/media/v1/transcripts/retrieve_create_params.py b/src/casedev/types/media/v1/transcripts/retrieve_create_params.py
new file mode 100644
index 00000000..3e31cb3b
--- /dev/null
+++ b/src/casedev/types/media/v1/transcripts/retrieve_create_params.py
@@ -0,0 +1,26 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["RetrieveCreateParams", "Transcript"]
+
+
+class RetrieveCreateParams(TypedDict, total=False):
+ object_id: Required[str]
+ """Object ID for either the source audio/video file or transcript artifact."""
+
+ vault_id: Required[str]
+ """Vault ID containing the source media or transcript object."""
+
+ transcript: Transcript
+ """Alternative nested transcript object reference."""
+
+
+class Transcript(TypedDict, total=False):
+ """Alternative nested transcript object reference."""
+
+ object_id: str
+
+ vault_id: str
diff --git a/src/casedev/types/media/v1/transcripts/retrieve_create_response.py b/src/casedev/types/media/v1/transcripts/retrieve_create_response.py
new file mode 100644
index 00000000..714f7c55
--- /dev/null
+++ b/src/casedev/types/media/v1/transcripts/retrieve_create_response.py
@@ -0,0 +1,37 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from typing_extensions import Literal
+
+from ....._models import BaseModel
+
+__all__ = ["RetrieveCreateResponse"]
+
+
+class RetrieveCreateResponse(BaseModel):
+ object_id: str
+ """Requested object ID."""
+
+ status: Literal["completed"]
+
+ text: str
+ """Full transcript text."""
+
+ vault_id: str
+
+ audio_duration: Optional[int] = None
+
+ confidence: Optional[int] = None
+
+ filename: Optional[str] = None
+
+ source_object_id: Optional[str] = None
+ """Source media object ID when known."""
+
+ transcript_object_id: Optional[str] = None
+ """Transcript object ID when known."""
+
+ transcription_job_id: Optional[str] = None
+ """Transcription job ID when known."""
+
+ word_count: Optional[int] = None
diff --git a/src/casedev/types/ocr/v1_process_params.py b/src/casedev/types/ocr/v1_process_params.py
index 7f6e99c4..f3f863eb 100644
--- a/src/casedev/types/ocr/v1_process_params.py
+++ b/src/casedev/types/ocr/v1_process_params.py
@@ -31,7 +31,11 @@ class V1ProcessParams(TypedDict, total=False):
"""S3 key prefix for results"""
-class FeaturesTables(TypedDict, total=False, extra_items=object): # type: ignore[call-arg]
+class FeaturesTables( # type: ignore[call-arg]
+ TypedDict,
+ total=False,
+ extra_items=object, # pyright: ignore[reportGeneralTypeIssues]
+):
"""Extract tables as structured data"""
format: Literal["csv", "json"]
diff --git a/src/casedev/types/ocr/v1_retrieve_params.py b/src/casedev/types/ocr/v1_retrieve_params.py
index 65ba0218..d5b674bf 100644
--- a/src/casedev/types/ocr/v1_retrieve_params.py
+++ b/src/casedev/types/ocr/v1_retrieve_params.py
@@ -9,4 +9,4 @@
class V1RetrieveParams(TypedDict, total=False):
include_text: Literal["true", "false"]
- """Include full OCR text in completed responses (default: true)"""
+ """Include full OCR text in completed responses (default: false)"""
diff --git a/src/casedev/types/ocr/v1_retrieve_response.py b/src/casedev/types/ocr/v1_retrieve_response.py
index a5a6ca8a..d7173544 100644
--- a/src/casedev/types/ocr/v1_retrieve_response.py
+++ b/src/casedev/types/ocr/v1_retrieve_response.py
@@ -29,4 +29,4 @@ class V1RetrieveResponse(BaseModel):
"""Number of pages processed"""
text: Optional[str] = None
- """Extracted text content (when completed)"""
+ """Extracted text content when completed and include_text=true"""
diff --git a/src/casedev/types/search/__init__.py b/src/casedev/types/search/__init__.py
index bd520293..5365d86e 100644
--- a/src/casedev/types/search/__init__.py
+++ b/src/casedev/types/search/__init__.py
@@ -7,10 +7,6 @@
from .v1_similar_params import V1SimilarParams as V1SimilarParams
from .v1_answer_response import V1AnswerResponse as V1AnswerResponse
from .v1_contents_params import V1ContentsParams as V1ContentsParams
-from .v1_research_params import V1ResearchParams as V1ResearchParams
from .v1_search_response import V1SearchResponse as V1SearchResponse
from .v1_similar_response import V1SimilarResponse as V1SimilarResponse
from .v1_contents_response import V1ContentsResponse as V1ContentsResponse
-from .v1_research_response import V1ResearchResponse as V1ResearchResponse
-from .v1_retrieve_research_params import V1RetrieveResearchParams as V1RetrieveResearchParams
-from .v1_retrieve_research_response import V1RetrieveResearchResponse as V1RetrieveResearchResponse
diff --git a/src/casedev/types/search/v1_research_params.py b/src/casedev/types/search/v1_research_params.py
deleted file mode 100644
index ea5924af..00000000
--- a/src/casedev/types/search/v1_research_params.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal, Required, Annotated, TypedDict
-
-from ..._utils import PropertyInfo
-
-__all__ = ["V1ResearchParams"]
-
-
-class V1ResearchParams(TypedDict, total=False):
- instructions: Required[str]
- """Research instructions or query"""
-
- model: Literal["fast", "normal", "pro"]
- """Research quality level - fast (quick), normal (balanced), pro (comprehensive)"""
-
- output_schema: Annotated[object, PropertyInfo(alias="outputSchema")]
- """Optional JSON schema to structure the research output"""
-
- query: str
- """Alias for instructions (for convenience)"""
diff --git a/src/casedev/types/search/v1_research_response.py b/src/casedev/types/search/v1_research_response.py
deleted file mode 100644
index db1b1259..00000000
--- a/src/casedev/types/search/v1_research_response.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-
-from pydantic import Field as FieldInfo
-
-from ..._models import BaseModel
-
-__all__ = ["V1ResearchResponse"]
-
-
-class V1ResearchResponse(BaseModel):
- model: Optional[str] = None
- """Model used for research"""
-
- research_id: Optional[str] = FieldInfo(alias="researchId", default=None)
- """Unique identifier for this research"""
-
- results: Optional[object] = None
- """Research findings and analysis"""
diff --git a/src/casedev/types/search/v1_retrieve_research_params.py b/src/casedev/types/search/v1_retrieve_research_params.py
deleted file mode 100644
index c62a5e1c..00000000
--- a/src/casedev/types/search/v1_retrieve_research_params.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import TypedDict
-
-__all__ = ["V1RetrieveResearchParams"]
-
-
-class V1RetrieveResearchParams(TypedDict, total=False):
- events: str
- """Filter specific event types for streaming"""
-
- stream: bool
- """Enable streaming for real-time updates"""
diff --git a/src/casedev/types/search/v1_retrieve_research_response.py b/src/casedev/types/search/v1_retrieve_research_response.py
deleted file mode 100644
index 2e05e7d6..00000000
--- a/src/casedev/types/search/v1_retrieve_research_response.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from pydantic import Field as FieldInfo
-
-from ..._models import BaseModel
-
-__all__ = ["V1RetrieveResearchResponse", "Results", "ResultsSection", "ResultsSectionSource", "ResultsSource"]
-
-
-class ResultsSectionSource(BaseModel):
- snippet: Optional[str] = None
-
- title: Optional[str] = None
-
- url: Optional[str] = None
-
-
-class ResultsSection(BaseModel):
- content: Optional[str] = None
-
- sources: Optional[List[ResultsSectionSource]] = None
-
- title: Optional[str] = None
-
-
-class ResultsSource(BaseModel):
- snippet: Optional[str] = None
-
- title: Optional[str] = None
-
- url: Optional[str] = None
-
-
-class Results(BaseModel):
- """Research findings and analysis"""
-
- sections: Optional[List[ResultsSection]] = None
- """Detailed research sections"""
-
- sources: Optional[List[ResultsSource]] = None
- """All sources referenced in research"""
-
- summary: Optional[str] = None
- """Executive summary of research findings"""
-
-
-class V1RetrieveResearchResponse(BaseModel):
- id: Optional[str] = None
- """Research task ID"""
-
- completed_at: Optional[datetime] = FieldInfo(alias="completedAt", default=None)
- """Task completion timestamp"""
-
- created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None)
- """Task creation timestamp"""
-
- model: Optional[Literal["fast", "normal", "pro"]] = None
- """Research model used"""
-
- progress: Optional[float] = None
- """Completion percentage (0-100)"""
-
- query: Optional[str] = None
- """Original research query"""
-
- results: Optional[Results] = None
- """Research findings and analysis"""
-
- status: Optional[Literal["pending", "running", "completed", "failed"]] = None
- """Current status of the research task"""
diff --git a/src/casedev/types/superdoc/__init__.py b/src/casedev/types/superdoc/__init__.py
deleted file mode 100644
index 111238a8..00000000
--- a/src/casedev/types/superdoc/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from .v1_convert_params import V1ConvertParams as V1ConvertParams
-from .v1_annotate_params import V1AnnotateParams as V1AnnotateParams
diff --git a/src/casedev/types/superdoc/v1_annotate_params.py b/src/casedev/types/superdoc/v1_annotate_params.py
deleted file mode 100644
index fc0321ba..00000000
--- a/src/casedev/types/superdoc/v1_annotate_params.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Union, Iterable
-from typing_extensions import Literal, Required, TypedDict
-
-__all__ = ["V1AnnotateParams", "Document", "Field", "FieldOptions"]
-
-
-class V1AnnotateParams(TypedDict, total=False):
- document: Required[Document]
- """Document source - provide either URL or base64"""
-
- fields: Required[Iterable[Field]]
- """Fields to populate in the template"""
-
- output_format: Literal["docx", "pdf"]
- """Output format for the annotated document"""
-
-
-class Document(TypedDict, total=False):
- """Document source - provide either URL or base64"""
-
- base64: str
- """Base64-encoded DOCX template"""
-
- url: str
- """URL to the DOCX template"""
-
-
-class FieldOptions(TypedDict, total=False):
- """Optional configuration (e.g., image dimensions)"""
-
- height: float
- """Image height in pixels"""
-
- width: float
- """Image width in pixels"""
-
-
-class Field(TypedDict, total=False):
- type: Required[Literal["text", "image", "date", "number"]]
- """Field data type"""
-
- value: Required[Union[str, float]]
- """Value to populate"""
-
- id: str
- """Target field ID (for single field)"""
-
- group: str
- """Target field group (for multiple fields with same tag)"""
-
- options: FieldOptions
- """Optional configuration (e.g., image dimensions)"""
diff --git a/src/casedev/types/superdoc/v1_convert_params.py b/src/casedev/types/superdoc/v1_convert_params.py
deleted file mode 100644
index 7e1513fb..00000000
--- a/src/casedev/types/superdoc/v1_convert_params.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal, Required, Annotated, TypedDict
-
-from ..._utils import PropertyInfo
-
-__all__ = ["V1ConvertParams"]
-
-
-class V1ConvertParams(TypedDict, total=False):
- from_: Required[Annotated[Literal["docx", "md", "html"], PropertyInfo(alias="from")]]
- """Source format of the document"""
-
- document_base64: str
- """Base64-encoded document content"""
-
- document_url: str
- """URL to the document to convert"""
-
- to: Literal["pdf", "docx"]
- """Target format for conversion"""
diff --git a/src/casedev/types/translate/__init__.py b/src/casedev/types/translate/__init__.py
index 8df52194..28cf9f11 100644
--- a/src/casedev/types/translate/__init__.py
+++ b/src/casedev/types/translate/__init__.py
@@ -8,3 +8,4 @@
from .v1_translate_response import V1TranslateResponse as V1TranslateResponse
from .v1_list_languages_params import V1ListLanguagesParams as V1ListLanguagesParams
from .v1_list_languages_response import V1ListLanguagesResponse as V1ListLanguagesResponse
+from .v1_translate_document_params import V1TranslateDocumentParams as V1TranslateDocumentParams
diff --git a/src/casedev/types/translate/v1_translate_document_params.py b/src/casedev/types/translate/v1_translate_document_params.py
new file mode 100644
index 00000000..64abe2d2
--- /dev/null
+++ b/src/casedev/types/translate/v1_translate_document_params.py
@@ -0,0 +1,20 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+from ..._types import FileTypes
+
+__all__ = ["V1TranslateDocumentParams"]
+
+
+class V1TranslateDocumentParams(TypedDict, total=False):
+ file: Required[FileTypes]
+ """TXT, DOCX, or searchable PDF document (max 20MB)"""
+
+ target: Required[str]
+ """Target BCP-47 language code"""
+
+ source: str
+ """Optional source BCP-47 language code. Auto-detected when omitted."""
diff --git a/src/casedev/types/usage/v1_retrieve_params.py b/src/casedev/types/usage/v1_retrieve_params.py
index bc0d74d9..26aae1a3 100644
--- a/src/casedev/types/usage/v1_retrieve_params.py
+++ b/src/casedev/types/usage/v1_retrieve_params.py
@@ -15,6 +15,18 @@ class V1RetrieveParams(TypedDict, total=False):
granularity: Literal["summary", "daily"]
"""Whether to return period totals only or include daily buckets."""
+ group_by: Annotated[Literal["lincSessionId"], PropertyInfo(alias="groupBy")]
+ """Optionally include usage groups keyed by native Linc session id.
+
+ Only Linc-session-attributable usage is grouped.
+ """
+
+ linc_session_id: Annotated[str, PropertyInfo(alias="lincSessionId")]
+ """Restrict usage to a native Linc session.
+
+ The session must belong to the authenticated organization.
+ """
+
period_end: Annotated[Union[str, datetime], PropertyInfo(alias="periodEnd", format="iso8601")]
"""Period end date. Defaults to now."""
diff --git a/src/casedev/types/vault/__init__.py b/src/casedev/types/vault/__init__.py
index 04f8aead..702284d9 100644
--- a/src/casedev/types/vault/__init__.py
+++ b/src/casedev/types/vault/__init__.py
@@ -2,33 +2,37 @@
from __future__ import annotations
+from .object_list_params import ObjectListParams as ObjectListParams
from .group_create_params import GroupCreateParams as GroupCreateParams
from .group_update_params import GroupUpdateParams as GroupUpdateParams
+from .object_merge_params import ObjectMergeParams as ObjectMergeParams
from .memory_create_params import MemoryCreateParams as MemoryCreateParams
from .memory_list_response import MemoryListResponse as MemoryListResponse
from .memory_search_params import MemorySearchParams as MemorySearchParams
from .memory_update_params import MemoryUpdateParams as MemoryUpdateParams
+from .object_append_params import ObjectAppendParams as ObjectAppendParams
from .object_delete_params import ObjectDeleteParams as ObjectDeleteParams
from .object_list_response import ObjectListResponse as ObjectListResponse
from .object_update_params import ObjectUpdateParams as ObjectUpdateParams
-from .graphrag_init_response import GraphragInitResponse as GraphragInitResponse
+from .multipart_init_params import MultipartInitParams as MultipartInitParams
+from .object_merge_response import ObjectMergeResponse as ObjectMergeResponse
from .memory_create_response import MemoryCreateResponse as MemoryCreateResponse
from .memory_search_response import MemorySearchResponse as MemorySearchResponse
from .multipart_abort_params import MultipartAbortParams as MultipartAbortParams
+from .object_append_response import ObjectAppendResponse as ObjectAppendResponse
from .object_delete_response import ObjectDeleteResponse as ObjectDeleteResponse
from .object_update_response import ObjectUpdateResponse as ObjectUpdateResponse
+from .multipart_init_response import MultipartInitResponse as MultipartInitResponse
from .object_get_pages_params import ObjectGetPagesParams as ObjectGetPagesParams
from .object_get_chunks_params import ObjectGetChunksParams as ObjectGetChunksParams
from .object_get_text_response import ObjectGetTextResponse as ObjectGetTextResponse
from .object_retrieve_response import ObjectRetrieveResponse as ObjectRetrieveResponse
+from .multipart_complete_params import MultipartCompleteParams as MultipartCompleteParams
from .object_get_pages_response import ObjectGetPagesResponse as ObjectGetPagesResponse
from .object_get_chunks_response import ObjectGetChunksResponse as ObjectGetChunksResponse
-from .graphrag_get_stats_response import GraphragGetStatsResponse as GraphragGetStatsResponse
from .object_get_ocr_words_params import ObjectGetOcrWordsParams as ObjectGetOcrWordsParams
from .object_get_ocr_words_response import ObjectGetOcrWordsResponse as ObjectGetOcrWordsResponse
from .multipart_get_part_urls_params import MultipartGetPartURLsParams as MultipartGetPartURLsParams
-from .graphrag_process_object_response import GraphragProcessObjectResponse as GraphragProcessObjectResponse
from .multipart_get_part_urls_response import MultipartGetPartURLsResponse as MultipartGetPartURLsResponse
-from .object_get_summarize_job_response import ObjectGetSummarizeJobResponse as ObjectGetSummarizeJobResponse
from .object_create_presigned_url_params import ObjectCreatePresignedURLParams as ObjectCreatePresignedURLParams
from .object_create_presigned_url_response import ObjectCreatePresignedURLResponse as ObjectCreatePresignedURLResponse
diff --git a/src/casedev/types/vault/graphrag_get_stats_response.py b/src/casedev/types/vault/graphrag_get_stats_response.py
deleted file mode 100644
index f390b944..00000000
--- a/src/casedev/types/vault/graphrag_get_stats_response.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from pydantic import Field as FieldInfo
-
-from ..._models import BaseModel
-
-__all__ = ["GraphragGetStatsResponse"]
-
-
-class GraphragGetStatsResponse(BaseModel):
- communities: Optional[int] = None
- """Number of entity communities identified"""
-
- documents: Optional[int] = None
- """Number of processed documents"""
-
- entities: Optional[int] = None
- """Total number of entities extracted from documents"""
-
- last_processed: Optional[datetime] = FieldInfo(alias="lastProcessed", default=None)
- """Timestamp of last GraphRAG processing"""
-
- relationships: Optional[int] = None
- """Total number of relationships between entities"""
-
- status: Optional[Literal["processing", "completed", "error"]] = None
- """Current processing status"""
diff --git a/src/casedev/types/vault/graphrag_init_response.py b/src/casedev/types/vault/graphrag_init_response.py
deleted file mode 100644
index ef489299..00000000
--- a/src/casedev/types/vault/graphrag_init_response.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-
-from ..._models import BaseModel
-
-__all__ = ["GraphragInitResponse"]
-
-
-class GraphragInitResponse(BaseModel):
- message: Optional[str] = None
-
- status: Optional[str] = None
-
- success: Optional[bool] = None
-
- vault_id: Optional[str] = None
diff --git a/src/casedev/types/vault/graphrag_process_object_response.py b/src/casedev/types/vault/graphrag_process_object_response.py
deleted file mode 100644
index d15b21ff..00000000
--- a/src/casedev/types/vault/graphrag_process_object_response.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-
-from pydantic import Field as FieldInfo
-
-from ..._models import BaseModel
-
-__all__ = ["GraphragProcessObjectResponse", "Stats"]
-
-
-class Stats(BaseModel):
- """Extraction statistics"""
-
- community_count: Optional[int] = None
-
- entity_count: Optional[int] = None
-
- relationship_count: Optional[int] = None
-
-
-class GraphragProcessObjectResponse(BaseModel):
- communities: int
- """Number of communities detected"""
-
- entities: int
- """Number of entities extracted"""
-
- object_id: str = FieldInfo(alias="objectId")
- """ID of the indexed object"""
-
- relationships: int
- """Number of relationships extracted"""
-
- stats: Stats
- """Extraction statistics"""
-
- status: str
- """Status from GraphRAG service"""
-
- success: bool
- """Whether indexing completed successfully"""
-
- vault_id: str = FieldInfo(alias="vaultId")
- """ID of the vault"""
diff --git a/src/casedev/types/vault/multipart_complete_params.py b/src/casedev/types/vault/multipart_complete_params.py
new file mode 100644
index 00000000..a3ec147f
--- /dev/null
+++ b/src/casedev/types/vault/multipart_complete_params.py
@@ -0,0 +1,30 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable
+from typing_extensions import Required, Annotated, TypedDict
+
+from ..._utils import PropertyInfo
+
+__all__ = ["MultipartCompleteParams", "Part"]
+
+
+class MultipartCompleteParams(TypedDict, total=False):
+ object_id: Required[Annotated[str, PropertyInfo(alias="objectId")]]
+
+ parts: Required[Iterable[Part]]
+
+ size_bytes: Required[Annotated[int, PropertyInfo(alias="sizeBytes")]]
+ """File size in bytes (default max 16GB).
+
+ Configure via VAULT_MULTIPART_MAX_FILE_SIZE_BYTES.
+ """
+
+ upload_id: Required[Annotated[str, PropertyInfo(alias="uploadId")]]
+
+
+class Part(TypedDict, total=False):
+ etag: Required[str]
+
+ part_number: Required[Annotated[int, PropertyInfo(alias="partNumber")]]
diff --git a/src/casedev/types/vault/multipart_init_params.py b/src/casedev/types/vault/multipart_init_params.py
new file mode 100644
index 00000000..83dc21a6
--- /dev/null
+++ b/src/casedev/types/vault/multipart_init_params.py
@@ -0,0 +1,43 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, Annotated, TypedDict
+
+from ..._utils import PropertyInfo
+
+__all__ = ["MultipartInitParams"]
+
+
+class MultipartInitParams(TypedDict, total=False):
+ content_type: Required[Annotated[str, PropertyInfo(alias="contentType")]]
+ """MIME type of the file"""
+
+ filename: Required[str]
+ """Name of the file to upload"""
+
+ size_bytes: Required[Annotated[int, PropertyInfo(alias="sizeBytes")]]
+ """File size in bytes (required, default max 16GB).
+
+ Configure via VAULT_MULTIPART_MAX_FILE_SIZE_BYTES.
+ """
+
+ auto_index: bool
+ """Whether to automatically process and index the file for search"""
+
+ is_ai_generated: bool
+ """Marks the file as AI-generated work product (e.g.
+
+ uploaded by an agent) rather than a user-provided source document. Persisted on
+ the object and returned by object listings so clients can distinguish
+ provenance.
+ """
+
+ metadata: object
+ """Additional metadata to associate with the file"""
+
+ part_size_bytes: Annotated[int, PropertyInfo(alias="partSizeBytes")]
+ """Multipart part size in bytes (min 5MB, max 5GB). Defaults to 64MB."""
+
+ path: str
+ """Optional folder path for hierarchy preservation"""
diff --git a/src/casedev/types/vault/multipart_init_response.py b/src/casedev/types/vault/multipart_init_response.py
new file mode 100644
index 00000000..2ec7c9b6
--- /dev/null
+++ b/src/casedev/types/vault/multipart_init_response.py
@@ -0,0 +1,23 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from pydantic import Field as FieldInfo
+
+from ..._models import BaseModel
+
+__all__ = ["MultipartInitResponse"]
+
+
+class MultipartInitResponse(BaseModel):
+ next_step: Optional[str] = None
+
+ object_id: Optional[str] = FieldInfo(alias="objectId", default=None)
+
+ part_count: Optional[int] = FieldInfo(alias="partCount", default=None)
+
+ part_size_bytes: Optional[int] = FieldInfo(alias="partSizeBytes", default=None)
+
+ s3_key: Optional[str] = FieldInfo(alias="s3Key", default=None)
+
+ upload_id: Optional[str] = FieldInfo(alias="uploadId", default=None)
diff --git a/src/casedev/types/vault/object_append_params.py b/src/casedev/types/vault/object_append_params.py
new file mode 100644
index 00000000..5c0f8ac7
--- /dev/null
+++ b/src/casedev/types/vault/object_append_params.py
@@ -0,0 +1,61 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, Annotated, TypedDict
+
+from ..._types import SequenceNotStr
+from ..._utils import PropertyInfo
+
+__all__ = ["ObjectAppendParams", "Bates"]
+
+
+class ObjectAppendParams(TypedDict, total=False):
+ id: Required[str]
+
+ append_object_ids: Required[Annotated[SequenceNotStr[str], PropertyInfo(alias="appendObjectIds")]]
+ """Vault object IDs whose pages will be appended onto the target object, in order.
+
+ Must not include the target object itself.
+ """
+
+ back_links: Annotated[bool, PropertyInfo(alias="backLinks")]
+ """Adds back links on appended pages"""
+
+ back_links_text: Annotated[str, PropertyInfo(alias="backLinksText")]
+ """Label text for the back link.
+
+ Used only when backLinks is true and rendered centered at the bottom of each
+ appended page.
+ """
+
+ bates: Bates
+ """Optional Bates stamping for appended source PDFs.
+
+ Numbering is deterministic across appendObjectIds order and does not stamp the
+ target report pages.
+ """
+
+ rewrite_links: Annotated[bool, PropertyInfo(alias="rewriteLinks")]
+ """
+ When true, rewrites links in the target object to internal PDF jumps when the
+ URL contains exactly one appended object ID as a standalone query parameter
+ value or decoded path segment.
+ """
+
+
+class Bates(TypedDict, total=False):
+ """Optional Bates stamping for appended source PDFs.
+
+ Numbering is deterministic across appendObjectIds order and does not stamp the target report pages.
+ """
+
+ enabled: bool
+
+ pad_to: Annotated[int, PropertyInfo(alias="padTo")]
+
+ prefix: str
+
+ start: int
+
+ suffix: str
diff --git a/src/casedev/types/vault/object_append_response.py b/src/casedev/types/vault/object_append_response.py
new file mode 100644
index 00000000..a9fdf9ff
--- /dev/null
+++ b/src/casedev/types/vault/object_append_response.py
@@ -0,0 +1,40 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from datetime import datetime
+
+from pydantic import Field as FieldInfo
+
+from ..._models import BaseModel
+
+__all__ = ["ObjectAppendResponse"]
+
+
+class ObjectAppendResponse(BaseModel):
+ id: Optional[str] = None
+
+ bates: Optional[object] = None
+
+ checksum: Optional[str] = None
+
+ content_type: Optional[str] = FieldInfo(alias="contentType", default=None)
+
+ created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None)
+
+ download_url: Optional[str] = FieldInfo(alias="downloadUrl", default=None)
+
+ expires_in: Optional[int] = FieldInfo(alias="expiresIn", default=None)
+
+ filename: Optional[str] = None
+
+ ingestion_status: Optional[str] = FieldInfo(alias="ingestionStatus", default=None)
+
+ metadata: Optional[object] = None
+
+ object_id: Optional[str] = FieldInfo(alias="objectId", default=None)
+
+ page_count: Optional[int] = FieldInfo(alias="pageCount", default=None)
+
+ size_bytes: Optional[int] = FieldInfo(alias="sizeBytes", default=None)
+
+ vault_id: Optional[str] = FieldInfo(alias="vaultId", default=None)
diff --git a/src/casedev/types/vault/object_get_summarize_job_response.py b/src/casedev/types/vault/object_get_summarize_job_response.py
deleted file mode 100644
index d57770f9..00000000
--- a/src/casedev/types/vault/object_get_summarize_job_response.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from pydantic import Field as FieldInfo
-
-from ..._models import BaseModel
-
-__all__ = ["ObjectGetSummarizeJobResponse"]
-
-
-class ObjectGetSummarizeJobResponse(BaseModel):
- completed_at: Optional[datetime] = FieldInfo(alias="completedAt", default=None)
- """When the job completed"""
-
- created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None)
- """When the job was created"""
-
- error: Optional[str] = None
- """Error message (if failed)"""
-
- job_id: Optional[str] = FieldInfo(alias="jobId", default=None)
- """Case.dev job ID"""
-
- result_filename: Optional[str] = FieldInfo(alias="resultFilename", default=None)
- """Filename of the result document (if completed)"""
-
- result_object_id: Optional[str] = FieldInfo(alias="resultObjectId", default=None)
- """ID of the result document (if completed)"""
-
- source_object_id: Optional[str] = FieldInfo(alias="sourceObjectId", default=None)
- """ID of the source document"""
-
- status: Optional[Literal["pending", "processing", "completed", "failed"]] = None
- """Current job status"""
-
- workflow_type: Optional[str] = FieldInfo(alias="workflowType", default=None)
- """Type of workflow being executed"""
diff --git a/src/casedev/types/vault/object_list_params.py b/src/casedev/types/vault/object_list_params.py
new file mode 100644
index 00000000..76d13deb
--- /dev/null
+++ b/src/casedev/types/vault/object_list_params.py
@@ -0,0 +1,17 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Annotated, TypedDict
+
+from ..._utils import PropertyInfo
+
+__all__ = ["ObjectListParams"]
+
+
+class ObjectListParams(TypedDict, total=False):
+ include_unconfirmed: Annotated[bool, PropertyInfo(alias="includeUnconfirmed")]
+ """
+ Include placeholders for uploads that were never completed (awaiting_upload) or
+ were cancelled (aborted). Excluded by default.
+ """
diff --git a/src/casedev/types/vault/object_list_response.py b/src/casedev/types/vault/object_list_response.py
index c057ee51..8e350e94 100644
--- a/src/casedev/types/vault/object_list_response.py
+++ b/src/casedev/types/vault/object_list_response.py
@@ -41,6 +41,9 @@ class Object(BaseModel):
ingestion_workflow_id: Optional[str] = FieldInfo(alias="ingestionWorkflowId", default=None)
"""Durable workflow run ID for the active or last ingestion attempt"""
+ is_ai_generated: Optional[bool] = None
+ """Whether the file was marked as AI-generated work product at upload time"""
+
metadata: Optional[object] = None
"""Custom metadata associated with the document"""
diff --git a/src/casedev/types/vault/object_merge_params.py b/src/casedev/types/vault/object_merge_params.py
new file mode 100644
index 00000000..a0f3d6d9
--- /dev/null
+++ b/src/casedev/types/vault/object_merge_params.py
@@ -0,0 +1,36 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, Required, Annotated, TypedDict
+
+from ..._types import SequenceNotStr
+from ..._utils import PropertyInfo
+
+__all__ = ["ObjectMergeParams", "Bates"]
+
+
+class ObjectMergeParams(TypedDict, total=False):
+ filename: Required[str]
+ """Output PDF filename"""
+
+ source_object_ids: Required[Annotated[SequenceNotStr[str], PropertyInfo(alias="sourceObjectIds")]]
+ """Source object IDs in output order"""
+
+ source_rendition: Required[Annotated[Literal["original", "searchable_pdf"], PropertyInfo(alias="sourceRendition")]]
+
+ idempotency_key: Required[Annotated[str, PropertyInfo(alias="Idempotency-Key")]]
+
+ bates: Bates
+
+ client_reference: Annotated[str, PropertyInfo(alias="clientReference")]
+
+
+class Bates(TypedDict, total=False):
+ pad_to: Annotated[int, PropertyInfo(alias="padTo")]
+
+ prefix: str
+
+ start: int
+
+ suffix: str
diff --git a/src/casedev/types/vault/object_merge_response.py b/src/casedev/types/vault/object_merge_response.py
new file mode 100644
index 00000000..65704223
--- /dev/null
+++ b/src/casedev/types/vault/object_merge_response.py
@@ -0,0 +1,20 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from typing_extensions import Literal
+
+from pydantic import Field as FieldInfo
+
+from ..._models import BaseModel
+
+__all__ = ["ObjectMergeResponse"]
+
+
+class ObjectMergeResponse(BaseModel):
+ client_reference: Optional[str] = FieldInfo(alias="clientReference", default=None)
+
+ object_id: Optional[str] = FieldInfo(alias="objectId", default=None)
+
+ status: Optional[Literal["processing"]] = None
+
+ workflow_id: Optional[str] = FieldInfo(alias="workflowId", default=None)
diff --git a/src/casedev/types/vault/object_retrieve_response.py b/src/casedev/types/vault/object_retrieve_response.py
index 72eeccc8..df9be6bf 100644
--- a/src/casedev/types/vault/object_retrieve_response.py
+++ b/src/casedev/types/vault/object_retrieve_response.py
@@ -41,6 +41,9 @@ class ObjectRetrieveResponse(BaseModel):
ingestion_error: Optional[str] = FieldInfo(alias="ingestionError", default=None)
"""Error details when ingestion fails"""
+ is_ai_generated: Optional[bool] = None
+ """Whether the file was marked as AI-generated work product at upload time"""
+
metadata: Optional[object] = None
"""Additional metadata"""
diff --git a/src/casedev/types/vault_confirm_upload_params.py b/src/casedev/types/vault_confirm_upload_params.py
index f71b18a5..9d684c4e 100644
--- a/src/casedev/types/vault_confirm_upload_params.py
+++ b/src/casedev/types/vault_confirm_upload_params.py
@@ -2,38 +2,38 @@
from __future__ import annotations
-from typing import Union
-from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict
+from typing_extensions import Required, Annotated, TypedDict
from .._utils import PropertyInfo
-__all__ = ["VaultConfirmUploadParams", "VaultConfirmUploadSuccess", "VaultConfirmUploadFailure"]
+__all__ = ["VaultConfirmUploadParams"]
-class VaultConfirmUploadSuccess(TypedDict, total=False):
+class VaultConfirmUploadParams(TypedDict, total=False):
id: Required[str]
- size_bytes: Required[Annotated[int, PropertyInfo(alias="sizeBytes")]]
- """Uploaded file size in bytes"""
-
- success: Required[Literal[True]]
+ success: Required[bool]
"""Whether the upload succeeded"""
- etag: str
- """S3 ETag for the uploaded object (optional if client cannot access ETag header)"""
-
+ auto_ingest: Annotated[bool, PropertyInfo(alias="autoIngest")]
+ """
+ When true and the object was uploaded with auto_index, trigger ingestion
+ immediately after a successful confirmation (no separate ingest call needed).
+ The ingest outcome is reported in the `ingest` response field; an ingest failure
+ does not fail the confirmation.
+ """
-class VaultConfirmUploadFailure(TypedDict, total=False):
- id: Required[str]
+ error_code: Annotated[str, PropertyInfo(alias="errorCode")]
+ """Client-side error code. Required when success=false."""
- error_code: Required[Annotated[str, PropertyInfo(alias="errorCode")]]
- """Client-side error code"""
+ error_message: Annotated[str, PropertyInfo(alias="errorMessage")]
+ """Client-side error message. Required when success=false."""
- error_message: Required[Annotated[str, PropertyInfo(alias="errorMessage")]]
- """Client-side error message"""
-
- success: Required[Literal[False]]
- """Whether the upload succeeded"""
+ etag: str
+ """S3 ETag for the uploaded object (optional if client cannot access ETag header).
+ Only meaningful when success=true.
+ """
-VaultConfirmUploadParams: TypeAlias = Union[VaultConfirmUploadSuccess, VaultConfirmUploadFailure]
+ size_bytes: Annotated[int, PropertyInfo(alias="sizeBytes")]
+ """Uploaded file size in bytes. Required when success=true."""
diff --git a/src/casedev/types/vault_confirm_upload_response.py b/src/casedev/types/vault_confirm_upload_response.py
index 697110ca..0c790222 100644
--- a/src/casedev/types/vault_confirm_upload_response.py
+++ b/src/casedev/types/vault_confirm_upload_response.py
@@ -7,12 +7,25 @@
from .._models import BaseModel
-__all__ = ["VaultConfirmUploadResponse"]
+__all__ = ["VaultConfirmUploadResponse", "Ingest"]
+
+
+class Ingest(BaseModel):
+ """Present when autoIngest was requested on a successful confirmation"""
+
+ error: Optional[str] = None
+
+ triggered: Optional[bool] = None
+
+ workflow_id: Optional[str] = FieldInfo(alias="workflowId", default=None)
class VaultConfirmUploadResponse(BaseModel):
already_confirmed: Optional[bool] = FieldInfo(alias="alreadyConfirmed", default=None)
+ ingest: Optional[Ingest] = None
+ """Present when autoIngest was requested on a successful confirmation"""
+
object_id: Optional[str] = FieldInfo(alias="objectId", default=None)
status: Optional[Literal["completed", "failed"]] = None
diff --git a/src/casedev/types/vault_ingest_response.py b/src/casedev/types/vault_ingest_response.py
index 454bf75c..0d3ffff8 100644
--- a/src/casedev/types/vault_ingest_response.py
+++ b/src/casedev/types/vault_ingest_response.py
@@ -12,10 +12,7 @@
class VaultIngestResponse(BaseModel):
enable_graph_rag: bool = FieldInfo(alias="enableGraphRAG")
- """
- Always false - GraphRAG must be triggered separately via POST
- /vault/:id/graphrag/:objectId
- """
+ """Always false; retained for response compatibility"""
message: str
"""Human-readable status message"""
diff --git a/src/casedev/types/vault_search_params.py b/src/casedev/types/vault_search_params.py
index 72c708e0..b3264eb3 100644
--- a/src/casedev/types/vault_search_params.py
+++ b/src/casedev/types/vault_search_params.py
@@ -31,7 +31,11 @@ class VaultSearchParams(TypedDict, total=False):
"""
-class Filters(TypedDict, total=False, extra_items=object): # type: ignore[call-arg]
+class Filters( # type: ignore[call-arg]
+ TypedDict,
+ total=False,
+ extra_items=object, # pyright: ignore[reportGeneralTypeIssues]
+):
"""Filters to narrow search results to specific documents"""
object_id: Union[str, SequenceNotStr[str]]
diff --git a/src/casedev/types/vault_upload_params.py b/src/casedev/types/vault_upload_params.py
index d3bcdcc1..af2e9f6e 100644
--- a/src/casedev/types/vault_upload_params.py
+++ b/src/casedev/types/vault_upload_params.py
@@ -19,6 +19,14 @@ class VaultUploadParams(TypedDict, total=False):
auto_index: bool
"""Whether to automatically process and index the file for search"""
+ is_ai_generated: bool
+ """Marks the file as AI-generated work product (e.g.
+
+ uploaded by an agent) rather than a user-provided source document. Persisted on
+ the object and returned by object listings so clients can distinguish
+ provenance.
+ """
+
metadata: object
"""Additional metadata to associate with the file"""
@@ -34,3 +42,5 @@ class VaultUploadParams(TypedDict, total=False):
When provided, enforces exact file size at S3 level.
"""
+
+ idempotency_key: Annotated[str, PropertyInfo(alias="Idempotency-Key")]
diff --git a/src/casedev/types/vault_upload_response.py b/src/casedev/types/vault_upload_response.py
index d4ae7fa1..6b97a741 100644
--- a/src/casedev/types/vault_upload_response.py
+++ b/src/casedev/types/vault_upload_response.py
@@ -18,6 +18,9 @@ class Instructions(BaseModel):
class VaultUploadResponse(BaseModel):
+ already_uploaded: Optional[bool] = FieldInfo(alias="alreadyUploaded", default=None)
+ """True when this idempotency key already identifies a confirmed upload"""
+
auto_index: Optional[bool] = None
"""Whether the file will be automatically indexed"""
@@ -29,6 +32,9 @@ class VaultUploadResponse(BaseModel):
instructions: Optional[Instructions] = None
+ is_ai_generated: Optional[bool] = None
+ """Whether the file is marked as AI-generated work product"""
+
next_step: Optional[str] = None
"""Next API endpoint to call for processing"""
diff --git a/src/casedev/types/voice/transcription_create_response.py b/src/casedev/types/voice/transcription_create_response.py
index 20fee025..2430b802 100644
--- a/src/casedev/types/voice/transcription_create_response.py
+++ b/src/casedev/types/voice/transcription_create_response.py
@@ -12,10 +12,16 @@ class TranscriptionCreateResponse(BaseModel):
id: Optional[str] = None
"""Unique transcription job ID"""
+ input_object_id: Optional[str] = None
+ """Object submitted to the speech provider.
+
+ For large videos, this is an internal audio derivative.
+ """
+
source_object_id: Optional[str] = None
- """Source audio object ID (only for vault-based transcription)"""
+ """Original source media object ID (only for vault-based transcription)"""
- status: Optional[Literal["queued", "processing", "completed", "error"]] = None
+ status: Optional[Literal["queued", "preprocessing", "processing", "completed", "error"]] = None
"""Current status of the transcription job"""
vault_id: Optional[str] = None
diff --git a/src/casedev/types/voice/transcription_retrieve_response.py b/src/casedev/types/voice/transcription_retrieve_response.py
index a50dc146..66ff4d4e 100644
--- a/src/casedev/types/voice/transcription_retrieve_response.py
+++ b/src/casedev/types/voice/transcription_retrieve_response.py
@@ -12,7 +12,7 @@ class TranscriptionRetrieveResponse(BaseModel):
id: str
"""Unique transcription job ID"""
- status: Literal["queued", "processing", "completed", "failed"]
+ status: Literal["queued", "preprocessing", "processing", "completed", "failed"]
"""Current status of the transcription job"""
audio_duration: Optional[float] = None
@@ -24,11 +24,17 @@ class TranscriptionRetrieveResponse(BaseModel):
error: Optional[str] = None
"""Error message (only present when status is failed)"""
+ input_object_id: Optional[str] = None
+ """Media object submitted to the speech provider.
+
+ May be an internal audio derivative for large videos.
+ """
+
result_object_id: Optional[str] = None
"""Result transcript object ID (vault-based jobs, when completed)"""
source_object_id: Optional[str] = None
- """Source audio object ID (vault-based jobs only)"""
+ """Original source media object ID (vault-based jobs only)"""
text: Optional[str] = None
"""
diff --git a/tests/api_resources/agent/v1/test_agents.py b/tests/api_resources/agent/v1/test_agents.py
deleted file mode 100644
index 91ce447a..00000000
--- a/tests/api_resources/agent/v1/test_agents.py
+++ /dev/null
@@ -1,460 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import pytest
-
-from casedev import Casedev, AsyncCasedev
-from tests.utils import assert_matches_type
-from casedev.types.agent.v1 import (
- AgentListResponse,
- AgentCreateResponse,
- AgentDeleteResponse,
- AgentUpdateResponse,
- AgentRetrieveResponse,
-)
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestAgents:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @parametrize
- def test_method_create(self, client: Casedev) -> None:
- agent = client.agent.v1.agents.create(
- instructions="instructions",
- name="name",
- )
- assert_matches_type(AgentCreateResponse, agent, path=["response"])
-
- @parametrize
- def test_method_create_with_all_params(self, client: Casedev) -> None:
- agent = client.agent.v1.agents.create(
- instructions="instructions",
- name="name",
- description="description",
- disabled_tools=["string"],
- enabled_tools=["string"],
- model="model",
- sandbox={
- "cpu": 0,
- "memory_mi_b": 0,
- },
- vault_groups=["string"],
- vault_ids=["string"],
- )
- assert_matches_type(AgentCreateResponse, agent, path=["response"])
-
- @parametrize
- def test_raw_response_create(self, client: Casedev) -> None:
- response = client.agent.v1.agents.with_raw_response.create(
- instructions="instructions",
- name="name",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- agent = response.parse()
- assert_matches_type(AgentCreateResponse, agent, path=["response"])
-
- @parametrize
- def test_streaming_response_create(self, client: Casedev) -> None:
- with client.agent.v1.agents.with_streaming_response.create(
- instructions="instructions",
- name="name",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- agent = response.parse()
- assert_matches_type(AgentCreateResponse, agent, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_method_retrieve(self, client: Casedev) -> None:
- agent = client.agent.v1.agents.retrieve(
- "id",
- )
- assert_matches_type(AgentRetrieveResponse, agent, path=["response"])
-
- @parametrize
- def test_raw_response_retrieve(self, client: Casedev) -> None:
- response = client.agent.v1.agents.with_raw_response.retrieve(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- agent = response.parse()
- assert_matches_type(AgentRetrieveResponse, agent, path=["response"])
-
- @parametrize
- def test_streaming_response_retrieve(self, client: Casedev) -> None:
- with client.agent.v1.agents.with_streaming_response.retrieve(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- agent = response.parse()
- assert_matches_type(AgentRetrieveResponse, agent, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_retrieve(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.agent.v1.agents.with_raw_response.retrieve(
- "",
- )
-
- @parametrize
- def test_method_update(self, client: Casedev) -> None:
- agent = client.agent.v1.agents.update(
- id="id",
- )
- assert_matches_type(AgentUpdateResponse, agent, path=["response"])
-
- @parametrize
- def test_method_update_with_all_params(self, client: Casedev) -> None:
- agent = client.agent.v1.agents.update(
- id="id",
- description="description",
- disabled_tools=["string"],
- enabled_tools=["string"],
- instructions="instructions",
- model="model",
- name="name",
- sandbox={},
- vault_groups=["string"],
- vault_ids=["string"],
- )
- assert_matches_type(AgentUpdateResponse, agent, path=["response"])
-
- @parametrize
- def test_raw_response_update(self, client: Casedev) -> None:
- response = client.agent.v1.agents.with_raw_response.update(
- id="id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- agent = response.parse()
- assert_matches_type(AgentUpdateResponse, agent, path=["response"])
-
- @parametrize
- def test_streaming_response_update(self, client: Casedev) -> None:
- with client.agent.v1.agents.with_streaming_response.update(
- id="id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- agent = response.parse()
- assert_matches_type(AgentUpdateResponse, agent, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_update(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.agent.v1.agents.with_raw_response.update(
- id="",
- )
-
- @parametrize
- def test_method_list(self, client: Casedev) -> None:
- agent = client.agent.v1.agents.list()
- assert_matches_type(AgentListResponse, agent, path=["response"])
-
- @parametrize
- def test_method_list_with_all_params(self, client: Casedev) -> None:
- agent = client.agent.v1.agents.list(
- cursor="cursor",
- limit=1,
- )
- assert_matches_type(AgentListResponse, agent, path=["response"])
-
- @parametrize
- def test_raw_response_list(self, client: Casedev) -> None:
- response = client.agent.v1.agents.with_raw_response.list()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- agent = response.parse()
- assert_matches_type(AgentListResponse, agent, path=["response"])
-
- @parametrize
- def test_streaming_response_list(self, client: Casedev) -> None:
- with client.agent.v1.agents.with_streaming_response.list() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- agent = response.parse()
- assert_matches_type(AgentListResponse, agent, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_method_delete(self, client: Casedev) -> None:
- agent = client.agent.v1.agents.delete(
- "id",
- )
- assert_matches_type(AgentDeleteResponse, agent, path=["response"])
-
- @parametrize
- def test_raw_response_delete(self, client: Casedev) -> None:
- response = client.agent.v1.agents.with_raw_response.delete(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- agent = response.parse()
- assert_matches_type(AgentDeleteResponse, agent, path=["response"])
-
- @parametrize
- def test_streaming_response_delete(self, client: Casedev) -> None:
- with client.agent.v1.agents.with_streaming_response.delete(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- agent = response.parse()
- assert_matches_type(AgentDeleteResponse, agent, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_delete(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.agent.v1.agents.with_raw_response.delete(
- "",
- )
-
-
-class TestAsyncAgents:
- parametrize = pytest.mark.parametrize(
- "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
- )
-
- @parametrize
- async def test_method_create(self, async_client: AsyncCasedev) -> None:
- agent = await async_client.agent.v1.agents.create(
- instructions="instructions",
- name="name",
- )
- assert_matches_type(AgentCreateResponse, agent, path=["response"])
-
- @parametrize
- async def test_method_create_with_all_params(self, async_client: AsyncCasedev) -> None:
- agent = await async_client.agent.v1.agents.create(
- instructions="instructions",
- name="name",
- description="description",
- disabled_tools=["string"],
- enabled_tools=["string"],
- model="model",
- sandbox={
- "cpu": 0,
- "memory_mi_b": 0,
- },
- vault_groups=["string"],
- vault_ids=["string"],
- )
- assert_matches_type(AgentCreateResponse, agent, path=["response"])
-
- @parametrize
- async def test_raw_response_create(self, async_client: AsyncCasedev) -> None:
- response = await async_client.agent.v1.agents.with_raw_response.create(
- instructions="instructions",
- name="name",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- agent = await response.parse()
- assert_matches_type(AgentCreateResponse, agent, path=["response"])
-
- @parametrize
- async def test_streaming_response_create(self, async_client: AsyncCasedev) -> None:
- async with async_client.agent.v1.agents.with_streaming_response.create(
- instructions="instructions",
- name="name",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- agent = await response.parse()
- assert_matches_type(AgentCreateResponse, agent, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_method_retrieve(self, async_client: AsyncCasedev) -> None:
- agent = await async_client.agent.v1.agents.retrieve(
- "id",
- )
- assert_matches_type(AgentRetrieveResponse, agent, path=["response"])
-
- @parametrize
- async def test_raw_response_retrieve(self, async_client: AsyncCasedev) -> None:
- response = await async_client.agent.v1.agents.with_raw_response.retrieve(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- agent = await response.parse()
- assert_matches_type(AgentRetrieveResponse, agent, path=["response"])
-
- @parametrize
- async def test_streaming_response_retrieve(self, async_client: AsyncCasedev) -> None:
- async with async_client.agent.v1.agents.with_streaming_response.retrieve(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- agent = await response.parse()
- assert_matches_type(AgentRetrieveResponse, agent, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_retrieve(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- await async_client.agent.v1.agents.with_raw_response.retrieve(
- "",
- )
-
- @parametrize
- async def test_method_update(self, async_client: AsyncCasedev) -> None:
- agent = await async_client.agent.v1.agents.update(
- id="id",
- )
- assert_matches_type(AgentUpdateResponse, agent, path=["response"])
-
- @parametrize
- async def test_method_update_with_all_params(self, async_client: AsyncCasedev) -> None:
- agent = await async_client.agent.v1.agents.update(
- id="id",
- description="description",
- disabled_tools=["string"],
- enabled_tools=["string"],
- instructions="instructions",
- model="model",
- name="name",
- sandbox={},
- vault_groups=["string"],
- vault_ids=["string"],
- )
- assert_matches_type(AgentUpdateResponse, agent, path=["response"])
-
- @parametrize
- async def test_raw_response_update(self, async_client: AsyncCasedev) -> None:
- response = await async_client.agent.v1.agents.with_raw_response.update(
- id="id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- agent = await response.parse()
- assert_matches_type(AgentUpdateResponse, agent, path=["response"])
-
- @parametrize
- async def test_streaming_response_update(self, async_client: AsyncCasedev) -> None:
- async with async_client.agent.v1.agents.with_streaming_response.update(
- id="id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- agent = await response.parse()
- assert_matches_type(AgentUpdateResponse, agent, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_update(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- await async_client.agent.v1.agents.with_raw_response.update(
- id="",
- )
-
- @parametrize
- async def test_method_list(self, async_client: AsyncCasedev) -> None:
- agent = await async_client.agent.v1.agents.list()
- assert_matches_type(AgentListResponse, agent, path=["response"])
-
- @parametrize
- async def test_method_list_with_all_params(self, async_client: AsyncCasedev) -> None:
- agent = await async_client.agent.v1.agents.list(
- cursor="cursor",
- limit=1,
- )
- assert_matches_type(AgentListResponse, agent, path=["response"])
-
- @parametrize
- async def test_raw_response_list(self, async_client: AsyncCasedev) -> None:
- response = await async_client.agent.v1.agents.with_raw_response.list()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- agent = await response.parse()
- assert_matches_type(AgentListResponse, agent, path=["response"])
-
- @parametrize
- async def test_streaming_response_list(self, async_client: AsyncCasedev) -> None:
- async with async_client.agent.v1.agents.with_streaming_response.list() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- agent = await response.parse()
- assert_matches_type(AgentListResponse, agent, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_method_delete(self, async_client: AsyncCasedev) -> None:
- agent = await async_client.agent.v1.agents.delete(
- "id",
- )
- assert_matches_type(AgentDeleteResponse, agent, path=["response"])
-
- @parametrize
- async def test_raw_response_delete(self, async_client: AsyncCasedev) -> None:
- response = await async_client.agent.v1.agents.with_raw_response.delete(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- agent = await response.parse()
- assert_matches_type(AgentDeleteResponse, agent, path=["response"])
-
- @parametrize
- async def test_streaming_response_delete(self, async_client: AsyncCasedev) -> None:
- async with async_client.agent.v1.agents.with_streaming_response.delete(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- agent = await response.parse()
- assert_matches_type(AgentDeleteResponse, agent, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_delete(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- await async_client.agent.v1.agents.with_raw_response.delete(
- "",
- )
diff --git a/tests/api_resources/agent/v1/test_execute.py b/tests/api_resources/agent/v1/test_execute.py
deleted file mode 100644
index 6a1e4370..00000000
--- a/tests/api_resources/agent/v1/test_execute.py
+++ /dev/null
@@ -1,122 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import pytest
-
-from casedev import Casedev, AsyncCasedev
-from tests.utils import assert_matches_type
-from casedev.types.agent.v1 import ExecuteCreateResponse
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestExecute:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @parametrize
- def test_method_create(self, client: Casedev) -> None:
- execute = client.agent.v1.execute.create(
- prompt="prompt",
- )
- assert_matches_type(ExecuteCreateResponse, execute, path=["response"])
-
- @parametrize
- def test_method_create_with_all_params(self, client: Casedev) -> None:
- execute = client.agent.v1.execute.create(
- prompt="prompt",
- disabled_tools=["string"],
- enabled_tools=["string"],
- guidance="guidance",
- instructions="instructions",
- model="model",
- object_ids=["string"],
- sandbox={
- "cpu": 0,
- "memory_mi_b": 0,
- },
- vault_ids=["string"],
- )
- assert_matches_type(ExecuteCreateResponse, execute, path=["response"])
-
- @parametrize
- def test_raw_response_create(self, client: Casedev) -> None:
- response = client.agent.v1.execute.with_raw_response.create(
- prompt="prompt",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- execute = response.parse()
- assert_matches_type(ExecuteCreateResponse, execute, path=["response"])
-
- @parametrize
- def test_streaming_response_create(self, client: Casedev) -> None:
- with client.agent.v1.execute.with_streaming_response.create(
- prompt="prompt",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- execute = response.parse()
- assert_matches_type(ExecuteCreateResponse, execute, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
-
-class TestAsyncExecute:
- parametrize = pytest.mark.parametrize(
- "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
- )
-
- @parametrize
- async def test_method_create(self, async_client: AsyncCasedev) -> None:
- execute = await async_client.agent.v1.execute.create(
- prompt="prompt",
- )
- assert_matches_type(ExecuteCreateResponse, execute, path=["response"])
-
- @parametrize
- async def test_method_create_with_all_params(self, async_client: AsyncCasedev) -> None:
- execute = await async_client.agent.v1.execute.create(
- prompt="prompt",
- disabled_tools=["string"],
- enabled_tools=["string"],
- guidance="guidance",
- instructions="instructions",
- model="model",
- object_ids=["string"],
- sandbox={
- "cpu": 0,
- "memory_mi_b": 0,
- },
- vault_ids=["string"],
- )
- assert_matches_type(ExecuteCreateResponse, execute, path=["response"])
-
- @parametrize
- async def test_raw_response_create(self, async_client: AsyncCasedev) -> None:
- response = await async_client.agent.v1.execute.with_raw_response.create(
- prompt="prompt",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- execute = await response.parse()
- assert_matches_type(ExecuteCreateResponse, execute, path=["response"])
-
- @parametrize
- async def test_streaming_response_create(self, async_client: AsyncCasedev) -> None:
- async with async_client.agent.v1.execute.with_streaming_response.create(
- prompt="prompt",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- execute = await response.parse()
- assert_matches_type(ExecuteCreateResponse, execute, path=["response"])
-
- assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/agent/v1/test_run.py b/tests/api_resources/agent/v1/test_run.py
deleted file mode 100644
index 902153a1..00000000
--- a/tests/api_resources/agent/v1/test_run.py
+++ /dev/null
@@ -1,672 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import pytest
-
-from casedev import Casedev, AsyncCasedev
-from tests.utils import assert_matches_type
-from casedev.types.agent.v1 import (
- RunExecResponse,
- RunListResponse,
- RunWatchResponse,
- RunCancelResponse,
- RunCreateResponse,
- RunGetStatusResponse,
- RunGetDetailsResponse,
-)
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestRun:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @parametrize
- def test_method_create(self, client: Casedev) -> None:
- run = client.agent.v1.run.create(
- agent_id="agentId",
- prompt="prompt",
- )
- assert_matches_type(RunCreateResponse, run, path=["response"])
-
- @parametrize
- def test_method_create_with_all_params(self, client: Casedev) -> None:
- run = client.agent.v1.run.create(
- agent_id="agentId",
- prompt="prompt",
- callback_url="https://example.com",
- guidance="guidance",
- model="model",
- object_ids=["string"],
- )
- assert_matches_type(RunCreateResponse, run, path=["response"])
-
- @parametrize
- def test_raw_response_create(self, client: Casedev) -> None:
- response = client.agent.v1.run.with_raw_response.create(
- agent_id="agentId",
- prompt="prompt",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- run = response.parse()
- assert_matches_type(RunCreateResponse, run, path=["response"])
-
- @parametrize
- def test_streaming_response_create(self, client: Casedev) -> None:
- with client.agent.v1.run.with_streaming_response.create(
- agent_id="agentId",
- prompt="prompt",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- run = response.parse()
- assert_matches_type(RunCreateResponse, run, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_method_list(self, client: Casedev) -> None:
- run = client.agent.v1.run.list()
- assert_matches_type(RunListResponse, run, path=["response"])
-
- @parametrize
- def test_method_list_with_all_params(self, client: Casedev) -> None:
- run = client.agent.v1.run.list(
- agent_id="agentId",
- cursor="cursor",
- limit=1,
- status="queued",
- )
- assert_matches_type(RunListResponse, run, path=["response"])
-
- @parametrize
- def test_raw_response_list(self, client: Casedev) -> None:
- response = client.agent.v1.run.with_raw_response.list()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- run = response.parse()
- assert_matches_type(RunListResponse, run, path=["response"])
-
- @parametrize
- def test_streaming_response_list(self, client: Casedev) -> None:
- with client.agent.v1.run.with_streaming_response.list() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- run = response.parse()
- assert_matches_type(RunListResponse, run, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_method_cancel(self, client: Casedev) -> None:
- run = client.agent.v1.run.cancel(
- "id",
- )
- assert_matches_type(RunCancelResponse, run, path=["response"])
-
- @parametrize
- def test_raw_response_cancel(self, client: Casedev) -> None:
- response = client.agent.v1.run.with_raw_response.cancel(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- run = response.parse()
- assert_matches_type(RunCancelResponse, run, path=["response"])
-
- @parametrize
- def test_streaming_response_cancel(self, client: Casedev) -> None:
- with client.agent.v1.run.with_streaming_response.cancel(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- run = response.parse()
- assert_matches_type(RunCancelResponse, run, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_cancel(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.agent.v1.run.with_raw_response.cancel(
- "",
- )
-
- @parametrize
- def test_method_events(self, client: Casedev) -> None:
- run_stream = client.agent.v1.run.events(
- id="id",
- )
- run_stream.response.close()
-
- @parametrize
- def test_method_events_with_all_params(self, client: Casedev) -> None:
- run_stream = client.agent.v1.run.events(
- id="id",
- last_event_id=0,
- )
- run_stream.response.close()
-
- @parametrize
- def test_raw_response_events(self, client: Casedev) -> None:
- response = client.agent.v1.run.with_raw_response.events(
- id="id",
- )
-
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- stream = response.parse()
- stream.close()
-
- @parametrize
- def test_streaming_response_events(self, client: Casedev) -> None:
- with client.agent.v1.run.with_streaming_response.events(
- id="id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- stream = response.parse()
- stream.close()
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_events(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.agent.v1.run.with_raw_response.events(
- id="",
- )
-
- @parametrize
- def test_method_exec(self, client: Casedev) -> None:
- run = client.agent.v1.run.exec(
- "id",
- )
- assert_matches_type(RunExecResponse, run, path=["response"])
-
- @parametrize
- def test_raw_response_exec(self, client: Casedev) -> None:
- response = client.agent.v1.run.with_raw_response.exec(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- run = response.parse()
- assert_matches_type(RunExecResponse, run, path=["response"])
-
- @parametrize
- def test_streaming_response_exec(self, client: Casedev) -> None:
- with client.agent.v1.run.with_streaming_response.exec(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- run = response.parse()
- assert_matches_type(RunExecResponse, run, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_exec(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.agent.v1.run.with_raw_response.exec(
- "",
- )
-
- @parametrize
- def test_method_get_details(self, client: Casedev) -> None:
- run = client.agent.v1.run.get_details(
- "id",
- )
- assert_matches_type(RunGetDetailsResponse, run, path=["response"])
-
- @parametrize
- def test_raw_response_get_details(self, client: Casedev) -> None:
- response = client.agent.v1.run.with_raw_response.get_details(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- run = response.parse()
- assert_matches_type(RunGetDetailsResponse, run, path=["response"])
-
- @parametrize
- def test_streaming_response_get_details(self, client: Casedev) -> None:
- with client.agent.v1.run.with_streaming_response.get_details(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- run = response.parse()
- assert_matches_type(RunGetDetailsResponse, run, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_get_details(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.agent.v1.run.with_raw_response.get_details(
- "",
- )
-
- @parametrize
- def test_method_get_status(self, client: Casedev) -> None:
- run = client.agent.v1.run.get_status(
- "id",
- )
- assert_matches_type(RunGetStatusResponse, run, path=["response"])
-
- @parametrize
- def test_raw_response_get_status(self, client: Casedev) -> None:
- response = client.agent.v1.run.with_raw_response.get_status(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- run = response.parse()
- assert_matches_type(RunGetStatusResponse, run, path=["response"])
-
- @parametrize
- def test_streaming_response_get_status(self, client: Casedev) -> None:
- with client.agent.v1.run.with_streaming_response.get_status(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- run = response.parse()
- assert_matches_type(RunGetStatusResponse, run, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_get_status(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.agent.v1.run.with_raw_response.get_status(
- "",
- )
-
- @parametrize
- def test_method_watch(self, client: Casedev) -> None:
- run = client.agent.v1.run.watch(
- id="id",
- callback_url="https://example.com",
- )
- assert_matches_type(RunWatchResponse, run, path=["response"])
-
- @parametrize
- def test_raw_response_watch(self, client: Casedev) -> None:
- response = client.agent.v1.run.with_raw_response.watch(
- id="id",
- callback_url="https://example.com",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- run = response.parse()
- assert_matches_type(RunWatchResponse, run, path=["response"])
-
- @parametrize
- def test_streaming_response_watch(self, client: Casedev) -> None:
- with client.agent.v1.run.with_streaming_response.watch(
- id="id",
- callback_url="https://example.com",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- run = response.parse()
- assert_matches_type(RunWatchResponse, run, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_watch(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.agent.v1.run.with_raw_response.watch(
- id="",
- callback_url="https://example.com",
- )
-
-
-class TestAsyncRun:
- parametrize = pytest.mark.parametrize(
- "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
- )
-
- @parametrize
- async def test_method_create(self, async_client: AsyncCasedev) -> None:
- run = await async_client.agent.v1.run.create(
- agent_id="agentId",
- prompt="prompt",
- )
- assert_matches_type(RunCreateResponse, run, path=["response"])
-
- @parametrize
- async def test_method_create_with_all_params(self, async_client: AsyncCasedev) -> None:
- run = await async_client.agent.v1.run.create(
- agent_id="agentId",
- prompt="prompt",
- callback_url="https://example.com",
- guidance="guidance",
- model="model",
- object_ids=["string"],
- )
- assert_matches_type(RunCreateResponse, run, path=["response"])
-
- @parametrize
- async def test_raw_response_create(self, async_client: AsyncCasedev) -> None:
- response = await async_client.agent.v1.run.with_raw_response.create(
- agent_id="agentId",
- prompt="prompt",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- run = await response.parse()
- assert_matches_type(RunCreateResponse, run, path=["response"])
-
- @parametrize
- async def test_streaming_response_create(self, async_client: AsyncCasedev) -> None:
- async with async_client.agent.v1.run.with_streaming_response.create(
- agent_id="agentId",
- prompt="prompt",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- run = await response.parse()
- assert_matches_type(RunCreateResponse, run, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_method_list(self, async_client: AsyncCasedev) -> None:
- run = await async_client.agent.v1.run.list()
- assert_matches_type(RunListResponse, run, path=["response"])
-
- @parametrize
- async def test_method_list_with_all_params(self, async_client: AsyncCasedev) -> None:
- run = await async_client.agent.v1.run.list(
- agent_id="agentId",
- cursor="cursor",
- limit=1,
- status="queued",
- )
- assert_matches_type(RunListResponse, run, path=["response"])
-
- @parametrize
- async def test_raw_response_list(self, async_client: AsyncCasedev) -> None:
- response = await async_client.agent.v1.run.with_raw_response.list()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- run = await response.parse()
- assert_matches_type(RunListResponse, run, path=["response"])
-
- @parametrize
- async def test_streaming_response_list(self, async_client: AsyncCasedev) -> None:
- async with async_client.agent.v1.run.with_streaming_response.list() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- run = await response.parse()
- assert_matches_type(RunListResponse, run, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_method_cancel(self, async_client: AsyncCasedev) -> None:
- run = await async_client.agent.v1.run.cancel(
- "id",
- )
- assert_matches_type(RunCancelResponse, run, path=["response"])
-
- @parametrize
- async def test_raw_response_cancel(self, async_client: AsyncCasedev) -> None:
- response = await async_client.agent.v1.run.with_raw_response.cancel(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- run = await response.parse()
- assert_matches_type(RunCancelResponse, run, path=["response"])
-
- @parametrize
- async def test_streaming_response_cancel(self, async_client: AsyncCasedev) -> None:
- async with async_client.agent.v1.run.with_streaming_response.cancel(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- run = await response.parse()
- assert_matches_type(RunCancelResponse, run, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_cancel(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- await async_client.agent.v1.run.with_raw_response.cancel(
- "",
- )
-
- @parametrize
- async def test_method_events(self, async_client: AsyncCasedev) -> None:
- run_stream = await async_client.agent.v1.run.events(
- id="id",
- )
- await run_stream.response.aclose()
-
- @parametrize
- async def test_method_events_with_all_params(self, async_client: AsyncCasedev) -> None:
- run_stream = await async_client.agent.v1.run.events(
- id="id",
- last_event_id=0,
- )
- await run_stream.response.aclose()
-
- @parametrize
- async def test_raw_response_events(self, async_client: AsyncCasedev) -> None:
- response = await async_client.agent.v1.run.with_raw_response.events(
- id="id",
- )
-
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- stream = await response.parse()
- await stream.close()
-
- @parametrize
- async def test_streaming_response_events(self, async_client: AsyncCasedev) -> None:
- async with async_client.agent.v1.run.with_streaming_response.events(
- id="id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- stream = await response.parse()
- await stream.close()
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_events(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- await async_client.agent.v1.run.with_raw_response.events(
- id="",
- )
-
- @parametrize
- async def test_method_exec(self, async_client: AsyncCasedev) -> None:
- run = await async_client.agent.v1.run.exec(
- "id",
- )
- assert_matches_type(RunExecResponse, run, path=["response"])
-
- @parametrize
- async def test_raw_response_exec(self, async_client: AsyncCasedev) -> None:
- response = await async_client.agent.v1.run.with_raw_response.exec(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- run = await response.parse()
- assert_matches_type(RunExecResponse, run, path=["response"])
-
- @parametrize
- async def test_streaming_response_exec(self, async_client: AsyncCasedev) -> None:
- async with async_client.agent.v1.run.with_streaming_response.exec(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- run = await response.parse()
- assert_matches_type(RunExecResponse, run, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_exec(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- await async_client.agent.v1.run.with_raw_response.exec(
- "",
- )
-
- @parametrize
- async def test_method_get_details(self, async_client: AsyncCasedev) -> None:
- run = await async_client.agent.v1.run.get_details(
- "id",
- )
- assert_matches_type(RunGetDetailsResponse, run, path=["response"])
-
- @parametrize
- async def test_raw_response_get_details(self, async_client: AsyncCasedev) -> None:
- response = await async_client.agent.v1.run.with_raw_response.get_details(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- run = await response.parse()
- assert_matches_type(RunGetDetailsResponse, run, path=["response"])
-
- @parametrize
- async def test_streaming_response_get_details(self, async_client: AsyncCasedev) -> None:
- async with async_client.agent.v1.run.with_streaming_response.get_details(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- run = await response.parse()
- assert_matches_type(RunGetDetailsResponse, run, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_get_details(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- await async_client.agent.v1.run.with_raw_response.get_details(
- "",
- )
-
- @parametrize
- async def test_method_get_status(self, async_client: AsyncCasedev) -> None:
- run = await async_client.agent.v1.run.get_status(
- "id",
- )
- assert_matches_type(RunGetStatusResponse, run, path=["response"])
-
- @parametrize
- async def test_raw_response_get_status(self, async_client: AsyncCasedev) -> None:
- response = await async_client.agent.v1.run.with_raw_response.get_status(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- run = await response.parse()
- assert_matches_type(RunGetStatusResponse, run, path=["response"])
-
- @parametrize
- async def test_streaming_response_get_status(self, async_client: AsyncCasedev) -> None:
- async with async_client.agent.v1.run.with_streaming_response.get_status(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- run = await response.parse()
- assert_matches_type(RunGetStatusResponse, run, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_get_status(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- await async_client.agent.v1.run.with_raw_response.get_status(
- "",
- )
-
- @parametrize
- async def test_method_watch(self, async_client: AsyncCasedev) -> None:
- run = await async_client.agent.v1.run.watch(
- id="id",
- callback_url="https://example.com",
- )
- assert_matches_type(RunWatchResponse, run, path=["response"])
-
- @parametrize
- async def test_raw_response_watch(self, async_client: AsyncCasedev) -> None:
- response = await async_client.agent.v1.run.with_raw_response.watch(
- id="id",
- callback_url="https://example.com",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- run = await response.parse()
- assert_matches_type(RunWatchResponse, run, path=["response"])
-
- @parametrize
- async def test_streaming_response_watch(self, async_client: AsyncCasedev) -> None:
- async with async_client.agent.v1.run.with_streaming_response.watch(
- id="id",
- callback_url="https://example.com",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- run = await response.parse()
- assert_matches_type(RunWatchResponse, run, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_watch(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- await async_client.agent.v1.run.with_raw_response.watch(
- id="",
- callback_url="https://example.com",
- )
diff --git a/tests/api_resources/agent/__init__.py b/tests/api_resources/connectors/__init__.py
similarity index 100%
rename from tests/api_resources/agent/__init__.py
rename to tests/api_resources/connectors/__init__.py
diff --git a/tests/api_resources/connectors/test_v1.py b/tests/api_resources/connectors/test_v1.py
new file mode 100644
index 00000000..c74c3ae3
--- /dev/null
+++ b/tests/api_resources/connectors/test_v1.py
@@ -0,0 +1,282 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from casedev import Casedev, AsyncCasedev
+from tests.utils import assert_matches_type
+from casedev.types.connectors import V1SyncLinkResponse, V1TransferResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestV1:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_sync_link(self, client: Casedev) -> None:
+ v1 = client.connectors.v1.sync_link(
+ connection_id="connection_id",
+ direction="import",
+ remote={"folder_id": "folder_id"},
+ vault_id="vault_id",
+ )
+ assert_matches_type(V1SyncLinkResponse, v1, path=["response"])
+
+ @parametrize
+ def test_method_sync_link_with_all_params(self, client: Casedev) -> None:
+ v1 = client.connectors.v1.sync_link(
+ connection_id="connection_id",
+ direction="import",
+ remote={
+ "folder_id": "folder_id",
+ "container_id": "container_id",
+ "path": "path",
+ "site_id": "site_id",
+ },
+ vault_id="vault_id",
+ matter_id="matter_id",
+ policy={
+ "collisions": "version",
+ "deletes": "mirror",
+ "filters": {
+ "exclude_mime": ["string"],
+ "max_size_bytes": 0,
+ },
+ },
+ )
+ assert_matches_type(V1SyncLinkResponse, v1, path=["response"])
+
+ @parametrize
+ def test_raw_response_sync_link(self, client: Casedev) -> None:
+ response = client.connectors.v1.with_raw_response.sync_link(
+ connection_id="connection_id",
+ direction="import",
+ remote={"folder_id": "folder_id"},
+ vault_id="vault_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ v1 = response.parse()
+ assert_matches_type(V1SyncLinkResponse, v1, path=["response"])
+
+ @parametrize
+ def test_streaming_response_sync_link(self, client: Casedev) -> None:
+ with client.connectors.v1.with_streaming_response.sync_link(
+ connection_id="connection_id",
+ direction="import",
+ remote={"folder_id": "folder_id"},
+ vault_id="vault_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ v1 = response.parse()
+ assert_matches_type(V1SyncLinkResponse, v1, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_transfer(self, client: Casedev) -> None:
+ v1 = client.connectors.v1.transfer(
+ connection_id="connection_id",
+ direction="import",
+ remote={"folder_id": "folder_id"},
+ vault_id="vault_id",
+ )
+ assert_matches_type(V1TransferResponse, v1, path=["response"])
+
+ @parametrize
+ def test_method_transfer_with_all_params(self, client: Casedev) -> None:
+ v1 = client.connectors.v1.transfer(
+ connection_id="connection_id",
+ direction="import",
+ remote={
+ "folder_id": "folder_id",
+ "container_id": "container_id",
+ "path": "path",
+ "site_id": "site_id",
+ },
+ vault_id="vault_id",
+ matter_id="matter_id",
+ policy={
+ "collisions": "version",
+ "deletes": "mirror",
+ "filters": {
+ "exclude_mime": ["string"],
+ "max_size_bytes": 0,
+ },
+ },
+ run_mode="auto",
+ )
+ assert_matches_type(V1TransferResponse, v1, path=["response"])
+
+ @parametrize
+ def test_raw_response_transfer(self, client: Casedev) -> None:
+ response = client.connectors.v1.with_raw_response.transfer(
+ connection_id="connection_id",
+ direction="import",
+ remote={"folder_id": "folder_id"},
+ vault_id="vault_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ v1 = response.parse()
+ assert_matches_type(V1TransferResponse, v1, path=["response"])
+
+ @parametrize
+ def test_streaming_response_transfer(self, client: Casedev) -> None:
+ with client.connectors.v1.with_streaming_response.transfer(
+ connection_id="connection_id",
+ direction="import",
+ remote={"folder_id": "folder_id"},
+ vault_id="vault_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ v1 = response.parse()
+ assert_matches_type(V1TransferResponse, v1, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncV1:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_sync_link(self, async_client: AsyncCasedev) -> None:
+ v1 = await async_client.connectors.v1.sync_link(
+ connection_id="connection_id",
+ direction="import",
+ remote={"folder_id": "folder_id"},
+ vault_id="vault_id",
+ )
+ assert_matches_type(V1SyncLinkResponse, v1, path=["response"])
+
+ @parametrize
+ async def test_method_sync_link_with_all_params(self, async_client: AsyncCasedev) -> None:
+ v1 = await async_client.connectors.v1.sync_link(
+ connection_id="connection_id",
+ direction="import",
+ remote={
+ "folder_id": "folder_id",
+ "container_id": "container_id",
+ "path": "path",
+ "site_id": "site_id",
+ },
+ vault_id="vault_id",
+ matter_id="matter_id",
+ policy={
+ "collisions": "version",
+ "deletes": "mirror",
+ "filters": {
+ "exclude_mime": ["string"],
+ "max_size_bytes": 0,
+ },
+ },
+ )
+ assert_matches_type(V1SyncLinkResponse, v1, path=["response"])
+
+ @parametrize
+ async def test_raw_response_sync_link(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.connectors.v1.with_raw_response.sync_link(
+ connection_id="connection_id",
+ direction="import",
+ remote={"folder_id": "folder_id"},
+ vault_id="vault_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ v1 = await response.parse()
+ assert_matches_type(V1SyncLinkResponse, v1, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_sync_link(self, async_client: AsyncCasedev) -> None:
+ async with async_client.connectors.v1.with_streaming_response.sync_link(
+ connection_id="connection_id",
+ direction="import",
+ remote={"folder_id": "folder_id"},
+ vault_id="vault_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ v1 = await response.parse()
+ assert_matches_type(V1SyncLinkResponse, v1, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_transfer(self, async_client: AsyncCasedev) -> None:
+ v1 = await async_client.connectors.v1.transfer(
+ connection_id="connection_id",
+ direction="import",
+ remote={"folder_id": "folder_id"},
+ vault_id="vault_id",
+ )
+ assert_matches_type(V1TransferResponse, v1, path=["response"])
+
+ @parametrize
+ async def test_method_transfer_with_all_params(self, async_client: AsyncCasedev) -> None:
+ v1 = await async_client.connectors.v1.transfer(
+ connection_id="connection_id",
+ direction="import",
+ remote={
+ "folder_id": "folder_id",
+ "container_id": "container_id",
+ "path": "path",
+ "site_id": "site_id",
+ },
+ vault_id="vault_id",
+ matter_id="matter_id",
+ policy={
+ "collisions": "version",
+ "deletes": "mirror",
+ "filters": {
+ "exclude_mime": ["string"],
+ "max_size_bytes": 0,
+ },
+ },
+ run_mode="auto",
+ )
+ assert_matches_type(V1TransferResponse, v1, path=["response"])
+
+ @parametrize
+ async def test_raw_response_transfer(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.connectors.v1.with_raw_response.transfer(
+ connection_id="connection_id",
+ direction="import",
+ remote={"folder_id": "folder_id"},
+ vault_id="vault_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ v1 = await response.parse()
+ assert_matches_type(V1TransferResponse, v1, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_transfer(self, async_client: AsyncCasedev) -> None:
+ async with async_client.connectors.v1.with_streaming_response.transfer(
+ connection_id="connection_id",
+ direction="import",
+ remote={"folder_id": "folder_id"},
+ vault_id="vault_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ v1 = await response.parse()
+ assert_matches_type(V1TransferResponse, v1, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/agent/v1/__init__.py b/tests/api_resources/connectors/v1/__init__.py
similarity index 100%
rename from tests/api_resources/agent/v1/__init__.py
rename to tests/api_resources/connectors/v1/__init__.py
diff --git a/tests/api_resources/database/__init__.py b/tests/api_resources/connectors/v1/installations/__init__.py
similarity index 100%
rename from tests/api_resources/database/__init__.py
rename to tests/api_resources/connectors/v1/installations/__init__.py
diff --git a/tests/api_resources/connectors/v1/installations/test_vaults.py b/tests/api_resources/connectors/v1/installations/test_vaults.py
new file mode 100644
index 00000000..00855920
--- /dev/null
+++ b/tests/api_resources/connectors/v1/installations/test_vaults.py
@@ -0,0 +1,316 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from casedev import Casedev, AsyncCasedev
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestVaults:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_list(self, client: Casedev) -> None:
+ vault = client.connectors.v1.installations.vaults.list(
+ "id",
+ )
+ assert vault is None
+
+ @parametrize
+ def test_raw_response_list(self, client: Casedev) -> None:
+ response = client.connectors.v1.installations.vaults.with_raw_response.list(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ vault = response.parse()
+ assert vault is None
+
+ @parametrize
+ def test_streaming_response_list(self, client: Casedev) -> None:
+ with client.connectors.v1.installations.vaults.with_streaming_response.list(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ vault = response.parse()
+ assert vault is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_list(self, client: Casedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.connectors.v1.installations.vaults.with_raw_response.list(
+ "",
+ )
+
+ @parametrize
+ def test_method_grant(self, client: Casedev) -> None:
+ vault = client.connectors.v1.installations.vaults.grant(
+ vault_id="vaultId",
+ id="id",
+ )
+ assert vault is None
+
+ @parametrize
+ def test_method_grant_with_all_params(self, client: Casedev) -> None:
+ vault = client.connectors.v1.installations.vaults.grant(
+ vault_id="vaultId",
+ id="id",
+ can_manage=True,
+ can_read=True,
+ can_write=True,
+ relationship="owned",
+ source="provisioning",
+ )
+ assert vault is None
+
+ @parametrize
+ def test_raw_response_grant(self, client: Casedev) -> None:
+ response = client.connectors.v1.installations.vaults.with_raw_response.grant(
+ vault_id="vaultId",
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ vault = response.parse()
+ assert vault is None
+
+ @parametrize
+ def test_streaming_response_grant(self, client: Casedev) -> None:
+ with client.connectors.v1.installations.vaults.with_streaming_response.grant(
+ vault_id="vaultId",
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ vault = response.parse()
+ assert vault is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_grant(self, client: Casedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.connectors.v1.installations.vaults.with_raw_response.grant(
+ vault_id="vaultId",
+ id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `vault_id` but received ''"):
+ client.connectors.v1.installations.vaults.with_raw_response.grant(
+ vault_id="",
+ id="id",
+ )
+
+ @parametrize
+ def test_method_revoke(self, client: Casedev) -> None:
+ vault = client.connectors.v1.installations.vaults.revoke(
+ vault_id="vaultId",
+ id="id",
+ )
+ assert vault is None
+
+ @parametrize
+ def test_raw_response_revoke(self, client: Casedev) -> None:
+ response = client.connectors.v1.installations.vaults.with_raw_response.revoke(
+ vault_id="vaultId",
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ vault = response.parse()
+ assert vault is None
+
+ @parametrize
+ def test_streaming_response_revoke(self, client: Casedev) -> None:
+ with client.connectors.v1.installations.vaults.with_streaming_response.revoke(
+ vault_id="vaultId",
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ vault = response.parse()
+ assert vault is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_revoke(self, client: Casedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.connectors.v1.installations.vaults.with_raw_response.revoke(
+ vault_id="vaultId",
+ id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `vault_id` but received ''"):
+ client.connectors.v1.installations.vaults.with_raw_response.revoke(
+ vault_id="",
+ id="id",
+ )
+
+
+class TestAsyncVaults:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncCasedev) -> None:
+ vault = await async_client.connectors.v1.installations.vaults.list(
+ "id",
+ )
+ assert vault is None
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.connectors.v1.installations.vaults.with_raw_response.list(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ vault = await response.parse()
+ assert vault is None
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncCasedev) -> None:
+ async with async_client.connectors.v1.installations.vaults.with_streaming_response.list(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ vault = await response.parse()
+ assert vault is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_list(self, async_client: AsyncCasedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.connectors.v1.installations.vaults.with_raw_response.list(
+ "",
+ )
+
+ @parametrize
+ async def test_method_grant(self, async_client: AsyncCasedev) -> None:
+ vault = await async_client.connectors.v1.installations.vaults.grant(
+ vault_id="vaultId",
+ id="id",
+ )
+ assert vault is None
+
+ @parametrize
+ async def test_method_grant_with_all_params(self, async_client: AsyncCasedev) -> None:
+ vault = await async_client.connectors.v1.installations.vaults.grant(
+ vault_id="vaultId",
+ id="id",
+ can_manage=True,
+ can_read=True,
+ can_write=True,
+ relationship="owned",
+ source="provisioning",
+ )
+ assert vault is None
+
+ @parametrize
+ async def test_raw_response_grant(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.connectors.v1.installations.vaults.with_raw_response.grant(
+ vault_id="vaultId",
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ vault = await response.parse()
+ assert vault is None
+
+ @parametrize
+ async def test_streaming_response_grant(self, async_client: AsyncCasedev) -> None:
+ async with async_client.connectors.v1.installations.vaults.with_streaming_response.grant(
+ vault_id="vaultId",
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ vault = await response.parse()
+ assert vault is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_grant(self, async_client: AsyncCasedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.connectors.v1.installations.vaults.with_raw_response.grant(
+ vault_id="vaultId",
+ id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `vault_id` but received ''"):
+ await async_client.connectors.v1.installations.vaults.with_raw_response.grant(
+ vault_id="",
+ id="id",
+ )
+
+ @parametrize
+ async def test_method_revoke(self, async_client: AsyncCasedev) -> None:
+ vault = await async_client.connectors.v1.installations.vaults.revoke(
+ vault_id="vaultId",
+ id="id",
+ )
+ assert vault is None
+
+ @parametrize
+ async def test_raw_response_revoke(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.connectors.v1.installations.vaults.with_raw_response.revoke(
+ vault_id="vaultId",
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ vault = await response.parse()
+ assert vault is None
+
+ @parametrize
+ async def test_streaming_response_revoke(self, async_client: AsyncCasedev) -> None:
+ async with async_client.connectors.v1.installations.vaults.with_streaming_response.revoke(
+ vault_id="vaultId",
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ vault = await response.parse()
+ assert vault is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_revoke(self, async_client: AsyncCasedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.connectors.v1.installations.vaults.with_raw_response.revoke(
+ vault_id="vaultId",
+ id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `vault_id` but received ''"):
+ await async_client.connectors.v1.installations.vaults.with_raw_response.revoke(
+ vault_id="",
+ id="id",
+ )
diff --git a/tests/api_resources/connectors/v1/test_connections.py b/tests/api_resources/connectors/v1/test_connections.py
new file mode 100644
index 00000000..b434fc17
--- /dev/null
+++ b/tests/api_resources/connectors/v1/test_connections.py
@@ -0,0 +1,450 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from casedev import Casedev, AsyncCasedev
+from tests.utils import assert_matches_type
+from casedev.types.connectors.v1 import (
+ ConnectionListResponse,
+ ConnectionBrowseResponse,
+ ConnectionCreateResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestConnections:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: Casedev) -> None:
+ connection = client.connectors.v1.connections.create(
+ provider="clio",
+ return_url="return_url",
+ )
+ assert_matches_type(ConnectionCreateResponse, connection, path=["response"])
+
+ @parametrize
+ def test_method_create_with_all_params(self, client: Casedev) -> None:
+ connection = client.connectors.v1.connections.create(
+ provider="clio",
+ return_url="return_url",
+ scope_tier="clio.us",
+ )
+ assert_matches_type(ConnectionCreateResponse, connection, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Casedev) -> None:
+ response = client.connectors.v1.connections.with_raw_response.create(
+ provider="clio",
+ return_url="return_url",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connection = response.parse()
+ assert_matches_type(ConnectionCreateResponse, connection, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: Casedev) -> None:
+ with client.connectors.v1.connections.with_streaming_response.create(
+ provider="clio",
+ return_url="return_url",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ connection = response.parse()
+ assert_matches_type(ConnectionCreateResponse, connection, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_retrieve(self, client: Casedev) -> None:
+ connection = client.connectors.v1.connections.retrieve(
+ "id",
+ )
+ assert connection is None
+
+ @parametrize
+ def test_raw_response_retrieve(self, client: Casedev) -> None:
+ response = client.connectors.v1.connections.with_raw_response.retrieve(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connection = response.parse()
+ assert connection is None
+
+ @parametrize
+ def test_streaming_response_retrieve(self, client: Casedev) -> None:
+ with client.connectors.v1.connections.with_streaming_response.retrieve(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ connection = response.parse()
+ assert connection is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_retrieve(self, client: Casedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.connectors.v1.connections.with_raw_response.retrieve(
+ "",
+ )
+
+ @parametrize
+ def test_method_list(self, client: Casedev) -> None:
+ connection = client.connectors.v1.connections.list()
+ assert_matches_type(ConnectionListResponse, connection, path=["response"])
+
+ @parametrize
+ def test_method_list_with_all_params(self, client: Casedev) -> None:
+ connection = client.connectors.v1.connections.list(
+ provider="provider",
+ status="pending",
+ )
+ assert_matches_type(ConnectionListResponse, connection, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Casedev) -> None:
+ response = client.connectors.v1.connections.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connection = response.parse()
+ assert_matches_type(ConnectionListResponse, connection, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Casedev) -> None:
+ with client.connectors.v1.connections.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ connection = response.parse()
+ assert_matches_type(ConnectionListResponse, connection, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_delete(self, client: Casedev) -> None:
+ connection = client.connectors.v1.connections.delete(
+ id="id",
+ )
+ assert connection is None
+
+ @parametrize
+ def test_method_delete_with_all_params(self, client: Casedev) -> None:
+ connection = client.connectors.v1.connections.delete(
+ id="id",
+ purge=True,
+ )
+ assert connection is None
+
+ @parametrize
+ def test_raw_response_delete(self, client: Casedev) -> None:
+ response = client.connectors.v1.connections.with_raw_response.delete(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connection = response.parse()
+ assert connection is None
+
+ @parametrize
+ def test_streaming_response_delete(self, client: Casedev) -> None:
+ with client.connectors.v1.connections.with_streaming_response.delete(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ connection = response.parse()
+ assert connection is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_delete(self, client: Casedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.connectors.v1.connections.with_raw_response.delete(
+ id="",
+ )
+
+ @parametrize
+ def test_method_browse(self, client: Casedev) -> None:
+ connection = client.connectors.v1.connections.browse(
+ id="id",
+ )
+ assert_matches_type(ConnectionBrowseResponse, connection, path=["response"])
+
+ @parametrize
+ def test_method_browse_with_all_params(self, client: Casedev) -> None:
+ connection = client.connectors.v1.connections.browse(
+ id="id",
+ container="container",
+ cursor="cursor",
+ page_size=1000,
+ parent="parent",
+ query="query",
+ site="site",
+ )
+ assert_matches_type(ConnectionBrowseResponse, connection, path=["response"])
+
+ @parametrize
+ def test_raw_response_browse(self, client: Casedev) -> None:
+ response = client.connectors.v1.connections.with_raw_response.browse(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connection = response.parse()
+ assert_matches_type(ConnectionBrowseResponse, connection, path=["response"])
+
+ @parametrize
+ def test_streaming_response_browse(self, client: Casedev) -> None:
+ with client.connectors.v1.connections.with_streaming_response.browse(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ connection = response.parse()
+ assert_matches_type(ConnectionBrowseResponse, connection, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_browse(self, client: Casedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.connectors.v1.connections.with_raw_response.browse(
+ id="",
+ )
+
+
+class TestAsyncConnections:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_create(self, async_client: AsyncCasedev) -> None:
+ connection = await async_client.connectors.v1.connections.create(
+ provider="clio",
+ return_url="return_url",
+ )
+ assert_matches_type(ConnectionCreateResponse, connection, path=["response"])
+
+ @parametrize
+ async def test_method_create_with_all_params(self, async_client: AsyncCasedev) -> None:
+ connection = await async_client.connectors.v1.connections.create(
+ provider="clio",
+ return_url="return_url",
+ scope_tier="clio.us",
+ )
+ assert_matches_type(ConnectionCreateResponse, connection, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.connectors.v1.connections.with_raw_response.create(
+ provider="clio",
+ return_url="return_url",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connection = await response.parse()
+ assert_matches_type(ConnectionCreateResponse, connection, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncCasedev) -> None:
+ async with async_client.connectors.v1.connections.with_streaming_response.create(
+ provider="clio",
+ return_url="return_url",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ connection = await response.parse()
+ assert_matches_type(ConnectionCreateResponse, connection, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_retrieve(self, async_client: AsyncCasedev) -> None:
+ connection = await async_client.connectors.v1.connections.retrieve(
+ "id",
+ )
+ assert connection is None
+
+ @parametrize
+ async def test_raw_response_retrieve(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.connectors.v1.connections.with_raw_response.retrieve(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connection = await response.parse()
+ assert connection is None
+
+ @parametrize
+ async def test_streaming_response_retrieve(self, async_client: AsyncCasedev) -> None:
+ async with async_client.connectors.v1.connections.with_streaming_response.retrieve(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ connection = await response.parse()
+ assert connection is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_retrieve(self, async_client: AsyncCasedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.connectors.v1.connections.with_raw_response.retrieve(
+ "",
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncCasedev) -> None:
+ connection = await async_client.connectors.v1.connections.list()
+ assert_matches_type(ConnectionListResponse, connection, path=["response"])
+
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncCasedev) -> None:
+ connection = await async_client.connectors.v1.connections.list(
+ provider="provider",
+ status="pending",
+ )
+ assert_matches_type(ConnectionListResponse, connection, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.connectors.v1.connections.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connection = await response.parse()
+ assert_matches_type(ConnectionListResponse, connection, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncCasedev) -> None:
+ async with async_client.connectors.v1.connections.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ connection = await response.parse()
+ assert_matches_type(ConnectionListResponse, connection, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncCasedev) -> None:
+ connection = await async_client.connectors.v1.connections.delete(
+ id="id",
+ )
+ assert connection is None
+
+ @parametrize
+ async def test_method_delete_with_all_params(self, async_client: AsyncCasedev) -> None:
+ connection = await async_client.connectors.v1.connections.delete(
+ id="id",
+ purge=True,
+ )
+ assert connection is None
+
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.connectors.v1.connections.with_raw_response.delete(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connection = await response.parse()
+ assert connection is None
+
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncCasedev) -> None:
+ async with async_client.connectors.v1.connections.with_streaming_response.delete(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ connection = await response.parse()
+ assert connection is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_delete(self, async_client: AsyncCasedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.connectors.v1.connections.with_raw_response.delete(
+ id="",
+ )
+
+ @parametrize
+ async def test_method_browse(self, async_client: AsyncCasedev) -> None:
+ connection = await async_client.connectors.v1.connections.browse(
+ id="id",
+ )
+ assert_matches_type(ConnectionBrowseResponse, connection, path=["response"])
+
+ @parametrize
+ async def test_method_browse_with_all_params(self, async_client: AsyncCasedev) -> None:
+ connection = await async_client.connectors.v1.connections.browse(
+ id="id",
+ container="container",
+ cursor="cursor",
+ page_size=1000,
+ parent="parent",
+ query="query",
+ site="site",
+ )
+ assert_matches_type(ConnectionBrowseResponse, connection, path=["response"])
+
+ @parametrize
+ async def test_raw_response_browse(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.connectors.v1.connections.with_raw_response.browse(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connection = await response.parse()
+ assert_matches_type(ConnectionBrowseResponse, connection, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_browse(self, async_client: AsyncCasedev) -> None:
+ async with async_client.connectors.v1.connections.with_streaming_response.browse(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ connection = await response.parse()
+ assert_matches_type(ConnectionBrowseResponse, connection, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_browse(self, async_client: AsyncCasedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.connectors.v1.connections.with_raw_response.browse(
+ id="",
+ )
diff --git a/tests/api_resources/connectors/v1/test_installations.py b/tests/api_resources/connectors/v1/test_installations.py
new file mode 100644
index 00000000..b97b2a38
--- /dev/null
+++ b/tests/api_resources/connectors/v1/test_installations.py
@@ -0,0 +1,156 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from casedev import Casedev, AsyncCasedev
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestInstallations:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_list(self, client: Casedev) -> None:
+ installation = client.connectors.v1.installations.list()
+ assert installation is None
+
+ @parametrize
+ def test_method_list_with_all_params(self, client: Casedev) -> None:
+ installation = client.connectors.v1.installations.list(
+ application="application",
+ external_tenant_id="external_tenant_id",
+ )
+ assert installation is None
+
+ @parametrize
+ def test_raw_response_list(self, client: Casedev) -> None:
+ response = client.connectors.v1.installations.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ installation = response.parse()
+ assert installation is None
+
+ @parametrize
+ def test_streaming_response_list(self, client: Casedev) -> None:
+ with client.connectors.v1.installations.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ installation = response.parse()
+ assert installation is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_ensure(self, client: Casedev) -> None:
+ installation = client.connectors.v1.installations.ensure(
+ application="application",
+ external_tenant_id="external_tenant_id",
+ )
+ assert installation is None
+
+ @parametrize
+ def test_raw_response_ensure(self, client: Casedev) -> None:
+ response = client.connectors.v1.installations.with_raw_response.ensure(
+ application="application",
+ external_tenant_id="external_tenant_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ installation = response.parse()
+ assert installation is None
+
+ @parametrize
+ def test_streaming_response_ensure(self, client: Casedev) -> None:
+ with client.connectors.v1.installations.with_streaming_response.ensure(
+ application="application",
+ external_tenant_id="external_tenant_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ installation = response.parse()
+ assert installation is None
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncInstallations:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncCasedev) -> None:
+ installation = await async_client.connectors.v1.installations.list()
+ assert installation is None
+
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncCasedev) -> None:
+ installation = await async_client.connectors.v1.installations.list(
+ application="application",
+ external_tenant_id="external_tenant_id",
+ )
+ assert installation is None
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.connectors.v1.installations.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ installation = await response.parse()
+ assert installation is None
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncCasedev) -> None:
+ async with async_client.connectors.v1.installations.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ installation = await response.parse()
+ assert installation is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_ensure(self, async_client: AsyncCasedev) -> None:
+ installation = await async_client.connectors.v1.installations.ensure(
+ application="application",
+ external_tenant_id="external_tenant_id",
+ )
+ assert installation is None
+
+ @parametrize
+ async def test_raw_response_ensure(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.connectors.v1.installations.with_raw_response.ensure(
+ application="application",
+ external_tenant_id="external_tenant_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ installation = await response.parse()
+ assert installation is None
+
+ @parametrize
+ async def test_streaming_response_ensure(self, async_client: AsyncCasedev) -> None:
+ async with async_client.connectors.v1.installations.with_streaming_response.ensure(
+ application="application",
+ external_tenant_id="external_tenant_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ installation = await response.parse()
+ assert installation is None
+
+ assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/connectors/v1/test_links.py b/tests/api_resources/connectors/v1/test_links.py
new file mode 100644
index 00000000..dd16ceef
--- /dev/null
+++ b/tests/api_resources/connectors/v1/test_links.py
@@ -0,0 +1,454 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from casedev import Casedev, AsyncCasedev
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestLinks:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_retrieve(self, client: Casedev) -> None:
+ link = client.connectors.v1.links.retrieve(
+ "id",
+ )
+ assert link is None
+
+ @parametrize
+ def test_raw_response_retrieve(self, client: Casedev) -> None:
+ response = client.connectors.v1.links.with_raw_response.retrieve(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ link = response.parse()
+ assert link is None
+
+ @parametrize
+ def test_streaming_response_retrieve(self, client: Casedev) -> None:
+ with client.connectors.v1.links.with_streaming_response.retrieve(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ link = response.parse()
+ assert link is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_retrieve(self, client: Casedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.connectors.v1.links.with_raw_response.retrieve(
+ "",
+ )
+
+ @parametrize
+ def test_method_update(self, client: Casedev) -> None:
+ link = client.connectors.v1.links.update(
+ id="id",
+ )
+ assert link is None
+
+ @parametrize
+ def test_method_update_with_all_params(self, client: Casedev) -> None:
+ link = client.connectors.v1.links.update(
+ id="id",
+ mode="once",
+ policy={},
+ state="paused",
+ )
+ assert link is None
+
+ @parametrize
+ def test_raw_response_update(self, client: Casedev) -> None:
+ response = client.connectors.v1.links.with_raw_response.update(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ link = response.parse()
+ assert link is None
+
+ @parametrize
+ def test_streaming_response_update(self, client: Casedev) -> None:
+ with client.connectors.v1.links.with_streaming_response.update(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ link = response.parse()
+ assert link is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_update(self, client: Casedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.connectors.v1.links.with_raw_response.update(
+ id="",
+ )
+
+ @parametrize
+ def test_method_list(self, client: Casedev) -> None:
+ link = client.connectors.v1.links.list()
+ assert link is None
+
+ @parametrize
+ def test_method_list_with_all_params(self, client: Casedev) -> None:
+ link = client.connectors.v1.links.list(
+ connection_id="connection_id",
+ direction="import",
+ mode="once",
+ pair_id="pair_id",
+ state="ready",
+ vault_id="vault_id",
+ )
+ assert link is None
+
+ @parametrize
+ def test_raw_response_list(self, client: Casedev) -> None:
+ response = client.connectors.v1.links.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ link = response.parse()
+ assert link is None
+
+ @parametrize
+ def test_streaming_response_list(self, client: Casedev) -> None:
+ with client.connectors.v1.links.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ link = response.parse()
+ assert link is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_delete(self, client: Casedev) -> None:
+ link = client.connectors.v1.links.delete(
+ id="id",
+ )
+ assert link is None
+
+ @parametrize
+ def test_method_delete_with_all_params(self, client: Casedev) -> None:
+ link = client.connectors.v1.links.delete(
+ id="id",
+ vault_docs="keep",
+ )
+ assert link is None
+
+ @parametrize
+ def test_raw_response_delete(self, client: Casedev) -> None:
+ response = client.connectors.v1.links.with_raw_response.delete(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ link = response.parse()
+ assert link is None
+
+ @parametrize
+ def test_streaming_response_delete(self, client: Casedev) -> None:
+ with client.connectors.v1.links.with_streaming_response.delete(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ link = response.parse()
+ assert link is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_delete(self, client: Casedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.connectors.v1.links.with_raw_response.delete(
+ id="",
+ )
+
+ @parametrize
+ def test_method_list_objects(self, client: Casedev) -> None:
+ link = client.connectors.v1.links.list_objects(
+ id="id",
+ )
+ assert link is None
+
+ @parametrize
+ def test_method_list_objects_with_all_params(self, client: Casedev) -> None:
+ link = client.connectors.v1.links.list_objects(
+ id="id",
+ cursor="cursor",
+ state="pending",
+ )
+ assert link is None
+
+ @parametrize
+ def test_raw_response_list_objects(self, client: Casedev) -> None:
+ response = client.connectors.v1.links.with_raw_response.list_objects(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ link = response.parse()
+ assert link is None
+
+ @parametrize
+ def test_streaming_response_list_objects(self, client: Casedev) -> None:
+ with client.connectors.v1.links.with_streaming_response.list_objects(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ link = response.parse()
+ assert link is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_list_objects(self, client: Casedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.connectors.v1.links.with_raw_response.list_objects(
+ id="",
+ )
+
+
+class TestAsyncLinks:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_retrieve(self, async_client: AsyncCasedev) -> None:
+ link = await async_client.connectors.v1.links.retrieve(
+ "id",
+ )
+ assert link is None
+
+ @parametrize
+ async def test_raw_response_retrieve(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.connectors.v1.links.with_raw_response.retrieve(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ link = await response.parse()
+ assert link is None
+
+ @parametrize
+ async def test_streaming_response_retrieve(self, async_client: AsyncCasedev) -> None:
+ async with async_client.connectors.v1.links.with_streaming_response.retrieve(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ link = await response.parse()
+ assert link is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_retrieve(self, async_client: AsyncCasedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.connectors.v1.links.with_raw_response.retrieve(
+ "",
+ )
+
+ @parametrize
+ async def test_method_update(self, async_client: AsyncCasedev) -> None:
+ link = await async_client.connectors.v1.links.update(
+ id="id",
+ )
+ assert link is None
+
+ @parametrize
+ async def test_method_update_with_all_params(self, async_client: AsyncCasedev) -> None:
+ link = await async_client.connectors.v1.links.update(
+ id="id",
+ mode="once",
+ policy={},
+ state="paused",
+ )
+ assert link is None
+
+ @parametrize
+ async def test_raw_response_update(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.connectors.v1.links.with_raw_response.update(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ link = await response.parse()
+ assert link is None
+
+ @parametrize
+ async def test_streaming_response_update(self, async_client: AsyncCasedev) -> None:
+ async with async_client.connectors.v1.links.with_streaming_response.update(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ link = await response.parse()
+ assert link is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_update(self, async_client: AsyncCasedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.connectors.v1.links.with_raw_response.update(
+ id="",
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncCasedev) -> None:
+ link = await async_client.connectors.v1.links.list()
+ assert link is None
+
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncCasedev) -> None:
+ link = await async_client.connectors.v1.links.list(
+ connection_id="connection_id",
+ direction="import",
+ mode="once",
+ pair_id="pair_id",
+ state="ready",
+ vault_id="vault_id",
+ )
+ assert link is None
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.connectors.v1.links.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ link = await response.parse()
+ assert link is None
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncCasedev) -> None:
+ async with async_client.connectors.v1.links.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ link = await response.parse()
+ assert link is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncCasedev) -> None:
+ link = await async_client.connectors.v1.links.delete(
+ id="id",
+ )
+ assert link is None
+
+ @parametrize
+ async def test_method_delete_with_all_params(self, async_client: AsyncCasedev) -> None:
+ link = await async_client.connectors.v1.links.delete(
+ id="id",
+ vault_docs="keep",
+ )
+ assert link is None
+
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.connectors.v1.links.with_raw_response.delete(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ link = await response.parse()
+ assert link is None
+
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncCasedev) -> None:
+ async with async_client.connectors.v1.links.with_streaming_response.delete(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ link = await response.parse()
+ assert link is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_delete(self, async_client: AsyncCasedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.connectors.v1.links.with_raw_response.delete(
+ id="",
+ )
+
+ @parametrize
+ async def test_method_list_objects(self, async_client: AsyncCasedev) -> None:
+ link = await async_client.connectors.v1.links.list_objects(
+ id="id",
+ )
+ assert link is None
+
+ @parametrize
+ async def test_method_list_objects_with_all_params(self, async_client: AsyncCasedev) -> None:
+ link = await async_client.connectors.v1.links.list_objects(
+ id="id",
+ cursor="cursor",
+ state="pending",
+ )
+ assert link is None
+
+ @parametrize
+ async def test_raw_response_list_objects(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.connectors.v1.links.with_raw_response.list_objects(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ link = await response.parse()
+ assert link is None
+
+ @parametrize
+ async def test_streaming_response_list_objects(self, async_client: AsyncCasedev) -> None:
+ async with async_client.connectors.v1.links.with_streaming_response.list_objects(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ link = await response.parse()
+ assert link is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_list_objects(self, async_client: AsyncCasedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.connectors.v1.links.with_raw_response.list_objects(
+ id="",
+ )
diff --git a/tests/api_resources/database/test_v1.py b/tests/api_resources/database/test_v1.py
deleted file mode 100644
index 61b93aac..00000000
--- a/tests/api_resources/database/test_v1.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import pytest
-
-from casedev import Casedev, AsyncCasedev
-from tests.utils import assert_matches_type
-from casedev.types.database import V1GetUsageResponse
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestV1:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @parametrize
- def test_method_get_usage(self, client: Casedev) -> None:
- v1 = client.database.v1.get_usage()
- assert_matches_type(V1GetUsageResponse, v1, path=["response"])
-
- @parametrize
- def test_raw_response_get_usage(self, client: Casedev) -> None:
- response = client.database.v1.with_raw_response.get_usage()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- v1 = response.parse()
- assert_matches_type(V1GetUsageResponse, v1, path=["response"])
-
- @parametrize
- def test_streaming_response_get_usage(self, client: Casedev) -> None:
- with client.database.v1.with_streaming_response.get_usage() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- v1 = response.parse()
- assert_matches_type(V1GetUsageResponse, v1, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
-
-class TestAsyncV1:
- parametrize = pytest.mark.parametrize(
- "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
- )
-
- @parametrize
- async def test_method_get_usage(self, async_client: AsyncCasedev) -> None:
- v1 = await async_client.database.v1.get_usage()
- assert_matches_type(V1GetUsageResponse, v1, path=["response"])
-
- @parametrize
- async def test_raw_response_get_usage(self, async_client: AsyncCasedev) -> None:
- response = await async_client.database.v1.with_raw_response.get_usage()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- v1 = await response.parse()
- assert_matches_type(V1GetUsageResponse, v1, path=["response"])
-
- @parametrize
- async def test_streaming_response_get_usage(self, async_client: AsyncCasedev) -> None:
- async with async_client.database.v1.with_streaming_response.get_usage() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- v1 = await response.parse()
- assert_matches_type(V1GetUsageResponse, v1, path=["response"])
-
- assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/database/v1/test_projects.py b/tests/api_resources/database/v1/test_projects.py
deleted file mode 100644
index 8a1d0ffe..00000000
--- a/tests/api_resources/database/v1/test_projects.py
+++ /dev/null
@@ -1,586 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import pytest
-
-from casedev import Casedev, AsyncCasedev
-from tests.utils import assert_matches_type
-from casedev.types.database.v1 import (
- ProjectListResponse,
- ProjectCreateResponse,
- ProjectDeleteResponse,
- ProjectRetrieveResponse,
- ProjectCreateBranchResponse,
- ProjectListBranchesResponse,
- ProjectGetConnectionResponse,
-)
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestProjects:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @parametrize
- def test_method_create(self, client: Casedev) -> None:
- project = client.database.v1.projects.create(
- name="litigation-docs-db",
- )
- assert_matches_type(ProjectCreateResponse, project, path=["response"])
-
- @parametrize
- def test_method_create_with_all_params(self, client: Casedev) -> None:
- project = client.database.v1.projects.create(
- name="litigation-docs-db",
- description="Production database for litigation document management",
- region="aws-us-east-1",
- )
- assert_matches_type(ProjectCreateResponse, project, path=["response"])
-
- @parametrize
- def test_raw_response_create(self, client: Casedev) -> None:
- response = client.database.v1.projects.with_raw_response.create(
- name="litigation-docs-db",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- project = response.parse()
- assert_matches_type(ProjectCreateResponse, project, path=["response"])
-
- @parametrize
- def test_streaming_response_create(self, client: Casedev) -> None:
- with client.database.v1.projects.with_streaming_response.create(
- name="litigation-docs-db",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- project = response.parse()
- assert_matches_type(ProjectCreateResponse, project, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_method_retrieve(self, client: Casedev) -> None:
- project = client.database.v1.projects.retrieve(
- "id",
- )
- assert_matches_type(ProjectRetrieveResponse, project, path=["response"])
-
- @parametrize
- def test_raw_response_retrieve(self, client: Casedev) -> None:
- response = client.database.v1.projects.with_raw_response.retrieve(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- project = response.parse()
- assert_matches_type(ProjectRetrieveResponse, project, path=["response"])
-
- @parametrize
- def test_streaming_response_retrieve(self, client: Casedev) -> None:
- with client.database.v1.projects.with_streaming_response.retrieve(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- project = response.parse()
- assert_matches_type(ProjectRetrieveResponse, project, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_retrieve(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.database.v1.projects.with_raw_response.retrieve(
- "",
- )
-
- @parametrize
- def test_method_list(self, client: Casedev) -> None:
- project = client.database.v1.projects.list()
- assert_matches_type(ProjectListResponse, project, path=["response"])
-
- @parametrize
- def test_raw_response_list(self, client: Casedev) -> None:
- response = client.database.v1.projects.with_raw_response.list()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- project = response.parse()
- assert_matches_type(ProjectListResponse, project, path=["response"])
-
- @parametrize
- def test_streaming_response_list(self, client: Casedev) -> None:
- with client.database.v1.projects.with_streaming_response.list() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- project = response.parse()
- assert_matches_type(ProjectListResponse, project, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_method_delete(self, client: Casedev) -> None:
- project = client.database.v1.projects.delete(
- "id",
- )
- assert_matches_type(ProjectDeleteResponse, project, path=["response"])
-
- @parametrize
- def test_raw_response_delete(self, client: Casedev) -> None:
- response = client.database.v1.projects.with_raw_response.delete(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- project = response.parse()
- assert_matches_type(ProjectDeleteResponse, project, path=["response"])
-
- @parametrize
- def test_streaming_response_delete(self, client: Casedev) -> None:
- with client.database.v1.projects.with_streaming_response.delete(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- project = response.parse()
- assert_matches_type(ProjectDeleteResponse, project, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_delete(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.database.v1.projects.with_raw_response.delete(
- "",
- )
-
- @parametrize
- def test_method_create_branch(self, client: Casedev) -> None:
- project = client.database.v1.projects.create_branch(
- id="id",
- name="staging",
- )
- assert_matches_type(ProjectCreateBranchResponse, project, path=["response"])
-
- @parametrize
- def test_method_create_branch_with_all_params(self, client: Casedev) -> None:
- project = client.database.v1.projects.create_branch(
- id="id",
- name="staging",
- parent_branch_id="branch_main_123",
- )
- assert_matches_type(ProjectCreateBranchResponse, project, path=["response"])
-
- @parametrize
- def test_raw_response_create_branch(self, client: Casedev) -> None:
- response = client.database.v1.projects.with_raw_response.create_branch(
- id="id",
- name="staging",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- project = response.parse()
- assert_matches_type(ProjectCreateBranchResponse, project, path=["response"])
-
- @parametrize
- def test_streaming_response_create_branch(self, client: Casedev) -> None:
- with client.database.v1.projects.with_streaming_response.create_branch(
- id="id",
- name="staging",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- project = response.parse()
- assert_matches_type(ProjectCreateBranchResponse, project, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_create_branch(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.database.v1.projects.with_raw_response.create_branch(
- id="",
- name="staging",
- )
-
- @parametrize
- def test_method_get_connection(self, client: Casedev) -> None:
- project = client.database.v1.projects.get_connection(
- id="id",
- )
- assert_matches_type(ProjectGetConnectionResponse, project, path=["response"])
-
- @parametrize
- def test_method_get_connection_with_all_params(self, client: Casedev) -> None:
- project = client.database.v1.projects.get_connection(
- id="id",
- branch="branch",
- pooled=True,
- )
- assert_matches_type(ProjectGetConnectionResponse, project, path=["response"])
-
- @parametrize
- def test_raw_response_get_connection(self, client: Casedev) -> None:
- response = client.database.v1.projects.with_raw_response.get_connection(
- id="id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- project = response.parse()
- assert_matches_type(ProjectGetConnectionResponse, project, path=["response"])
-
- @parametrize
- def test_streaming_response_get_connection(self, client: Casedev) -> None:
- with client.database.v1.projects.with_streaming_response.get_connection(
- id="id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- project = response.parse()
- assert_matches_type(ProjectGetConnectionResponse, project, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_get_connection(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.database.v1.projects.with_raw_response.get_connection(
- id="",
- )
-
- @parametrize
- def test_method_list_branches(self, client: Casedev) -> None:
- project = client.database.v1.projects.list_branches(
- "id",
- )
- assert_matches_type(ProjectListBranchesResponse, project, path=["response"])
-
- @parametrize
- def test_raw_response_list_branches(self, client: Casedev) -> None:
- response = client.database.v1.projects.with_raw_response.list_branches(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- project = response.parse()
- assert_matches_type(ProjectListBranchesResponse, project, path=["response"])
-
- @parametrize
- def test_streaming_response_list_branches(self, client: Casedev) -> None:
- with client.database.v1.projects.with_streaming_response.list_branches(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- project = response.parse()
- assert_matches_type(ProjectListBranchesResponse, project, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_list_branches(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.database.v1.projects.with_raw_response.list_branches(
- "",
- )
-
-
-class TestAsyncProjects:
- parametrize = pytest.mark.parametrize(
- "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
- )
-
- @parametrize
- async def test_method_create(self, async_client: AsyncCasedev) -> None:
- project = await async_client.database.v1.projects.create(
- name="litigation-docs-db",
- )
- assert_matches_type(ProjectCreateResponse, project, path=["response"])
-
- @parametrize
- async def test_method_create_with_all_params(self, async_client: AsyncCasedev) -> None:
- project = await async_client.database.v1.projects.create(
- name="litigation-docs-db",
- description="Production database for litigation document management",
- region="aws-us-east-1",
- )
- assert_matches_type(ProjectCreateResponse, project, path=["response"])
-
- @parametrize
- async def test_raw_response_create(self, async_client: AsyncCasedev) -> None:
- response = await async_client.database.v1.projects.with_raw_response.create(
- name="litigation-docs-db",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- project = await response.parse()
- assert_matches_type(ProjectCreateResponse, project, path=["response"])
-
- @parametrize
- async def test_streaming_response_create(self, async_client: AsyncCasedev) -> None:
- async with async_client.database.v1.projects.with_streaming_response.create(
- name="litigation-docs-db",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- project = await response.parse()
- assert_matches_type(ProjectCreateResponse, project, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_method_retrieve(self, async_client: AsyncCasedev) -> None:
- project = await async_client.database.v1.projects.retrieve(
- "id",
- )
- assert_matches_type(ProjectRetrieveResponse, project, path=["response"])
-
- @parametrize
- async def test_raw_response_retrieve(self, async_client: AsyncCasedev) -> None:
- response = await async_client.database.v1.projects.with_raw_response.retrieve(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- project = await response.parse()
- assert_matches_type(ProjectRetrieveResponse, project, path=["response"])
-
- @parametrize
- async def test_streaming_response_retrieve(self, async_client: AsyncCasedev) -> None:
- async with async_client.database.v1.projects.with_streaming_response.retrieve(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- project = await response.parse()
- assert_matches_type(ProjectRetrieveResponse, project, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_retrieve(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- await async_client.database.v1.projects.with_raw_response.retrieve(
- "",
- )
-
- @parametrize
- async def test_method_list(self, async_client: AsyncCasedev) -> None:
- project = await async_client.database.v1.projects.list()
- assert_matches_type(ProjectListResponse, project, path=["response"])
-
- @parametrize
- async def test_raw_response_list(self, async_client: AsyncCasedev) -> None:
- response = await async_client.database.v1.projects.with_raw_response.list()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- project = await response.parse()
- assert_matches_type(ProjectListResponse, project, path=["response"])
-
- @parametrize
- async def test_streaming_response_list(self, async_client: AsyncCasedev) -> None:
- async with async_client.database.v1.projects.with_streaming_response.list() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- project = await response.parse()
- assert_matches_type(ProjectListResponse, project, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_method_delete(self, async_client: AsyncCasedev) -> None:
- project = await async_client.database.v1.projects.delete(
- "id",
- )
- assert_matches_type(ProjectDeleteResponse, project, path=["response"])
-
- @parametrize
- async def test_raw_response_delete(self, async_client: AsyncCasedev) -> None:
- response = await async_client.database.v1.projects.with_raw_response.delete(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- project = await response.parse()
- assert_matches_type(ProjectDeleteResponse, project, path=["response"])
-
- @parametrize
- async def test_streaming_response_delete(self, async_client: AsyncCasedev) -> None:
- async with async_client.database.v1.projects.with_streaming_response.delete(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- project = await response.parse()
- assert_matches_type(ProjectDeleteResponse, project, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_delete(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- await async_client.database.v1.projects.with_raw_response.delete(
- "",
- )
-
- @parametrize
- async def test_method_create_branch(self, async_client: AsyncCasedev) -> None:
- project = await async_client.database.v1.projects.create_branch(
- id="id",
- name="staging",
- )
- assert_matches_type(ProjectCreateBranchResponse, project, path=["response"])
-
- @parametrize
- async def test_method_create_branch_with_all_params(self, async_client: AsyncCasedev) -> None:
- project = await async_client.database.v1.projects.create_branch(
- id="id",
- name="staging",
- parent_branch_id="branch_main_123",
- )
- assert_matches_type(ProjectCreateBranchResponse, project, path=["response"])
-
- @parametrize
- async def test_raw_response_create_branch(self, async_client: AsyncCasedev) -> None:
- response = await async_client.database.v1.projects.with_raw_response.create_branch(
- id="id",
- name="staging",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- project = await response.parse()
- assert_matches_type(ProjectCreateBranchResponse, project, path=["response"])
-
- @parametrize
- async def test_streaming_response_create_branch(self, async_client: AsyncCasedev) -> None:
- async with async_client.database.v1.projects.with_streaming_response.create_branch(
- id="id",
- name="staging",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- project = await response.parse()
- assert_matches_type(ProjectCreateBranchResponse, project, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_create_branch(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- await async_client.database.v1.projects.with_raw_response.create_branch(
- id="",
- name="staging",
- )
-
- @parametrize
- async def test_method_get_connection(self, async_client: AsyncCasedev) -> None:
- project = await async_client.database.v1.projects.get_connection(
- id="id",
- )
- assert_matches_type(ProjectGetConnectionResponse, project, path=["response"])
-
- @parametrize
- async def test_method_get_connection_with_all_params(self, async_client: AsyncCasedev) -> None:
- project = await async_client.database.v1.projects.get_connection(
- id="id",
- branch="branch",
- pooled=True,
- )
- assert_matches_type(ProjectGetConnectionResponse, project, path=["response"])
-
- @parametrize
- async def test_raw_response_get_connection(self, async_client: AsyncCasedev) -> None:
- response = await async_client.database.v1.projects.with_raw_response.get_connection(
- id="id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- project = await response.parse()
- assert_matches_type(ProjectGetConnectionResponse, project, path=["response"])
-
- @parametrize
- async def test_streaming_response_get_connection(self, async_client: AsyncCasedev) -> None:
- async with async_client.database.v1.projects.with_streaming_response.get_connection(
- id="id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- project = await response.parse()
- assert_matches_type(ProjectGetConnectionResponse, project, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_get_connection(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- await async_client.database.v1.projects.with_raw_response.get_connection(
- id="",
- )
-
- @parametrize
- async def test_method_list_branches(self, async_client: AsyncCasedev) -> None:
- project = await async_client.database.v1.projects.list_branches(
- "id",
- )
- assert_matches_type(ProjectListBranchesResponse, project, path=["response"])
-
- @parametrize
- async def test_raw_response_list_branches(self, async_client: AsyncCasedev) -> None:
- response = await async_client.database.v1.projects.with_raw_response.list_branches(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- project = await response.parse()
- assert_matches_type(ProjectListBranchesResponse, project, path=["response"])
-
- @parametrize
- async def test_streaming_response_list_branches(self, async_client: AsyncCasedev) -> None:
- async with async_client.database.v1.projects.with_streaming_response.list_branches(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- project = await response.parse()
- assert_matches_type(ProjectListBranchesResponse, project, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_list_branches(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- await async_client.database.v1.projects.with_raw_response.list_branches(
- "",
- )
diff --git a/tests/api_resources/format/test_v1.py b/tests/api_resources/format/test_v1.py
deleted file mode 100644
index 67a1690a..00000000
--- a/tests/api_resources/format/test_v1.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import httpx
-import pytest
-from respx import MockRouter
-
-from casedev import Casedev, AsyncCasedev
-from casedev._response import (
- BinaryAPIResponse,
- AsyncBinaryAPIResponse,
- StreamedBinaryAPIResponse,
- AsyncStreamedBinaryAPIResponse,
-)
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestV1:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- def test_method_create_document(self, client: Casedev, respx_mock: MockRouter) -> None:
- respx_mock.post("/format/v1/document").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- v1 = client.format.v1.create_document(
- content="content",
- output_format="pdf",
- )
- assert v1.is_closed
- assert v1.json() == {"foo": "bar"}
- assert cast(Any, v1.is_closed) is True
- assert isinstance(v1, BinaryAPIResponse)
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- def test_method_create_document_with_all_params(self, client: Casedev, respx_mock: MockRouter) -> None:
- respx_mock.post("/format/v1/document").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- v1 = client.format.v1.create_document(
- content="content",
- output_format="pdf",
- input_format="md",
- options={
- "components": [
- {
- "content": "content",
- "styles": {},
- "template_id": "templateId",
- "variables": {},
- }
- ]
- },
- )
- assert v1.is_closed
- assert v1.json() == {"foo": "bar"}
- assert cast(Any, v1.is_closed) is True
- assert isinstance(v1, BinaryAPIResponse)
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- def test_raw_response_create_document(self, client: Casedev, respx_mock: MockRouter) -> None:
- respx_mock.post("/format/v1/document").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
-
- v1 = client.format.v1.with_raw_response.create_document(
- content="content",
- output_format="pdf",
- )
-
- assert v1.is_closed is True
- assert v1.http_request.headers.get("X-Stainless-Lang") == "python"
- assert v1.json() == {"foo": "bar"}
- assert isinstance(v1, BinaryAPIResponse)
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- def test_streaming_response_create_document(self, client: Casedev, respx_mock: MockRouter) -> None:
- respx_mock.post("/format/v1/document").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- with client.format.v1.with_streaming_response.create_document(
- content="content",
- output_format="pdf",
- ) as v1:
- assert not v1.is_closed
- assert v1.http_request.headers.get("X-Stainless-Lang") == "python"
-
- assert v1.json() == {"foo": "bar"}
- assert cast(Any, v1.is_closed) is True
- assert isinstance(v1, StreamedBinaryAPIResponse)
-
- assert cast(Any, v1.is_closed) is True
-
-
-class TestAsyncV1:
- parametrize = pytest.mark.parametrize(
- "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
- )
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- async def test_method_create_document(self, async_client: AsyncCasedev, respx_mock: MockRouter) -> None:
- respx_mock.post("/format/v1/document").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- v1 = await async_client.format.v1.create_document(
- content="content",
- output_format="pdf",
- )
- assert v1.is_closed
- assert await v1.json() == {"foo": "bar"}
- assert cast(Any, v1.is_closed) is True
- assert isinstance(v1, AsyncBinaryAPIResponse)
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- async def test_method_create_document_with_all_params(
- self, async_client: AsyncCasedev, respx_mock: MockRouter
- ) -> None:
- respx_mock.post("/format/v1/document").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- v1 = await async_client.format.v1.create_document(
- content="content",
- output_format="pdf",
- input_format="md",
- options={
- "components": [
- {
- "content": "content",
- "styles": {},
- "template_id": "templateId",
- "variables": {},
- }
- ]
- },
- )
- assert v1.is_closed
- assert await v1.json() == {"foo": "bar"}
- assert cast(Any, v1.is_closed) is True
- assert isinstance(v1, AsyncBinaryAPIResponse)
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- async def test_raw_response_create_document(self, async_client: AsyncCasedev, respx_mock: MockRouter) -> None:
- respx_mock.post("/format/v1/document").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
-
- v1 = await async_client.format.v1.with_raw_response.create_document(
- content="content",
- output_format="pdf",
- )
-
- assert v1.is_closed is True
- assert v1.http_request.headers.get("X-Stainless-Lang") == "python"
- assert await v1.json() == {"foo": "bar"}
- assert isinstance(v1, AsyncBinaryAPIResponse)
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- async def test_streaming_response_create_document(self, async_client: AsyncCasedev, respx_mock: MockRouter) -> None:
- respx_mock.post("/format/v1/document").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- async with async_client.format.v1.with_streaming_response.create_document(
- content="content",
- output_format="pdf",
- ) as v1:
- assert not v1.is_closed
- assert v1.http_request.headers.get("X-Stainless-Lang") == "python"
-
- assert await v1.json() == {"foo": "bar"}
- assert cast(Any, v1.is_closed) is True
- assert isinstance(v1, AsyncStreamedBinaryAPIResponse)
-
- assert cast(Any, v1.is_closed) is True
diff --git a/tests/api_resources/format/v1/__init__.py b/tests/api_resources/format/v1/__init__.py
deleted file mode 100644
index fd8019a9..00000000
--- a/tests/api_resources/format/v1/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/format/v1/test_templates.py b/tests/api_resources/format/v1/test_templates.py
deleted file mode 100644
index 5817c69b..00000000
--- a/tests/api_resources/format/v1/test_templates.py
+++ /dev/null
@@ -1,268 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import pytest
-
-from casedev import Casedev, AsyncCasedev
-from tests.utils import assert_matches_type
-from casedev.types.format.v1 import (
- TemplateListResponse,
- TemplateCreateResponse,
- TemplateRetrieveResponse,
-)
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestTemplates:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @parametrize
- def test_method_create(self, client: Casedev) -> None:
- template = client.format.v1.templates.create(
- content="content",
- name="name",
- type="caption",
- )
- assert_matches_type(TemplateCreateResponse, template, path=["response"])
-
- @parametrize
- def test_method_create_with_all_params(self, client: Casedev) -> None:
- template = client.format.v1.templates.create(
- content="content",
- name="name",
- type="caption",
- description="description",
- styles={},
- tags=["string"],
- variables=["string"],
- )
- assert_matches_type(TemplateCreateResponse, template, path=["response"])
-
- @parametrize
- def test_raw_response_create(self, client: Casedev) -> None:
- response = client.format.v1.templates.with_raw_response.create(
- content="content",
- name="name",
- type="caption",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- template = response.parse()
- assert_matches_type(TemplateCreateResponse, template, path=["response"])
-
- @parametrize
- def test_streaming_response_create(self, client: Casedev) -> None:
- with client.format.v1.templates.with_streaming_response.create(
- content="content",
- name="name",
- type="caption",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- template = response.parse()
- assert_matches_type(TemplateCreateResponse, template, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_method_retrieve(self, client: Casedev) -> None:
- template = client.format.v1.templates.retrieve(
- "id",
- )
- assert_matches_type(TemplateRetrieveResponse, template, path=["response"])
-
- @parametrize
- def test_raw_response_retrieve(self, client: Casedev) -> None:
- response = client.format.v1.templates.with_raw_response.retrieve(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- template = response.parse()
- assert_matches_type(TemplateRetrieveResponse, template, path=["response"])
-
- @parametrize
- def test_streaming_response_retrieve(self, client: Casedev) -> None:
- with client.format.v1.templates.with_streaming_response.retrieve(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- template = response.parse()
- assert_matches_type(TemplateRetrieveResponse, template, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_retrieve(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.format.v1.templates.with_raw_response.retrieve(
- "",
- )
-
- @parametrize
- def test_method_list(self, client: Casedev) -> None:
- template = client.format.v1.templates.list()
- assert_matches_type(TemplateListResponse, template, path=["response"])
-
- @parametrize
- def test_method_list_with_all_params(self, client: Casedev) -> None:
- template = client.format.v1.templates.list(
- type="type",
- )
- assert_matches_type(TemplateListResponse, template, path=["response"])
-
- @parametrize
- def test_raw_response_list(self, client: Casedev) -> None:
- response = client.format.v1.templates.with_raw_response.list()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- template = response.parse()
- assert_matches_type(TemplateListResponse, template, path=["response"])
-
- @parametrize
- def test_streaming_response_list(self, client: Casedev) -> None:
- with client.format.v1.templates.with_streaming_response.list() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- template = response.parse()
- assert_matches_type(TemplateListResponse, template, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
-
-class TestAsyncTemplates:
- parametrize = pytest.mark.parametrize(
- "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
- )
-
- @parametrize
- async def test_method_create(self, async_client: AsyncCasedev) -> None:
- template = await async_client.format.v1.templates.create(
- content="content",
- name="name",
- type="caption",
- )
- assert_matches_type(TemplateCreateResponse, template, path=["response"])
-
- @parametrize
- async def test_method_create_with_all_params(self, async_client: AsyncCasedev) -> None:
- template = await async_client.format.v1.templates.create(
- content="content",
- name="name",
- type="caption",
- description="description",
- styles={},
- tags=["string"],
- variables=["string"],
- )
- assert_matches_type(TemplateCreateResponse, template, path=["response"])
-
- @parametrize
- async def test_raw_response_create(self, async_client: AsyncCasedev) -> None:
- response = await async_client.format.v1.templates.with_raw_response.create(
- content="content",
- name="name",
- type="caption",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- template = await response.parse()
- assert_matches_type(TemplateCreateResponse, template, path=["response"])
-
- @parametrize
- async def test_streaming_response_create(self, async_client: AsyncCasedev) -> None:
- async with async_client.format.v1.templates.with_streaming_response.create(
- content="content",
- name="name",
- type="caption",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- template = await response.parse()
- assert_matches_type(TemplateCreateResponse, template, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_method_retrieve(self, async_client: AsyncCasedev) -> None:
- template = await async_client.format.v1.templates.retrieve(
- "id",
- )
- assert_matches_type(TemplateRetrieveResponse, template, path=["response"])
-
- @parametrize
- async def test_raw_response_retrieve(self, async_client: AsyncCasedev) -> None:
- response = await async_client.format.v1.templates.with_raw_response.retrieve(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- template = await response.parse()
- assert_matches_type(TemplateRetrieveResponse, template, path=["response"])
-
- @parametrize
- async def test_streaming_response_retrieve(self, async_client: AsyncCasedev) -> None:
- async with async_client.format.v1.templates.with_streaming_response.retrieve(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- template = await response.parse()
- assert_matches_type(TemplateRetrieveResponse, template, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_retrieve(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- await async_client.format.v1.templates.with_raw_response.retrieve(
- "",
- )
-
- @parametrize
- async def test_method_list(self, async_client: AsyncCasedev) -> None:
- template = await async_client.format.v1.templates.list()
- assert_matches_type(TemplateListResponse, template, path=["response"])
-
- @parametrize
- async def test_method_list_with_all_params(self, async_client: AsyncCasedev) -> None:
- template = await async_client.format.v1.templates.list(
- type="type",
- )
- assert_matches_type(TemplateListResponse, template, path=["response"])
-
- @parametrize
- async def test_raw_response_list(self, async_client: AsyncCasedev) -> None:
- response = await async_client.format.v1.templates.with_raw_response.list()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- template = await response.parse()
- assert_matches_type(TemplateListResponse, template, path=["response"])
-
- @parametrize
- async def test_streaming_response_list(self, async_client: AsyncCasedev) -> None:
- async with async_client.format.v1.templates.with_streaming_response.list() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- template = await response.parse()
- assert_matches_type(TemplateListResponse, template, path=["response"])
-
- assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/legal/test_v1.py b/tests/api_resources/legal/test_v1.py
index c1edc410..e4e24632 100644
--- a/tests/api_resources/legal/test_v1.py
+++ b/tests/api_resources/legal/test_v1.py
@@ -12,7 +12,6 @@
from casedev._utils import parse_date
from casedev.types.legal import (
V1FindResponse,
- V1DraftResponse,
V1DocketResponse,
V1VerifyResponse,
V1SimilarResponse,
@@ -81,59 +80,6 @@ def test_streaming_response_docket(self, client: Casedev) -> None:
assert cast(Any, response.is_closed) is True
- @parametrize
- def test_method_draft(self, client: Casedev) -> None:
- v1 = client.legal.v1.draft(
- instructions="xxxxxxxxxx",
- vault_id="vault_id",
- )
- assert_matches_type(V1DraftResponse, v1, path=["response"])
-
- @parametrize
- def test_method_draft_with_all_params(self, client: Casedev) -> None:
- v1 = client.legal.v1.draft(
- instructions="xxxxxxxxxx",
- vault_id="vault_id",
- citations=True,
- format="format",
- length={
- "target": 0,
- "unit": "words",
- },
- model="model",
- object_ids=["string"],
- output_name="output_name",
- output_type="pdf",
- verified=True,
- )
- assert_matches_type(V1DraftResponse, v1, path=["response"])
-
- @parametrize
- def test_raw_response_draft(self, client: Casedev) -> None:
- response = client.legal.v1.with_raw_response.draft(
- instructions="xxxxxxxxxx",
- vault_id="vault_id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- v1 = response.parse()
- assert_matches_type(V1DraftResponse, v1, path=["response"])
-
- @parametrize
- def test_streaming_response_draft(self, client: Casedev) -> None:
- with client.legal.v1.with_streaming_response.draft(
- instructions="xxxxxxxxxx",
- vault_id="vault_id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- v1 = response.parse()
- assert_matches_type(V1DraftResponse, v1, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
@parametrize
def test_method_find(self, client: Casedev) -> None:
v1 = client.legal.v1.find(
@@ -641,59 +587,6 @@ async def test_streaming_response_docket(self, async_client: AsyncCasedev) -> No
assert cast(Any, response.is_closed) is True
- @parametrize
- async def test_method_draft(self, async_client: AsyncCasedev) -> None:
- v1 = await async_client.legal.v1.draft(
- instructions="xxxxxxxxxx",
- vault_id="vault_id",
- )
- assert_matches_type(V1DraftResponse, v1, path=["response"])
-
- @parametrize
- async def test_method_draft_with_all_params(self, async_client: AsyncCasedev) -> None:
- v1 = await async_client.legal.v1.draft(
- instructions="xxxxxxxxxx",
- vault_id="vault_id",
- citations=True,
- format="format",
- length={
- "target": 0,
- "unit": "words",
- },
- model="model",
- object_ids=["string"],
- output_name="output_name",
- output_type="pdf",
- verified=True,
- )
- assert_matches_type(V1DraftResponse, v1, path=["response"])
-
- @parametrize
- async def test_raw_response_draft(self, async_client: AsyncCasedev) -> None:
- response = await async_client.legal.v1.with_raw_response.draft(
- instructions="xxxxxxxxxx",
- vault_id="vault_id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- v1 = await response.parse()
- assert_matches_type(V1DraftResponse, v1, path=["response"])
-
- @parametrize
- async def test_streaming_response_draft(self, async_client: AsyncCasedev) -> None:
- async with async_client.legal.v1.with_streaming_response.draft(
- instructions="xxxxxxxxxx",
- vault_id="vault_id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- v1 = await response.parse()
- assert_matches_type(V1DraftResponse, v1, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
@parametrize
async def test_method_find(self, async_client: AsyncCasedev) -> None:
v1 = await async_client.legal.v1.find(
diff --git a/tests/api_resources/database/v1/__init__.py b/tests/api_resources/linc/__init__.py
similarity index 100%
rename from tests/api_resources/database/v1/__init__.py
rename to tests/api_resources/linc/__init__.py
diff --git a/tests/api_resources/format/__init__.py b/tests/api_resources/linc/v1/__init__.py
similarity index 100%
rename from tests/api_resources/format/__init__.py
rename to tests/api_resources/linc/v1/__init__.py
diff --git a/tests/api_resources/linc/v1/test_sessions.py b/tests/api_resources/linc/v1/test_sessions.py
new file mode 100644
index 00000000..be6e84c0
--- /dev/null
+++ b/tests/api_resources/linc/v1/test_sessions.py
@@ -0,0 +1,776 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from casedev import Casedev, AsyncCasedev
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestSessions:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: Casedev) -> None:
+ session = client.linc.v1.sessions.create()
+ assert session is None
+
+ @parametrize
+ def test_method_create_with_all_params(self, client: Casedev) -> None:
+ session = client.linc.v1.sessions.create(
+ document_template_slugs=["string"],
+ idle_timeout_ms=0,
+ include_document_templates=True,
+ instructions="instructions",
+ model="model",
+ scoped_api_key="scopedApiKey",
+ service_tier="default",
+ skill_slugs=["string"],
+ title="title",
+ vault_ids=["string"],
+ )
+ assert session is None
+
+ @parametrize
+ def test_raw_response_create(self, client: Casedev) -> None:
+ response = client.linc.v1.sessions.with_raw_response.create()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ session = response.parse()
+ assert session is None
+
+ @parametrize
+ def test_streaming_response_create(self, client: Casedev) -> None:
+ with client.linc.v1.sessions.with_streaming_response.create() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ session = response.parse()
+ assert session is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_delete(self, client: Casedev) -> None:
+ session = client.linc.v1.sessions.delete(
+ "id",
+ )
+ assert session is None
+
+ @parametrize
+ def test_raw_response_delete(self, client: Casedev) -> None:
+ response = client.linc.v1.sessions.with_raw_response.delete(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ session = response.parse()
+ assert session is None
+
+ @parametrize
+ def test_streaming_response_delete(self, client: Casedev) -> None:
+ with client.linc.v1.sessions.with_streaming_response.delete(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ session = response.parse()
+ assert session is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_delete(self, client: Casedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.linc.v1.sessions.with_raw_response.delete(
+ "",
+ )
+
+ @parametrize
+ def test_method_cancel(self, client: Casedev) -> None:
+ session = client.linc.v1.sessions.cancel(
+ id="id",
+ )
+ assert session is None
+
+ @parametrize
+ def test_method_cancel_with_all_params(self, client: Casedev) -> None:
+ session = client.linc.v1.sessions.cancel(
+ id="id",
+ clear_queue=True,
+ )
+ assert session is None
+
+ @parametrize
+ def test_raw_response_cancel(self, client: Casedev) -> None:
+ response = client.linc.v1.sessions.with_raw_response.cancel(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ session = response.parse()
+ assert session is None
+
+ @parametrize
+ def test_streaming_response_cancel(self, client: Casedev) -> None:
+ with client.linc.v1.sessions.with_streaming_response.cancel(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ session = response.parse()
+ assert session is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_cancel(self, client: Casedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.linc.v1.sessions.with_raw_response.cancel(
+ id="",
+ )
+
+ @parametrize
+ def test_method_ingest_events(self, client: Casedev) -> None:
+ session = client.linc.v1.sessions.ingest_events(
+ id="id",
+ frames=[
+ {
+ "event": {"foo": "bar"},
+ "seq": 1,
+ "type": "type",
+ }
+ ],
+ )
+ assert session is None
+
+ @parametrize
+ def test_raw_response_ingest_events(self, client: Casedev) -> None:
+ response = client.linc.v1.sessions.with_raw_response.ingest_events(
+ id="id",
+ frames=[
+ {
+ "event": {"foo": "bar"},
+ "seq": 1,
+ "type": "type",
+ }
+ ],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ session = response.parse()
+ assert session is None
+
+ @parametrize
+ def test_streaming_response_ingest_events(self, client: Casedev) -> None:
+ with client.linc.v1.sessions.with_streaming_response.ingest_events(
+ id="id",
+ frames=[
+ {
+ "event": {"foo": "bar"},
+ "seq": 1,
+ "type": "type",
+ }
+ ],
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ session = response.parse()
+ assert session is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_ingest_events(self, client: Casedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.linc.v1.sessions.with_raw_response.ingest_events(
+ id="",
+ frames=[
+ {
+ "event": {"foo": "bar"},
+ "seq": 1,
+ "type": "type",
+ }
+ ],
+ )
+
+ @parametrize
+ def test_method_retrieve_events(self, client: Casedev) -> None:
+ session = client.linc.v1.sessions.retrieve_events(
+ id="id",
+ )
+ assert session is None
+
+ @parametrize
+ def test_method_retrieve_events_with_all_params(self, client: Casedev) -> None:
+ session = client.linc.v1.sessions.retrieve_events(
+ id="id",
+ after_seq=0,
+ cursor=0,
+ exclude_event_types=["string"],
+ limit=1,
+ )
+ assert session is None
+
+ @parametrize
+ def test_raw_response_retrieve_events(self, client: Casedev) -> None:
+ response = client.linc.v1.sessions.with_raw_response.retrieve_events(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ session = response.parse()
+ assert session is None
+
+ @parametrize
+ def test_streaming_response_retrieve_events(self, client: Casedev) -> None:
+ with client.linc.v1.sessions.with_streaming_response.retrieve_events(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ session = response.parse()
+ assert session is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_retrieve_events(self, client: Casedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.linc.v1.sessions.with_raw_response.retrieve_events(
+ id="",
+ )
+
+ @parametrize
+ def test_method_retrieve_messages(self, client: Casedev) -> None:
+ session = client.linc.v1.sessions.retrieve_messages(
+ id="id",
+ )
+ assert session is None
+
+ @parametrize
+ def test_method_retrieve_messages_with_all_params(self, client: Casedev) -> None:
+ session = client.linc.v1.sessions.retrieve_messages(
+ id="id",
+ after_seq=0,
+ cursor=0,
+ limit=1,
+ )
+ assert session is None
+
+ @parametrize
+ def test_raw_response_retrieve_messages(self, client: Casedev) -> None:
+ response = client.linc.v1.sessions.with_raw_response.retrieve_messages(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ session = response.parse()
+ assert session is None
+
+ @parametrize
+ def test_streaming_response_retrieve_messages(self, client: Casedev) -> None:
+ with client.linc.v1.sessions.with_streaming_response.retrieve_messages(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ session = response.parse()
+ assert session is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_retrieve_messages(self, client: Casedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.linc.v1.sessions.with_raw_response.retrieve_messages(
+ id="",
+ )
+
+ @parametrize
+ def test_method_retrieve_state(self, client: Casedev) -> None:
+ session = client.linc.v1.sessions.retrieve_state(
+ "id",
+ )
+ assert session is None
+
+ @parametrize
+ def test_raw_response_retrieve_state(self, client: Casedev) -> None:
+ response = client.linc.v1.sessions.with_raw_response.retrieve_state(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ session = response.parse()
+ assert session is None
+
+ @parametrize
+ def test_streaming_response_retrieve_state(self, client: Casedev) -> None:
+ with client.linc.v1.sessions.with_streaming_response.retrieve_state(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ session = response.parse()
+ assert session is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_retrieve_state(self, client: Casedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.linc.v1.sessions.with_raw_response.retrieve_state(
+ "",
+ )
+
+ @parametrize
+ def test_method_send_rpc(self, client: Casedev) -> None:
+ session = client.linc.v1.sessions.send_rpc(
+ path_id="id",
+ type="type",
+ )
+ assert session is None
+
+ @parametrize
+ def test_method_send_rpc_with_all_params(self, client: Casedev) -> None:
+ session = client.linc.v1.sessions.send_rpc(
+ path_id="id",
+ type="type",
+ body_id="id",
+ )
+ assert session is None
+
+ @parametrize
+ def test_raw_response_send_rpc(self, client: Casedev) -> None:
+ response = client.linc.v1.sessions.with_raw_response.send_rpc(
+ path_id="id",
+ type="type",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ session = response.parse()
+ assert session is None
+
+ @parametrize
+ def test_streaming_response_send_rpc(self, client: Casedev) -> None:
+ with client.linc.v1.sessions.with_streaming_response.send_rpc(
+ path_id="id",
+ type="type",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ session = response.parse()
+ assert session is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_send_rpc(self, client: Casedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `path_id` but received ''"):
+ client.linc.v1.sessions.with_raw_response.send_rpc(
+ path_id="",
+ type="type",
+ )
+
+
+class TestAsyncSessions:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_create(self, async_client: AsyncCasedev) -> None:
+ session = await async_client.linc.v1.sessions.create()
+ assert session is None
+
+ @parametrize
+ async def test_method_create_with_all_params(self, async_client: AsyncCasedev) -> None:
+ session = await async_client.linc.v1.sessions.create(
+ document_template_slugs=["string"],
+ idle_timeout_ms=0,
+ include_document_templates=True,
+ instructions="instructions",
+ model="model",
+ scoped_api_key="scopedApiKey",
+ service_tier="default",
+ skill_slugs=["string"],
+ title="title",
+ vault_ids=["string"],
+ )
+ assert session is None
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.linc.v1.sessions.with_raw_response.create()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ session = await response.parse()
+ assert session is None
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncCasedev) -> None:
+ async with async_client.linc.v1.sessions.with_streaming_response.create() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ session = await response.parse()
+ assert session is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncCasedev) -> None:
+ session = await async_client.linc.v1.sessions.delete(
+ "id",
+ )
+ assert session is None
+
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.linc.v1.sessions.with_raw_response.delete(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ session = await response.parse()
+ assert session is None
+
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncCasedev) -> None:
+ async with async_client.linc.v1.sessions.with_streaming_response.delete(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ session = await response.parse()
+ assert session is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_delete(self, async_client: AsyncCasedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.linc.v1.sessions.with_raw_response.delete(
+ "",
+ )
+
+ @parametrize
+ async def test_method_cancel(self, async_client: AsyncCasedev) -> None:
+ session = await async_client.linc.v1.sessions.cancel(
+ id="id",
+ )
+ assert session is None
+
+ @parametrize
+ async def test_method_cancel_with_all_params(self, async_client: AsyncCasedev) -> None:
+ session = await async_client.linc.v1.sessions.cancel(
+ id="id",
+ clear_queue=True,
+ )
+ assert session is None
+
+ @parametrize
+ async def test_raw_response_cancel(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.linc.v1.sessions.with_raw_response.cancel(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ session = await response.parse()
+ assert session is None
+
+ @parametrize
+ async def test_streaming_response_cancel(self, async_client: AsyncCasedev) -> None:
+ async with async_client.linc.v1.sessions.with_streaming_response.cancel(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ session = await response.parse()
+ assert session is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_cancel(self, async_client: AsyncCasedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.linc.v1.sessions.with_raw_response.cancel(
+ id="",
+ )
+
+ @parametrize
+ async def test_method_ingest_events(self, async_client: AsyncCasedev) -> None:
+ session = await async_client.linc.v1.sessions.ingest_events(
+ id="id",
+ frames=[
+ {
+ "event": {"foo": "bar"},
+ "seq": 1,
+ "type": "type",
+ }
+ ],
+ )
+ assert session is None
+
+ @parametrize
+ async def test_raw_response_ingest_events(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.linc.v1.sessions.with_raw_response.ingest_events(
+ id="id",
+ frames=[
+ {
+ "event": {"foo": "bar"},
+ "seq": 1,
+ "type": "type",
+ }
+ ],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ session = await response.parse()
+ assert session is None
+
+ @parametrize
+ async def test_streaming_response_ingest_events(self, async_client: AsyncCasedev) -> None:
+ async with async_client.linc.v1.sessions.with_streaming_response.ingest_events(
+ id="id",
+ frames=[
+ {
+ "event": {"foo": "bar"},
+ "seq": 1,
+ "type": "type",
+ }
+ ],
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ session = await response.parse()
+ assert session is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_ingest_events(self, async_client: AsyncCasedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.linc.v1.sessions.with_raw_response.ingest_events(
+ id="",
+ frames=[
+ {
+ "event": {"foo": "bar"},
+ "seq": 1,
+ "type": "type",
+ }
+ ],
+ )
+
+ @parametrize
+ async def test_method_retrieve_events(self, async_client: AsyncCasedev) -> None:
+ session = await async_client.linc.v1.sessions.retrieve_events(
+ id="id",
+ )
+ assert session is None
+
+ @parametrize
+ async def test_method_retrieve_events_with_all_params(self, async_client: AsyncCasedev) -> None:
+ session = await async_client.linc.v1.sessions.retrieve_events(
+ id="id",
+ after_seq=0,
+ cursor=0,
+ exclude_event_types=["string"],
+ limit=1,
+ )
+ assert session is None
+
+ @parametrize
+ async def test_raw_response_retrieve_events(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.linc.v1.sessions.with_raw_response.retrieve_events(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ session = await response.parse()
+ assert session is None
+
+ @parametrize
+ async def test_streaming_response_retrieve_events(self, async_client: AsyncCasedev) -> None:
+ async with async_client.linc.v1.sessions.with_streaming_response.retrieve_events(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ session = await response.parse()
+ assert session is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_retrieve_events(self, async_client: AsyncCasedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.linc.v1.sessions.with_raw_response.retrieve_events(
+ id="",
+ )
+
+ @parametrize
+ async def test_method_retrieve_messages(self, async_client: AsyncCasedev) -> None:
+ session = await async_client.linc.v1.sessions.retrieve_messages(
+ id="id",
+ )
+ assert session is None
+
+ @parametrize
+ async def test_method_retrieve_messages_with_all_params(self, async_client: AsyncCasedev) -> None:
+ session = await async_client.linc.v1.sessions.retrieve_messages(
+ id="id",
+ after_seq=0,
+ cursor=0,
+ limit=1,
+ )
+ assert session is None
+
+ @parametrize
+ async def test_raw_response_retrieve_messages(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.linc.v1.sessions.with_raw_response.retrieve_messages(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ session = await response.parse()
+ assert session is None
+
+ @parametrize
+ async def test_streaming_response_retrieve_messages(self, async_client: AsyncCasedev) -> None:
+ async with async_client.linc.v1.sessions.with_streaming_response.retrieve_messages(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ session = await response.parse()
+ assert session is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_retrieve_messages(self, async_client: AsyncCasedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.linc.v1.sessions.with_raw_response.retrieve_messages(
+ id="",
+ )
+
+ @parametrize
+ async def test_method_retrieve_state(self, async_client: AsyncCasedev) -> None:
+ session = await async_client.linc.v1.sessions.retrieve_state(
+ "id",
+ )
+ assert session is None
+
+ @parametrize
+ async def test_raw_response_retrieve_state(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.linc.v1.sessions.with_raw_response.retrieve_state(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ session = await response.parse()
+ assert session is None
+
+ @parametrize
+ async def test_streaming_response_retrieve_state(self, async_client: AsyncCasedev) -> None:
+ async with async_client.linc.v1.sessions.with_streaming_response.retrieve_state(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ session = await response.parse()
+ assert session is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_retrieve_state(self, async_client: AsyncCasedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.linc.v1.sessions.with_raw_response.retrieve_state(
+ "",
+ )
+
+ @parametrize
+ async def test_method_send_rpc(self, async_client: AsyncCasedev) -> None:
+ session = await async_client.linc.v1.sessions.send_rpc(
+ path_id="id",
+ type="type",
+ )
+ assert session is None
+
+ @parametrize
+ async def test_method_send_rpc_with_all_params(self, async_client: AsyncCasedev) -> None:
+ session = await async_client.linc.v1.sessions.send_rpc(
+ path_id="id",
+ type="type",
+ body_id="id",
+ )
+ assert session is None
+
+ @parametrize
+ async def test_raw_response_send_rpc(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.linc.v1.sessions.with_raw_response.send_rpc(
+ path_id="id",
+ type="type",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ session = await response.parse()
+ assert session is None
+
+ @parametrize
+ async def test_streaming_response_send_rpc(self, async_client: AsyncCasedev) -> None:
+ async with async_client.linc.v1.sessions.with_streaming_response.send_rpc(
+ path_id="id",
+ type="type",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ session = await response.parse()
+ assert session is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_send_rpc(self, async_client: AsyncCasedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `path_id` but received ''"):
+ await async_client.linc.v1.sessions.with_raw_response.send_rpc(
+ path_id="",
+ type="type",
+ )
diff --git a/tests/api_resources/mail/__init__.py b/tests/api_resources/mail/__init__.py
deleted file mode 100644
index fd8019a9..00000000
--- a/tests/api_resources/mail/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/mail/v1/__init__.py b/tests/api_resources/mail/v1/__init__.py
deleted file mode 100644
index fd8019a9..00000000
--- a/tests/api_resources/mail/v1/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/mail/v1/test_inboxes.py b/tests/api_resources/mail/v1/test_inboxes.py
deleted file mode 100644
index 02cb0b7d..00000000
--- a/tests/api_resources/mail/v1/test_inboxes.py
+++ /dev/null
@@ -1,930 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import pytest
-
-from casedev import Casedev, AsyncCasedev
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestInboxes:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @parametrize
- def test_method_create(self, client: Casedev) -> None:
- inbox = client.mail.v1.inboxes.create()
- assert inbox is None
-
- @parametrize
- def test_method_create_with_all_params(self, client: Casedev) -> None:
- inbox = client.mail.v1.inboxes.create(
- address="address",
- display_name="displayName",
- )
- assert inbox is None
-
- @parametrize
- def test_raw_response_create(self, client: Casedev) -> None:
- response = client.mail.v1.inboxes.with_raw_response.create()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- inbox = response.parse()
- assert inbox is None
-
- @parametrize
- def test_streaming_response_create(self, client: Casedev) -> None:
- with client.mail.v1.inboxes.with_streaming_response.create() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- inbox = response.parse()
- assert inbox is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_method_retrieve(self, client: Casedev) -> None:
- inbox = client.mail.v1.inboxes.retrieve(
- "inboxId",
- )
- assert inbox is None
-
- @parametrize
- def test_raw_response_retrieve(self, client: Casedev) -> None:
- response = client.mail.v1.inboxes.with_raw_response.retrieve(
- "inboxId",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- inbox = response.parse()
- assert inbox is None
-
- @parametrize
- def test_streaming_response_retrieve(self, client: Casedev) -> None:
- with client.mail.v1.inboxes.with_streaming_response.retrieve(
- "inboxId",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- inbox = response.parse()
- assert inbox is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_retrieve(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `inbox_id` but received ''"):
- client.mail.v1.inboxes.with_raw_response.retrieve(
- "",
- )
-
- @parametrize
- def test_method_list(self, client: Casedev) -> None:
- inbox = client.mail.v1.inboxes.list()
- assert inbox is None
-
- @parametrize
- def test_raw_response_list(self, client: Casedev) -> None:
- response = client.mail.v1.inboxes.with_raw_response.list()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- inbox = response.parse()
- assert inbox is None
-
- @parametrize
- def test_streaming_response_list(self, client: Casedev) -> None:
- with client.mail.v1.inboxes.with_streaming_response.list() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- inbox = response.parse()
- assert inbox is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_method_delete(self, client: Casedev) -> None:
- inbox = client.mail.v1.inboxes.delete(
- "inboxId",
- )
- assert inbox is None
-
- @parametrize
- def test_raw_response_delete(self, client: Casedev) -> None:
- response = client.mail.v1.inboxes.with_raw_response.delete(
- "inboxId",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- inbox = response.parse()
- assert inbox is None
-
- @parametrize
- def test_streaming_response_delete(self, client: Casedev) -> None:
- with client.mail.v1.inboxes.with_streaming_response.delete(
- "inboxId",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- inbox = response.parse()
- assert inbox is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_delete(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `inbox_id` but received ''"):
- client.mail.v1.inboxes.with_raw_response.delete(
- "",
- )
-
- @parametrize
- def test_method_get_attachment(self, client: Casedev) -> None:
- inbox = client.mail.v1.inboxes.get_attachment(
- attachment_id="attachmentId",
- inbox_id="inboxId",
- message_id="messageId",
- )
- assert inbox is None
-
- @parametrize
- def test_raw_response_get_attachment(self, client: Casedev) -> None:
- response = client.mail.v1.inboxes.with_raw_response.get_attachment(
- attachment_id="attachmentId",
- inbox_id="inboxId",
- message_id="messageId",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- inbox = response.parse()
- assert inbox is None
-
- @parametrize
- def test_streaming_response_get_attachment(self, client: Casedev) -> None:
- with client.mail.v1.inboxes.with_streaming_response.get_attachment(
- attachment_id="attachmentId",
- inbox_id="inboxId",
- message_id="messageId",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- inbox = response.parse()
- assert inbox is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_get_attachment(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `inbox_id` but received ''"):
- client.mail.v1.inboxes.with_raw_response.get_attachment(
- attachment_id="attachmentId",
- inbox_id="",
- message_id="messageId",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_id` but received ''"):
- client.mail.v1.inboxes.with_raw_response.get_attachment(
- attachment_id="attachmentId",
- inbox_id="inboxId",
- message_id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `attachment_id` but received ''"):
- client.mail.v1.inboxes.with_raw_response.get_attachment(
- attachment_id="",
- inbox_id="inboxId",
- message_id="messageId",
- )
-
- @parametrize
- def test_method_get_message(self, client: Casedev) -> None:
- inbox = client.mail.v1.inboxes.get_message(
- message_id="messageId",
- inbox_id="inboxId",
- )
- assert inbox is None
-
- @parametrize
- def test_raw_response_get_message(self, client: Casedev) -> None:
- response = client.mail.v1.inboxes.with_raw_response.get_message(
- message_id="messageId",
- inbox_id="inboxId",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- inbox = response.parse()
- assert inbox is None
-
- @parametrize
- def test_streaming_response_get_message(self, client: Casedev) -> None:
- with client.mail.v1.inboxes.with_streaming_response.get_message(
- message_id="messageId",
- inbox_id="inboxId",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- inbox = response.parse()
- assert inbox is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_get_message(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `inbox_id` but received ''"):
- client.mail.v1.inboxes.with_raw_response.get_message(
- message_id="messageId",
- inbox_id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_id` but received ''"):
- client.mail.v1.inboxes.with_raw_response.get_message(
- message_id="",
- inbox_id="inboxId",
- )
-
- @parametrize
- def test_method_get_policy(self, client: Casedev) -> None:
- inbox = client.mail.v1.inboxes.get_policy(
- "inboxId",
- )
- assert inbox is None
-
- @parametrize
- def test_raw_response_get_policy(self, client: Casedev) -> None:
- response = client.mail.v1.inboxes.with_raw_response.get_policy(
- "inboxId",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- inbox = response.parse()
- assert inbox is None
-
- @parametrize
- def test_streaming_response_get_policy(self, client: Casedev) -> None:
- with client.mail.v1.inboxes.with_streaming_response.get_policy(
- "inboxId",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- inbox = response.parse()
- assert inbox is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_get_policy(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `inbox_id` but received ''"):
- client.mail.v1.inboxes.with_raw_response.get_policy(
- "",
- )
-
- @parametrize
- def test_method_list_messages(self, client: Casedev) -> None:
- inbox = client.mail.v1.inboxes.list_messages(
- "inboxId",
- )
- assert inbox is None
-
- @parametrize
- def test_raw_response_list_messages(self, client: Casedev) -> None:
- response = client.mail.v1.inboxes.with_raw_response.list_messages(
- "inboxId",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- inbox = response.parse()
- assert inbox is None
-
- @parametrize
- def test_streaming_response_list_messages(self, client: Casedev) -> None:
- with client.mail.v1.inboxes.with_streaming_response.list_messages(
- "inboxId",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- inbox = response.parse()
- assert inbox is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_list_messages(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `inbox_id` but received ''"):
- client.mail.v1.inboxes.with_raw_response.list_messages(
- "",
- )
-
- @parametrize
- def test_method_reply(self, client: Casedev) -> None:
- inbox = client.mail.v1.inboxes.reply(
- message_id="messageId",
- inbox_id="inboxId",
- )
- assert inbox is None
-
- @parametrize
- def test_raw_response_reply(self, client: Casedev) -> None:
- response = client.mail.v1.inboxes.with_raw_response.reply(
- message_id="messageId",
- inbox_id="inboxId",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- inbox = response.parse()
- assert inbox is None
-
- @parametrize
- def test_streaming_response_reply(self, client: Casedev) -> None:
- with client.mail.v1.inboxes.with_streaming_response.reply(
- message_id="messageId",
- inbox_id="inboxId",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- inbox = response.parse()
- assert inbox is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_reply(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `inbox_id` but received ''"):
- client.mail.v1.inboxes.with_raw_response.reply(
- message_id="messageId",
- inbox_id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_id` but received ''"):
- client.mail.v1.inboxes.with_raw_response.reply(
- message_id="",
- inbox_id="inboxId",
- )
-
- @parametrize
- def test_method_send(self, client: Casedev) -> None:
- inbox = client.mail.v1.inboxes.send(
- "inboxId",
- )
- assert inbox is None
-
- @parametrize
- def test_raw_response_send(self, client: Casedev) -> None:
- response = client.mail.v1.inboxes.with_raw_response.send(
- "inboxId",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- inbox = response.parse()
- assert inbox is None
-
- @parametrize
- def test_streaming_response_send(self, client: Casedev) -> None:
- with client.mail.v1.inboxes.with_streaming_response.send(
- "inboxId",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- inbox = response.parse()
- assert inbox is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_send(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `inbox_id` but received ''"):
- client.mail.v1.inboxes.with_raw_response.send(
- "",
- )
-
- @parametrize
- def test_method_set_policy(self, client: Casedev) -> None:
- inbox = client.mail.v1.inboxes.set_policy(
- inbox_id="inboxId",
- )
- assert inbox is None
-
- @parametrize
- def test_method_set_policy_with_all_params(self, client: Casedev) -> None:
- inbox = client.mail.v1.inboxes.set_policy(
- inbox_id="inboxId",
- allowed_sender_patterns=["string"],
- enforce_sender_allowlist=True,
- read_access_rules=["string"],
- reply_access_rules=["string"],
- send_access_rules=["string"],
- )
- assert inbox is None
-
- @parametrize
- def test_raw_response_set_policy(self, client: Casedev) -> None:
- response = client.mail.v1.inboxes.with_raw_response.set_policy(
- inbox_id="inboxId",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- inbox = response.parse()
- assert inbox is None
-
- @parametrize
- def test_streaming_response_set_policy(self, client: Casedev) -> None:
- with client.mail.v1.inboxes.with_streaming_response.set_policy(
- inbox_id="inboxId",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- inbox = response.parse()
- assert inbox is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_set_policy(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `inbox_id` but received ''"):
- client.mail.v1.inboxes.with_raw_response.set_policy(
- inbox_id="",
- )
-
-
-class TestAsyncInboxes:
- parametrize = pytest.mark.parametrize(
- "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
- )
-
- @parametrize
- async def test_method_create(self, async_client: AsyncCasedev) -> None:
- inbox = await async_client.mail.v1.inboxes.create()
- assert inbox is None
-
- @parametrize
- async def test_method_create_with_all_params(self, async_client: AsyncCasedev) -> None:
- inbox = await async_client.mail.v1.inboxes.create(
- address="address",
- display_name="displayName",
- )
- assert inbox is None
-
- @parametrize
- async def test_raw_response_create(self, async_client: AsyncCasedev) -> None:
- response = await async_client.mail.v1.inboxes.with_raw_response.create()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- inbox = await response.parse()
- assert inbox is None
-
- @parametrize
- async def test_streaming_response_create(self, async_client: AsyncCasedev) -> None:
- async with async_client.mail.v1.inboxes.with_streaming_response.create() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- inbox = await response.parse()
- assert inbox is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_method_retrieve(self, async_client: AsyncCasedev) -> None:
- inbox = await async_client.mail.v1.inboxes.retrieve(
- "inboxId",
- )
- assert inbox is None
-
- @parametrize
- async def test_raw_response_retrieve(self, async_client: AsyncCasedev) -> None:
- response = await async_client.mail.v1.inboxes.with_raw_response.retrieve(
- "inboxId",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- inbox = await response.parse()
- assert inbox is None
-
- @parametrize
- async def test_streaming_response_retrieve(self, async_client: AsyncCasedev) -> None:
- async with async_client.mail.v1.inboxes.with_streaming_response.retrieve(
- "inboxId",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- inbox = await response.parse()
- assert inbox is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_retrieve(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `inbox_id` but received ''"):
- await async_client.mail.v1.inboxes.with_raw_response.retrieve(
- "",
- )
-
- @parametrize
- async def test_method_list(self, async_client: AsyncCasedev) -> None:
- inbox = await async_client.mail.v1.inboxes.list()
- assert inbox is None
-
- @parametrize
- async def test_raw_response_list(self, async_client: AsyncCasedev) -> None:
- response = await async_client.mail.v1.inboxes.with_raw_response.list()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- inbox = await response.parse()
- assert inbox is None
-
- @parametrize
- async def test_streaming_response_list(self, async_client: AsyncCasedev) -> None:
- async with async_client.mail.v1.inboxes.with_streaming_response.list() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- inbox = await response.parse()
- assert inbox is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_method_delete(self, async_client: AsyncCasedev) -> None:
- inbox = await async_client.mail.v1.inboxes.delete(
- "inboxId",
- )
- assert inbox is None
-
- @parametrize
- async def test_raw_response_delete(self, async_client: AsyncCasedev) -> None:
- response = await async_client.mail.v1.inboxes.with_raw_response.delete(
- "inboxId",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- inbox = await response.parse()
- assert inbox is None
-
- @parametrize
- async def test_streaming_response_delete(self, async_client: AsyncCasedev) -> None:
- async with async_client.mail.v1.inboxes.with_streaming_response.delete(
- "inboxId",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- inbox = await response.parse()
- assert inbox is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_delete(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `inbox_id` but received ''"):
- await async_client.mail.v1.inboxes.with_raw_response.delete(
- "",
- )
-
- @parametrize
- async def test_method_get_attachment(self, async_client: AsyncCasedev) -> None:
- inbox = await async_client.mail.v1.inboxes.get_attachment(
- attachment_id="attachmentId",
- inbox_id="inboxId",
- message_id="messageId",
- )
- assert inbox is None
-
- @parametrize
- async def test_raw_response_get_attachment(self, async_client: AsyncCasedev) -> None:
- response = await async_client.mail.v1.inboxes.with_raw_response.get_attachment(
- attachment_id="attachmentId",
- inbox_id="inboxId",
- message_id="messageId",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- inbox = await response.parse()
- assert inbox is None
-
- @parametrize
- async def test_streaming_response_get_attachment(self, async_client: AsyncCasedev) -> None:
- async with async_client.mail.v1.inboxes.with_streaming_response.get_attachment(
- attachment_id="attachmentId",
- inbox_id="inboxId",
- message_id="messageId",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- inbox = await response.parse()
- assert inbox is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_get_attachment(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `inbox_id` but received ''"):
- await async_client.mail.v1.inboxes.with_raw_response.get_attachment(
- attachment_id="attachmentId",
- inbox_id="",
- message_id="messageId",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_id` but received ''"):
- await async_client.mail.v1.inboxes.with_raw_response.get_attachment(
- attachment_id="attachmentId",
- inbox_id="inboxId",
- message_id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `attachment_id` but received ''"):
- await async_client.mail.v1.inboxes.with_raw_response.get_attachment(
- attachment_id="",
- inbox_id="inboxId",
- message_id="messageId",
- )
-
- @parametrize
- async def test_method_get_message(self, async_client: AsyncCasedev) -> None:
- inbox = await async_client.mail.v1.inboxes.get_message(
- message_id="messageId",
- inbox_id="inboxId",
- )
- assert inbox is None
-
- @parametrize
- async def test_raw_response_get_message(self, async_client: AsyncCasedev) -> None:
- response = await async_client.mail.v1.inboxes.with_raw_response.get_message(
- message_id="messageId",
- inbox_id="inboxId",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- inbox = await response.parse()
- assert inbox is None
-
- @parametrize
- async def test_streaming_response_get_message(self, async_client: AsyncCasedev) -> None:
- async with async_client.mail.v1.inboxes.with_streaming_response.get_message(
- message_id="messageId",
- inbox_id="inboxId",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- inbox = await response.parse()
- assert inbox is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_get_message(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `inbox_id` but received ''"):
- await async_client.mail.v1.inboxes.with_raw_response.get_message(
- message_id="messageId",
- inbox_id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_id` but received ''"):
- await async_client.mail.v1.inboxes.with_raw_response.get_message(
- message_id="",
- inbox_id="inboxId",
- )
-
- @parametrize
- async def test_method_get_policy(self, async_client: AsyncCasedev) -> None:
- inbox = await async_client.mail.v1.inboxes.get_policy(
- "inboxId",
- )
- assert inbox is None
-
- @parametrize
- async def test_raw_response_get_policy(self, async_client: AsyncCasedev) -> None:
- response = await async_client.mail.v1.inboxes.with_raw_response.get_policy(
- "inboxId",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- inbox = await response.parse()
- assert inbox is None
-
- @parametrize
- async def test_streaming_response_get_policy(self, async_client: AsyncCasedev) -> None:
- async with async_client.mail.v1.inboxes.with_streaming_response.get_policy(
- "inboxId",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- inbox = await response.parse()
- assert inbox is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_get_policy(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `inbox_id` but received ''"):
- await async_client.mail.v1.inboxes.with_raw_response.get_policy(
- "",
- )
-
- @parametrize
- async def test_method_list_messages(self, async_client: AsyncCasedev) -> None:
- inbox = await async_client.mail.v1.inboxes.list_messages(
- "inboxId",
- )
- assert inbox is None
-
- @parametrize
- async def test_raw_response_list_messages(self, async_client: AsyncCasedev) -> None:
- response = await async_client.mail.v1.inboxes.with_raw_response.list_messages(
- "inboxId",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- inbox = await response.parse()
- assert inbox is None
-
- @parametrize
- async def test_streaming_response_list_messages(self, async_client: AsyncCasedev) -> None:
- async with async_client.mail.v1.inboxes.with_streaming_response.list_messages(
- "inboxId",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- inbox = await response.parse()
- assert inbox is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_list_messages(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `inbox_id` but received ''"):
- await async_client.mail.v1.inboxes.with_raw_response.list_messages(
- "",
- )
-
- @parametrize
- async def test_method_reply(self, async_client: AsyncCasedev) -> None:
- inbox = await async_client.mail.v1.inboxes.reply(
- message_id="messageId",
- inbox_id="inboxId",
- )
- assert inbox is None
-
- @parametrize
- async def test_raw_response_reply(self, async_client: AsyncCasedev) -> None:
- response = await async_client.mail.v1.inboxes.with_raw_response.reply(
- message_id="messageId",
- inbox_id="inboxId",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- inbox = await response.parse()
- assert inbox is None
-
- @parametrize
- async def test_streaming_response_reply(self, async_client: AsyncCasedev) -> None:
- async with async_client.mail.v1.inboxes.with_streaming_response.reply(
- message_id="messageId",
- inbox_id="inboxId",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- inbox = await response.parse()
- assert inbox is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_reply(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `inbox_id` but received ''"):
- await async_client.mail.v1.inboxes.with_raw_response.reply(
- message_id="messageId",
- inbox_id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `message_id` but received ''"):
- await async_client.mail.v1.inboxes.with_raw_response.reply(
- message_id="",
- inbox_id="inboxId",
- )
-
- @parametrize
- async def test_method_send(self, async_client: AsyncCasedev) -> None:
- inbox = await async_client.mail.v1.inboxes.send(
- "inboxId",
- )
- assert inbox is None
-
- @parametrize
- async def test_raw_response_send(self, async_client: AsyncCasedev) -> None:
- response = await async_client.mail.v1.inboxes.with_raw_response.send(
- "inboxId",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- inbox = await response.parse()
- assert inbox is None
-
- @parametrize
- async def test_streaming_response_send(self, async_client: AsyncCasedev) -> None:
- async with async_client.mail.v1.inboxes.with_streaming_response.send(
- "inboxId",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- inbox = await response.parse()
- assert inbox is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_send(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `inbox_id` but received ''"):
- await async_client.mail.v1.inboxes.with_raw_response.send(
- "",
- )
-
- @parametrize
- async def test_method_set_policy(self, async_client: AsyncCasedev) -> None:
- inbox = await async_client.mail.v1.inboxes.set_policy(
- inbox_id="inboxId",
- )
- assert inbox is None
-
- @parametrize
- async def test_method_set_policy_with_all_params(self, async_client: AsyncCasedev) -> None:
- inbox = await async_client.mail.v1.inboxes.set_policy(
- inbox_id="inboxId",
- allowed_sender_patterns=["string"],
- enforce_sender_allowlist=True,
- read_access_rules=["string"],
- reply_access_rules=["string"],
- send_access_rules=["string"],
- )
- assert inbox is None
-
- @parametrize
- async def test_raw_response_set_policy(self, async_client: AsyncCasedev) -> None:
- response = await async_client.mail.v1.inboxes.with_raw_response.set_policy(
- inbox_id="inboxId",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- inbox = await response.parse()
- assert inbox is None
-
- @parametrize
- async def test_streaming_response_set_policy(self, async_client: AsyncCasedev) -> None:
- async with async_client.mail.v1.inboxes.with_streaming_response.set_policy(
- inbox_id="inboxId",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- inbox = await response.parse()
- assert inbox is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_set_policy(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `inbox_id` but received ''"):
- await async_client.mail.v1.inboxes.with_raw_response.set_policy(
- inbox_id="",
- )
diff --git a/tests/api_resources/matters/v1/test_work_items.py b/tests/api_resources/matters/v1/test_work_items.py
index 8456b862..7128c0af 100644
--- a/tests/api_resources/matters/v1/test_work_items.py
+++ b/tests/api_resources/matters/v1/test_work_items.py
@@ -252,7 +252,6 @@ def test_method_decide_with_all_params(self, client: Casedev) -> None:
work_item_id="workItemId",
id="id",
decision="approve",
- agent_type_id="agent_type_id",
metadata={"foo": "bar"},
reason="reason",
)
@@ -302,54 +301,6 @@ def test_path_params_decide(self, client: Casedev) -> None:
decision="approve",
)
- @parametrize
- def test_method_list_executions(self, client: Casedev) -> None:
- work_item = client.matters.v1.work_items.list_executions(
- work_item_id="workItemId",
- id="id",
- )
- assert work_item is None
-
- @parametrize
- def test_raw_response_list_executions(self, client: Casedev) -> None:
- response = client.matters.v1.work_items.with_raw_response.list_executions(
- work_item_id="workItemId",
- id="id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- work_item = response.parse()
- assert work_item is None
-
- @parametrize
- def test_streaming_response_list_executions(self, client: Casedev) -> None:
- with client.matters.v1.work_items.with_streaming_response.list_executions(
- work_item_id="workItemId",
- id="id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- work_item = response.parse()
- assert work_item is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_list_executions(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.matters.v1.work_items.with_raw_response.list_executions(
- work_item_id="workItemId",
- id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `work_item_id` but received ''"):
- client.matters.v1.work_items.with_raw_response.list_executions(
- work_item_id="",
- id="id",
- )
-
class TestAsyncWorkItems:
parametrize = pytest.mark.parametrize(
@@ -592,7 +543,6 @@ async def test_method_decide_with_all_params(self, async_client: AsyncCasedev) -
work_item_id="workItemId",
id="id",
decision="approve",
- agent_type_id="agent_type_id",
metadata={"foo": "bar"},
reason="reason",
)
@@ -641,51 +591,3 @@ async def test_path_params_decide(self, async_client: AsyncCasedev) -> None:
id="id",
decision="approve",
)
-
- @parametrize
- async def test_method_list_executions(self, async_client: AsyncCasedev) -> None:
- work_item = await async_client.matters.v1.work_items.list_executions(
- work_item_id="workItemId",
- id="id",
- )
- assert work_item is None
-
- @parametrize
- async def test_raw_response_list_executions(self, async_client: AsyncCasedev) -> None:
- response = await async_client.matters.v1.work_items.with_raw_response.list_executions(
- work_item_id="workItemId",
- id="id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- work_item = await response.parse()
- assert work_item is None
-
- @parametrize
- async def test_streaming_response_list_executions(self, async_client: AsyncCasedev) -> None:
- async with async_client.matters.v1.work_items.with_streaming_response.list_executions(
- work_item_id="workItemId",
- id="id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- work_item = await response.parse()
- assert work_item is None
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_list_executions(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- await async_client.matters.v1.work_items.with_raw_response.list_executions(
- work_item_id="workItemId",
- id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `work_item_id` but received ''"):
- await async_client.matters.v1.work_items.with_raw_response.list_executions(
- work_item_id="",
- id="id",
- )
diff --git a/tests/api_resources/media/v1/transcripts/test_retrieve.py b/tests/api_resources/media/v1/transcripts/test_retrieve.py
new file mode 100644
index 00000000..aba332cc
--- /dev/null
+++ b/tests/api_resources/media/v1/transcripts/test_retrieve.py
@@ -0,0 +1,116 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from casedev import Casedev, AsyncCasedev
+from tests.utils import assert_matches_type
+from casedev.types.media.v1.transcripts import RetrieveCreateResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestRetrieve:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: Casedev) -> None:
+ retrieve = client.media.v1.transcripts.retrieve.create(
+ object_id="object_id",
+ vault_id="vault_id",
+ )
+ assert_matches_type(RetrieveCreateResponse, retrieve, path=["response"])
+
+ @parametrize
+ def test_method_create_with_all_params(self, client: Casedev) -> None:
+ retrieve = client.media.v1.transcripts.retrieve.create(
+ object_id="object_id",
+ vault_id="vault_id",
+ transcript={
+ "object_id": "object_id",
+ "vault_id": "vault_id",
+ },
+ )
+ assert_matches_type(RetrieveCreateResponse, retrieve, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Casedev) -> None:
+ response = client.media.v1.transcripts.retrieve.with_raw_response.create(
+ object_id="object_id",
+ vault_id="vault_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ retrieve = response.parse()
+ assert_matches_type(RetrieveCreateResponse, retrieve, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: Casedev) -> None:
+ with client.media.v1.transcripts.retrieve.with_streaming_response.create(
+ object_id="object_id",
+ vault_id="vault_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ retrieve = response.parse()
+ assert_matches_type(RetrieveCreateResponse, retrieve, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncRetrieve:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_create(self, async_client: AsyncCasedev) -> None:
+ retrieve = await async_client.media.v1.transcripts.retrieve.create(
+ object_id="object_id",
+ vault_id="vault_id",
+ )
+ assert_matches_type(RetrieveCreateResponse, retrieve, path=["response"])
+
+ @parametrize
+ async def test_method_create_with_all_params(self, async_client: AsyncCasedev) -> None:
+ retrieve = await async_client.media.v1.transcripts.retrieve.create(
+ object_id="object_id",
+ vault_id="vault_id",
+ transcript={
+ "object_id": "object_id",
+ "vault_id": "vault_id",
+ },
+ )
+ assert_matches_type(RetrieveCreateResponse, retrieve, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.media.v1.transcripts.retrieve.with_raw_response.create(
+ object_id="object_id",
+ vault_id="vault_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ retrieve = await response.parse()
+ assert_matches_type(RetrieveCreateResponse, retrieve, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncCasedev) -> None:
+ async with async_client.media.v1.transcripts.retrieve.with_streaming_response.create(
+ object_id="object_id",
+ vault_id="vault_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ retrieve = await response.parse()
+ assert_matches_type(RetrieveCreateResponse, retrieve, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/search/test_v1.py b/tests/api_resources/search/test_v1.py
index c33c4361..fa704f35 100644
--- a/tests/api_resources/search/test_v1.py
+++ b/tests/api_resources/search/test_v1.py
@@ -15,8 +15,6 @@
V1SearchResponse,
V1SimilarResponse,
V1ContentsResponse,
- V1ResearchResponse,
- V1RetrieveResearchResponse,
)
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -120,94 +118,6 @@ def test_streaming_response_contents(self, client: Casedev) -> None:
assert cast(Any, response.is_closed) is True
- @parametrize
- def test_method_research(self, client: Casedev) -> None:
- v1 = client.search.v1.research(
- instructions="instructions",
- )
- assert_matches_type(V1ResearchResponse, v1, path=["response"])
-
- @parametrize
- def test_method_research_with_all_params(self, client: Casedev) -> None:
- v1 = client.search.v1.research(
- instructions="instructions",
- model="fast",
- output_schema={},
- query="query",
- )
- assert_matches_type(V1ResearchResponse, v1, path=["response"])
-
- @parametrize
- def test_raw_response_research(self, client: Casedev) -> None:
- response = client.search.v1.with_raw_response.research(
- instructions="instructions",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- v1 = response.parse()
- assert_matches_type(V1ResearchResponse, v1, path=["response"])
-
- @parametrize
- def test_streaming_response_research(self, client: Casedev) -> None:
- with client.search.v1.with_streaming_response.research(
- instructions="instructions",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- v1 = response.parse()
- assert_matches_type(V1ResearchResponse, v1, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_method_retrieve_research(self, client: Casedev) -> None:
- v1 = client.search.v1.retrieve_research(
- id="id",
- )
- assert_matches_type(V1RetrieveResearchResponse, v1, path=["response"])
-
- @parametrize
- def test_method_retrieve_research_with_all_params(self, client: Casedev) -> None:
- v1 = client.search.v1.retrieve_research(
- id="id",
- events="events",
- stream=True,
- )
- assert_matches_type(V1RetrieveResearchResponse, v1, path=["response"])
-
- @parametrize
- def test_raw_response_retrieve_research(self, client: Casedev) -> None:
- response = client.search.v1.with_raw_response.retrieve_research(
- id="id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- v1 = response.parse()
- assert_matches_type(V1RetrieveResearchResponse, v1, path=["response"])
-
- @parametrize
- def test_streaming_response_retrieve_research(self, client: Casedev) -> None:
- with client.search.v1.with_streaming_response.retrieve_research(
- id="id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- v1 = response.parse()
- assert_matches_type(V1RetrieveResearchResponse, v1, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_retrieve_research(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.search.v1.with_raw_response.retrieve_research(
- id="",
- )
-
@parametrize
def test_method_search(self, client: Casedev) -> None:
v1 = client.search.v1.search(
@@ -407,94 +317,6 @@ async def test_streaming_response_contents(self, async_client: AsyncCasedev) ->
assert cast(Any, response.is_closed) is True
- @parametrize
- async def test_method_research(self, async_client: AsyncCasedev) -> None:
- v1 = await async_client.search.v1.research(
- instructions="instructions",
- )
- assert_matches_type(V1ResearchResponse, v1, path=["response"])
-
- @parametrize
- async def test_method_research_with_all_params(self, async_client: AsyncCasedev) -> None:
- v1 = await async_client.search.v1.research(
- instructions="instructions",
- model="fast",
- output_schema={},
- query="query",
- )
- assert_matches_type(V1ResearchResponse, v1, path=["response"])
-
- @parametrize
- async def test_raw_response_research(self, async_client: AsyncCasedev) -> None:
- response = await async_client.search.v1.with_raw_response.research(
- instructions="instructions",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- v1 = await response.parse()
- assert_matches_type(V1ResearchResponse, v1, path=["response"])
-
- @parametrize
- async def test_streaming_response_research(self, async_client: AsyncCasedev) -> None:
- async with async_client.search.v1.with_streaming_response.research(
- instructions="instructions",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- v1 = await response.parse()
- assert_matches_type(V1ResearchResponse, v1, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_method_retrieve_research(self, async_client: AsyncCasedev) -> None:
- v1 = await async_client.search.v1.retrieve_research(
- id="id",
- )
- assert_matches_type(V1RetrieveResearchResponse, v1, path=["response"])
-
- @parametrize
- async def test_method_retrieve_research_with_all_params(self, async_client: AsyncCasedev) -> None:
- v1 = await async_client.search.v1.retrieve_research(
- id="id",
- events="events",
- stream=True,
- )
- assert_matches_type(V1RetrieveResearchResponse, v1, path=["response"])
-
- @parametrize
- async def test_raw_response_retrieve_research(self, async_client: AsyncCasedev) -> None:
- response = await async_client.search.v1.with_raw_response.retrieve_research(
- id="id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- v1 = await response.parse()
- assert_matches_type(V1RetrieveResearchResponse, v1, path=["response"])
-
- @parametrize
- async def test_streaming_response_retrieve_research(self, async_client: AsyncCasedev) -> None:
- async with async_client.search.v1.with_streaming_response.retrieve_research(
- id="id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- v1 = await response.parse()
- assert_matches_type(V1RetrieveResearchResponse, v1, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_retrieve_research(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- await async_client.search.v1.with_raw_response.retrieve_research(
- id="",
- )
-
@parametrize
async def test_method_search(self, async_client: AsyncCasedev) -> None:
v1 = await async_client.search.v1.search(
diff --git a/tests/api_resources/superdoc/__init__.py b/tests/api_resources/superdoc/__init__.py
deleted file mode 100644
index fd8019a9..00000000
--- a/tests/api_resources/superdoc/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/superdoc/test_v1.py b/tests/api_resources/superdoc/test_v1.py
deleted file mode 100644
index 458417cb..00000000
--- a/tests/api_resources/superdoc/test_v1.py
+++ /dev/null
@@ -1,320 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import httpx
-import pytest
-from respx import MockRouter
-
-from casedev import Casedev, AsyncCasedev
-from casedev._response import (
- BinaryAPIResponse,
- AsyncBinaryAPIResponse,
- StreamedBinaryAPIResponse,
- AsyncStreamedBinaryAPIResponse,
-)
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestV1:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- def test_method_annotate(self, client: Casedev, respx_mock: MockRouter) -> None:
- respx_mock.post("/superdoc/v1/annotate").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- v1 = client.superdoc.v1.annotate(
- document={},
- fields=[
- {
- "type": "text",
- "value": "string",
- }
- ],
- )
- assert v1.is_closed
- assert v1.json() == {"foo": "bar"}
- assert cast(Any, v1.is_closed) is True
- assert isinstance(v1, BinaryAPIResponse)
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- def test_method_annotate_with_all_params(self, client: Casedev, respx_mock: MockRouter) -> None:
- respx_mock.post("/superdoc/v1/annotate").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- v1 = client.superdoc.v1.annotate(
- document={
- "base64": "base64",
- "url": "url",
- },
- fields=[
- {
- "type": "text",
- "value": "string",
- "id": "id",
- "group": "group",
- "options": {
- "height": 0,
- "width": 0,
- },
- }
- ],
- output_format="docx",
- )
- assert v1.is_closed
- assert v1.json() == {"foo": "bar"}
- assert cast(Any, v1.is_closed) is True
- assert isinstance(v1, BinaryAPIResponse)
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- def test_raw_response_annotate(self, client: Casedev, respx_mock: MockRouter) -> None:
- respx_mock.post("/superdoc/v1/annotate").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
-
- v1 = client.superdoc.v1.with_raw_response.annotate(
- document={},
- fields=[
- {
- "type": "text",
- "value": "string",
- }
- ],
- )
-
- assert v1.is_closed is True
- assert v1.http_request.headers.get("X-Stainless-Lang") == "python"
- assert v1.json() == {"foo": "bar"}
- assert isinstance(v1, BinaryAPIResponse)
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- def test_streaming_response_annotate(self, client: Casedev, respx_mock: MockRouter) -> None:
- respx_mock.post("/superdoc/v1/annotate").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- with client.superdoc.v1.with_streaming_response.annotate(
- document={},
- fields=[
- {
- "type": "text",
- "value": "string",
- }
- ],
- ) as v1:
- assert not v1.is_closed
- assert v1.http_request.headers.get("X-Stainless-Lang") == "python"
-
- assert v1.json() == {"foo": "bar"}
- assert cast(Any, v1.is_closed) is True
- assert isinstance(v1, StreamedBinaryAPIResponse)
-
- assert cast(Any, v1.is_closed) is True
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- def test_method_convert(self, client: Casedev, respx_mock: MockRouter) -> None:
- respx_mock.post("/superdoc/v1/convert").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- v1 = client.superdoc.v1.convert(
- from_="docx",
- )
- assert v1.is_closed
- assert v1.json() == {"foo": "bar"}
- assert cast(Any, v1.is_closed) is True
- assert isinstance(v1, BinaryAPIResponse)
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- def test_method_convert_with_all_params(self, client: Casedev, respx_mock: MockRouter) -> None:
- respx_mock.post("/superdoc/v1/convert").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- v1 = client.superdoc.v1.convert(
- from_="docx",
- document_base64="document_base64",
- document_url="document_url",
- to="pdf",
- )
- assert v1.is_closed
- assert v1.json() == {"foo": "bar"}
- assert cast(Any, v1.is_closed) is True
- assert isinstance(v1, BinaryAPIResponse)
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- def test_raw_response_convert(self, client: Casedev, respx_mock: MockRouter) -> None:
- respx_mock.post("/superdoc/v1/convert").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
-
- v1 = client.superdoc.v1.with_raw_response.convert(
- from_="docx",
- )
-
- assert v1.is_closed is True
- assert v1.http_request.headers.get("X-Stainless-Lang") == "python"
- assert v1.json() == {"foo": "bar"}
- assert isinstance(v1, BinaryAPIResponse)
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- def test_streaming_response_convert(self, client: Casedev, respx_mock: MockRouter) -> None:
- respx_mock.post("/superdoc/v1/convert").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- with client.superdoc.v1.with_streaming_response.convert(
- from_="docx",
- ) as v1:
- assert not v1.is_closed
- assert v1.http_request.headers.get("X-Stainless-Lang") == "python"
-
- assert v1.json() == {"foo": "bar"}
- assert cast(Any, v1.is_closed) is True
- assert isinstance(v1, StreamedBinaryAPIResponse)
-
- assert cast(Any, v1.is_closed) is True
-
-
-class TestAsyncV1:
- parametrize = pytest.mark.parametrize(
- "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
- )
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- async def test_method_annotate(self, async_client: AsyncCasedev, respx_mock: MockRouter) -> None:
- respx_mock.post("/superdoc/v1/annotate").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- v1 = await async_client.superdoc.v1.annotate(
- document={},
- fields=[
- {
- "type": "text",
- "value": "string",
- }
- ],
- )
- assert v1.is_closed
- assert await v1.json() == {"foo": "bar"}
- assert cast(Any, v1.is_closed) is True
- assert isinstance(v1, AsyncBinaryAPIResponse)
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- async def test_method_annotate_with_all_params(self, async_client: AsyncCasedev, respx_mock: MockRouter) -> None:
- respx_mock.post("/superdoc/v1/annotate").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- v1 = await async_client.superdoc.v1.annotate(
- document={
- "base64": "base64",
- "url": "url",
- },
- fields=[
- {
- "type": "text",
- "value": "string",
- "id": "id",
- "group": "group",
- "options": {
- "height": 0,
- "width": 0,
- },
- }
- ],
- output_format="docx",
- )
- assert v1.is_closed
- assert await v1.json() == {"foo": "bar"}
- assert cast(Any, v1.is_closed) is True
- assert isinstance(v1, AsyncBinaryAPIResponse)
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- async def test_raw_response_annotate(self, async_client: AsyncCasedev, respx_mock: MockRouter) -> None:
- respx_mock.post("/superdoc/v1/annotate").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
-
- v1 = await async_client.superdoc.v1.with_raw_response.annotate(
- document={},
- fields=[
- {
- "type": "text",
- "value": "string",
- }
- ],
- )
-
- assert v1.is_closed is True
- assert v1.http_request.headers.get("X-Stainless-Lang") == "python"
- assert await v1.json() == {"foo": "bar"}
- assert isinstance(v1, AsyncBinaryAPIResponse)
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- async def test_streaming_response_annotate(self, async_client: AsyncCasedev, respx_mock: MockRouter) -> None:
- respx_mock.post("/superdoc/v1/annotate").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- async with async_client.superdoc.v1.with_streaming_response.annotate(
- document={},
- fields=[
- {
- "type": "text",
- "value": "string",
- }
- ],
- ) as v1:
- assert not v1.is_closed
- assert v1.http_request.headers.get("X-Stainless-Lang") == "python"
-
- assert await v1.json() == {"foo": "bar"}
- assert cast(Any, v1.is_closed) is True
- assert isinstance(v1, AsyncStreamedBinaryAPIResponse)
-
- assert cast(Any, v1.is_closed) is True
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- async def test_method_convert(self, async_client: AsyncCasedev, respx_mock: MockRouter) -> None:
- respx_mock.post("/superdoc/v1/convert").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- v1 = await async_client.superdoc.v1.convert(
- from_="docx",
- )
- assert v1.is_closed
- assert await v1.json() == {"foo": "bar"}
- assert cast(Any, v1.is_closed) is True
- assert isinstance(v1, AsyncBinaryAPIResponse)
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- async def test_method_convert_with_all_params(self, async_client: AsyncCasedev, respx_mock: MockRouter) -> None:
- respx_mock.post("/superdoc/v1/convert").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- v1 = await async_client.superdoc.v1.convert(
- from_="docx",
- document_base64="document_base64",
- document_url="document_url",
- to="pdf",
- )
- assert v1.is_closed
- assert await v1.json() == {"foo": "bar"}
- assert cast(Any, v1.is_closed) is True
- assert isinstance(v1, AsyncBinaryAPIResponse)
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- async def test_raw_response_convert(self, async_client: AsyncCasedev, respx_mock: MockRouter) -> None:
- respx_mock.post("/superdoc/v1/convert").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
-
- v1 = await async_client.superdoc.v1.with_raw_response.convert(
- from_="docx",
- )
-
- assert v1.is_closed is True
- assert v1.http_request.headers.get("X-Stainless-Lang") == "python"
- assert await v1.json() == {"foo": "bar"}
- assert isinstance(v1, AsyncBinaryAPIResponse)
-
- @parametrize
- @pytest.mark.respx(base_url=base_url)
- async def test_streaming_response_convert(self, async_client: AsyncCasedev, respx_mock: MockRouter) -> None:
- respx_mock.post("/superdoc/v1/convert").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- async with async_client.superdoc.v1.with_streaming_response.convert(
- from_="docx",
- ) as v1:
- assert not v1.is_closed
- assert v1.http_request.headers.get("X-Stainless-Lang") == "python"
-
- assert await v1.json() == {"foo": "bar"}
- assert cast(Any, v1.is_closed) is True
- assert isinstance(v1, AsyncStreamedBinaryAPIResponse)
-
- assert cast(Any, v1.is_closed) is True
diff --git a/tests/api_resources/test_vault.py b/tests/api_resources/test_vault.py
index dbf210d8..704c42b5 100644
--- a/tests/api_resources/test_vault.py
+++ b/tests/api_resources/test_vault.py
@@ -233,32 +233,33 @@ def test_path_params_delete(self, client: Casedev) -> None:
)
@parametrize
- def test_method_confirm_upload_overload_1(self, client: Casedev) -> None:
+ def test_method_confirm_upload(self, client: Casedev) -> None:
vault = client.vault.confirm_upload(
object_id="objectId",
id="id",
- size_bytes=1,
success=True,
)
assert_matches_type(VaultConfirmUploadResponse, vault, path=["response"])
@parametrize
- def test_method_confirm_upload_with_all_params_overload_1(self, client: Casedev) -> None:
+ def test_method_confirm_upload_with_all_params(self, client: Casedev) -> None:
vault = client.vault.confirm_upload(
object_id="objectId",
id="id",
- size_bytes=1,
success=True,
+ auto_ingest=True,
+ error_code="errorCode",
+ error_message="errorMessage",
etag="etag",
+ size_bytes=1,
)
assert_matches_type(VaultConfirmUploadResponse, vault, path=["response"])
@parametrize
- def test_raw_response_confirm_upload_overload_1(self, client: Casedev) -> None:
+ def test_raw_response_confirm_upload(self, client: Casedev) -> None:
response = client.vault.with_raw_response.confirm_upload(
object_id="objectId",
id="id",
- size_bytes=1,
success=True,
)
@@ -268,11 +269,10 @@ def test_raw_response_confirm_upload_overload_1(self, client: Casedev) -> None:
assert_matches_type(VaultConfirmUploadResponse, vault, path=["response"])
@parametrize
- def test_streaming_response_confirm_upload_overload_1(self, client: Casedev) -> None:
+ def test_streaming_response_confirm_upload(self, client: Casedev) -> None:
with client.vault.with_streaming_response.confirm_upload(
object_id="objectId",
id="id",
- size_bytes=1,
success=True,
) as response:
assert not response.is_closed
@@ -284,12 +284,11 @@ def test_streaming_response_confirm_upload_overload_1(self, client: Casedev) ->
assert cast(Any, response.is_closed) is True
@parametrize
- def test_path_params_confirm_upload_overload_1(self, client: Casedev) -> None:
+ def test_path_params_confirm_upload(self, client: Casedev) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
client.vault.with_raw_response.confirm_upload(
object_id="objectId",
id="",
- size_bytes=1,
success=True,
)
@@ -297,73 +296,9 @@ def test_path_params_confirm_upload_overload_1(self, client: Casedev) -> None:
client.vault.with_raw_response.confirm_upload(
object_id="",
id="id",
- size_bytes=1,
success=True,
)
- @parametrize
- def test_method_confirm_upload_overload_2(self, client: Casedev) -> None:
- vault = client.vault.confirm_upload(
- object_id="objectId",
- id="id",
- error_code="errorCode",
- error_message="errorMessage",
- success=False,
- )
- assert_matches_type(VaultConfirmUploadResponse, vault, path=["response"])
-
- @parametrize
- def test_raw_response_confirm_upload_overload_2(self, client: Casedev) -> None:
- response = client.vault.with_raw_response.confirm_upload(
- object_id="objectId",
- id="id",
- error_code="errorCode",
- error_message="errorMessage",
- success=False,
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- vault = response.parse()
- assert_matches_type(VaultConfirmUploadResponse, vault, path=["response"])
-
- @parametrize
- def test_streaming_response_confirm_upload_overload_2(self, client: Casedev) -> None:
- with client.vault.with_streaming_response.confirm_upload(
- object_id="objectId",
- id="id",
- error_code="errorCode",
- error_message="errorMessage",
- success=False,
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- vault = response.parse()
- assert_matches_type(VaultConfirmUploadResponse, vault, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_confirm_upload_overload_2(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.vault.with_raw_response.confirm_upload(
- object_id="objectId",
- id="",
- error_code="errorCode",
- error_message="errorMessage",
- success=False,
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `object_id` but received ''"):
- client.vault.with_raw_response.confirm_upload(
- object_id="",
- id="id",
- error_code="errorCode",
- error_message="errorMessage",
- success=False,
- )
-
@parametrize
def test_method_ingest(self, client: Casedev) -> None:
vault = client.vault.ingest(
@@ -481,9 +416,11 @@ def test_method_upload_with_all_params(self, client: Casedev) -> None:
content_type="contentType",
filename="filename",
auto_index=True,
+ is_ai_generated=True,
metadata={},
path="path",
size_bytes=1,
+ idempotency_key="Idempotency-Key",
)
assert_matches_type(VaultUploadResponse, vault, path=["response"])
@@ -736,32 +673,33 @@ async def test_path_params_delete(self, async_client: AsyncCasedev) -> None:
)
@parametrize
- async def test_method_confirm_upload_overload_1(self, async_client: AsyncCasedev) -> None:
+ async def test_method_confirm_upload(self, async_client: AsyncCasedev) -> None:
vault = await async_client.vault.confirm_upload(
object_id="objectId",
id="id",
- size_bytes=1,
success=True,
)
assert_matches_type(VaultConfirmUploadResponse, vault, path=["response"])
@parametrize
- async def test_method_confirm_upload_with_all_params_overload_1(self, async_client: AsyncCasedev) -> None:
+ async def test_method_confirm_upload_with_all_params(self, async_client: AsyncCasedev) -> None:
vault = await async_client.vault.confirm_upload(
object_id="objectId",
id="id",
- size_bytes=1,
success=True,
+ auto_ingest=True,
+ error_code="errorCode",
+ error_message="errorMessage",
etag="etag",
+ size_bytes=1,
)
assert_matches_type(VaultConfirmUploadResponse, vault, path=["response"])
@parametrize
- async def test_raw_response_confirm_upload_overload_1(self, async_client: AsyncCasedev) -> None:
+ async def test_raw_response_confirm_upload(self, async_client: AsyncCasedev) -> None:
response = await async_client.vault.with_raw_response.confirm_upload(
object_id="objectId",
id="id",
- size_bytes=1,
success=True,
)
@@ -771,11 +709,10 @@ async def test_raw_response_confirm_upload_overload_1(self, async_client: AsyncC
assert_matches_type(VaultConfirmUploadResponse, vault, path=["response"])
@parametrize
- async def test_streaming_response_confirm_upload_overload_1(self, async_client: AsyncCasedev) -> None:
+ async def test_streaming_response_confirm_upload(self, async_client: AsyncCasedev) -> None:
async with async_client.vault.with_streaming_response.confirm_upload(
object_id="objectId",
id="id",
- size_bytes=1,
success=True,
) as response:
assert not response.is_closed
@@ -787,12 +724,11 @@ async def test_streaming_response_confirm_upload_overload_1(self, async_client:
assert cast(Any, response.is_closed) is True
@parametrize
- async def test_path_params_confirm_upload_overload_1(self, async_client: AsyncCasedev) -> None:
+ async def test_path_params_confirm_upload(self, async_client: AsyncCasedev) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
await async_client.vault.with_raw_response.confirm_upload(
object_id="objectId",
id="",
- size_bytes=1,
success=True,
)
@@ -800,73 +736,9 @@ async def test_path_params_confirm_upload_overload_1(self, async_client: AsyncCa
await async_client.vault.with_raw_response.confirm_upload(
object_id="",
id="id",
- size_bytes=1,
success=True,
)
- @parametrize
- async def test_method_confirm_upload_overload_2(self, async_client: AsyncCasedev) -> None:
- vault = await async_client.vault.confirm_upload(
- object_id="objectId",
- id="id",
- error_code="errorCode",
- error_message="errorMessage",
- success=False,
- )
- assert_matches_type(VaultConfirmUploadResponse, vault, path=["response"])
-
- @parametrize
- async def test_raw_response_confirm_upload_overload_2(self, async_client: AsyncCasedev) -> None:
- response = await async_client.vault.with_raw_response.confirm_upload(
- object_id="objectId",
- id="id",
- error_code="errorCode",
- error_message="errorMessage",
- success=False,
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- vault = await response.parse()
- assert_matches_type(VaultConfirmUploadResponse, vault, path=["response"])
-
- @parametrize
- async def test_streaming_response_confirm_upload_overload_2(self, async_client: AsyncCasedev) -> None:
- async with async_client.vault.with_streaming_response.confirm_upload(
- object_id="objectId",
- id="id",
- error_code="errorCode",
- error_message="errorMessage",
- success=False,
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- vault = await response.parse()
- assert_matches_type(VaultConfirmUploadResponse, vault, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_confirm_upload_overload_2(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- await async_client.vault.with_raw_response.confirm_upload(
- object_id="objectId",
- id="",
- error_code="errorCode",
- error_message="errorMessage",
- success=False,
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `object_id` but received ''"):
- await async_client.vault.with_raw_response.confirm_upload(
- object_id="",
- id="id",
- error_code="errorCode",
- error_message="errorMessage",
- success=False,
- )
-
@parametrize
async def test_method_ingest(self, async_client: AsyncCasedev) -> None:
vault = await async_client.vault.ingest(
@@ -984,9 +856,11 @@ async def test_method_upload_with_all_params(self, async_client: AsyncCasedev) -
content_type="contentType",
filename="filename",
auto_index=True,
+ is_ai_generated=True,
metadata={},
path="path",
size_bytes=1,
+ idempotency_key="Idempotency-Key",
)
assert_matches_type(VaultUploadResponse, vault, path=["response"])
diff --git a/tests/api_resources/translate/test_v1.py b/tests/api_resources/translate/test_v1.py
index 3af69dc8..921b8c79 100644
--- a/tests/api_resources/translate/test_v1.py
+++ b/tests/api_resources/translate/test_v1.py
@@ -5,10 +5,18 @@
import os
from typing import Any, cast
+import httpx
import pytest
+from respx import MockRouter
from casedev import Casedev, AsyncCasedev
from tests.utils import assert_matches_type
+from casedev._response import (
+ BinaryAPIResponse,
+ AsyncBinaryAPIResponse,
+ StreamedBinaryAPIResponse,
+ AsyncStreamedBinaryAPIResponse,
+)
from casedev.types.translate import (
V1DetectResponse,
V1TranslateResponse,
@@ -130,6 +138,65 @@ def test_streaming_response_translate(self, client: Casedev) -> None:
assert cast(Any, response.is_closed) is True
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_method_translate_document(self, client: Casedev, respx_mock: MockRouter) -> None:
+ respx_mock.post("/translate/v1/document").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
+ v1 = client.translate.v1.translate_document(
+ file=b"Example data",
+ target="es",
+ )
+ assert v1.is_closed
+ assert v1.json() == {"foo": "bar"}
+ assert cast(Any, v1.is_closed) is True
+ assert isinstance(v1, BinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_method_translate_document_with_all_params(self, client: Casedev, respx_mock: MockRouter) -> None:
+ respx_mock.post("/translate/v1/document").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
+ v1 = client.translate.v1.translate_document(
+ file=b"Example data",
+ target="es",
+ source="en",
+ )
+ assert v1.is_closed
+ assert v1.json() == {"foo": "bar"}
+ assert cast(Any, v1.is_closed) is True
+ assert isinstance(v1, BinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_raw_response_translate_document(self, client: Casedev, respx_mock: MockRouter) -> None:
+ respx_mock.post("/translate/v1/document").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
+
+ v1 = client.translate.v1.with_raw_response.translate_document(
+ file=b"Example data",
+ target="es",
+ )
+
+ assert v1.is_closed is True
+ assert v1.http_request.headers.get("X-Stainless-Lang") == "python"
+ assert v1.json() == {"foo": "bar"}
+ assert isinstance(v1, BinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_streaming_response_translate_document(self, client: Casedev, respx_mock: MockRouter) -> None:
+ respx_mock.post("/translate/v1/document").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
+ with client.translate.v1.with_streaming_response.translate_document(
+ file=b"Example data",
+ target="es",
+ ) as v1:
+ assert not v1.is_closed
+ assert v1.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ assert v1.json() == {"foo": "bar"}
+ assert cast(Any, v1.is_closed) is True
+ assert isinstance(v1, StreamedBinaryAPIResponse)
+
+ assert cast(Any, v1.is_closed) is True
+
class TestAsyncV1:
parametrize = pytest.mark.parametrize(
@@ -244,3 +311,66 @@ async def test_streaming_response_translate(self, async_client: AsyncCasedev) ->
assert_matches_type(V1TranslateResponse, v1, path=["response"])
assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_method_translate_document(self, async_client: AsyncCasedev, respx_mock: MockRouter) -> None:
+ respx_mock.post("/translate/v1/document").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
+ v1 = await async_client.translate.v1.translate_document(
+ file=b"Example data",
+ target="es",
+ )
+ assert v1.is_closed
+ assert await v1.json() == {"foo": "bar"}
+ assert cast(Any, v1.is_closed) is True
+ assert isinstance(v1, AsyncBinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_method_translate_document_with_all_params(
+ self, async_client: AsyncCasedev, respx_mock: MockRouter
+ ) -> None:
+ respx_mock.post("/translate/v1/document").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
+ v1 = await async_client.translate.v1.translate_document(
+ file=b"Example data",
+ target="es",
+ source="en",
+ )
+ assert v1.is_closed
+ assert await v1.json() == {"foo": "bar"}
+ assert cast(Any, v1.is_closed) is True
+ assert isinstance(v1, AsyncBinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_raw_response_translate_document(self, async_client: AsyncCasedev, respx_mock: MockRouter) -> None:
+ respx_mock.post("/translate/v1/document").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
+
+ v1 = await async_client.translate.v1.with_raw_response.translate_document(
+ file=b"Example data",
+ target="es",
+ )
+
+ assert v1.is_closed is True
+ assert v1.http_request.headers.get("X-Stainless-Lang") == "python"
+ assert await v1.json() == {"foo": "bar"}
+ assert isinstance(v1, AsyncBinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_streaming_response_translate_document(
+ self, async_client: AsyncCasedev, respx_mock: MockRouter
+ ) -> None:
+ respx_mock.post("/translate/v1/document").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
+ async with async_client.translate.v1.with_streaming_response.translate_document(
+ file=b"Example data",
+ target="es",
+ ) as v1:
+ assert not v1.is_closed
+ assert v1.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ assert await v1.json() == {"foo": "bar"}
+ assert cast(Any, v1.is_closed) is True
+ assert isinstance(v1, AsyncStreamedBinaryAPIResponse)
+
+ assert cast(Any, v1.is_closed) is True
diff --git a/tests/api_resources/usage/test_v1.py b/tests/api_resources/usage/test_v1.py
index b793596a..4ee2a1f1 100644
--- a/tests/api_resources/usage/test_v1.py
+++ b/tests/api_resources/usage/test_v1.py
@@ -25,6 +25,8 @@ def test_method_retrieve(self, client: Casedev) -> None:
def test_method_retrieve_with_all_params(self, client: Casedev) -> None:
v1 = client.usage.v1.retrieve(
granularity="summary",
+ group_by="lincSessionId",
+ linc_session_id="lincSessionId",
period_end=parse_datetime("2019-12-27T18:11:19.117Z"),
period_start=parse_datetime("2019-12-27T18:11:19.117Z"),
)
@@ -65,6 +67,8 @@ async def test_method_retrieve(self, async_client: AsyncCasedev) -> None:
async def test_method_retrieve_with_all_params(self, async_client: AsyncCasedev) -> None:
v1 = await async_client.usage.v1.retrieve(
granularity="summary",
+ group_by="lincSessionId",
+ linc_session_id="lincSessionId",
period_end=parse_datetime("2019-12-27T18:11:19.117Z"),
period_start=parse_datetime("2019-12-27T18:11:19.117Z"),
)
diff --git a/tests/api_resources/vault/test_graphrag.py b/tests/api_resources/vault/test_graphrag.py
deleted file mode 100644
index 7a36f4de..00000000
--- a/tests/api_resources/vault/test_graphrag.py
+++ /dev/null
@@ -1,272 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import pytest
-
-from casedev import Casedev, AsyncCasedev
-from tests.utils import assert_matches_type
-from casedev.types.vault import GraphragInitResponse, GraphragGetStatsResponse, GraphragProcessObjectResponse
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestGraphrag:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @parametrize
- def test_method_get_stats(self, client: Casedev) -> None:
- graphrag = client.vault.graphrag.get_stats(
- "id",
- )
- assert_matches_type(GraphragGetStatsResponse, graphrag, path=["response"])
-
- @parametrize
- def test_raw_response_get_stats(self, client: Casedev) -> None:
- response = client.vault.graphrag.with_raw_response.get_stats(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- graphrag = response.parse()
- assert_matches_type(GraphragGetStatsResponse, graphrag, path=["response"])
-
- @parametrize
- def test_streaming_response_get_stats(self, client: Casedev) -> None:
- with client.vault.graphrag.with_streaming_response.get_stats(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- graphrag = response.parse()
- assert_matches_type(GraphragGetStatsResponse, graphrag, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_get_stats(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.vault.graphrag.with_raw_response.get_stats(
- "",
- )
-
- @parametrize
- def test_method_init(self, client: Casedev) -> None:
- graphrag = client.vault.graphrag.init(
- "id",
- )
- assert_matches_type(GraphragInitResponse, graphrag, path=["response"])
-
- @parametrize
- def test_raw_response_init(self, client: Casedev) -> None:
- response = client.vault.graphrag.with_raw_response.init(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- graphrag = response.parse()
- assert_matches_type(GraphragInitResponse, graphrag, path=["response"])
-
- @parametrize
- def test_streaming_response_init(self, client: Casedev) -> None:
- with client.vault.graphrag.with_streaming_response.init(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- graphrag = response.parse()
- assert_matches_type(GraphragInitResponse, graphrag, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_init(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.vault.graphrag.with_raw_response.init(
- "",
- )
-
- @parametrize
- def test_method_process_object(self, client: Casedev) -> None:
- graphrag = client.vault.graphrag.process_object(
- object_id="objectId",
- id="id",
- )
- assert_matches_type(GraphragProcessObjectResponse, graphrag, path=["response"])
-
- @parametrize
- def test_raw_response_process_object(self, client: Casedev) -> None:
- response = client.vault.graphrag.with_raw_response.process_object(
- object_id="objectId",
- id="id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- graphrag = response.parse()
- assert_matches_type(GraphragProcessObjectResponse, graphrag, path=["response"])
-
- @parametrize
- def test_streaming_response_process_object(self, client: Casedev) -> None:
- with client.vault.graphrag.with_streaming_response.process_object(
- object_id="objectId",
- id="id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- graphrag = response.parse()
- assert_matches_type(GraphragProcessObjectResponse, graphrag, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_process_object(self, client: Casedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.vault.graphrag.with_raw_response.process_object(
- object_id="objectId",
- id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `object_id` but received ''"):
- client.vault.graphrag.with_raw_response.process_object(
- object_id="",
- id="id",
- )
-
-
-class TestAsyncGraphrag:
- parametrize = pytest.mark.parametrize(
- "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
- )
-
- @parametrize
- async def test_method_get_stats(self, async_client: AsyncCasedev) -> None:
- graphrag = await async_client.vault.graphrag.get_stats(
- "id",
- )
- assert_matches_type(GraphragGetStatsResponse, graphrag, path=["response"])
-
- @parametrize
- async def test_raw_response_get_stats(self, async_client: AsyncCasedev) -> None:
- response = await async_client.vault.graphrag.with_raw_response.get_stats(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- graphrag = await response.parse()
- assert_matches_type(GraphragGetStatsResponse, graphrag, path=["response"])
-
- @parametrize
- async def test_streaming_response_get_stats(self, async_client: AsyncCasedev) -> None:
- async with async_client.vault.graphrag.with_streaming_response.get_stats(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- graphrag = await response.parse()
- assert_matches_type(GraphragGetStatsResponse, graphrag, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_get_stats(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- await async_client.vault.graphrag.with_raw_response.get_stats(
- "",
- )
-
- @parametrize
- async def test_method_init(self, async_client: AsyncCasedev) -> None:
- graphrag = await async_client.vault.graphrag.init(
- "id",
- )
- assert_matches_type(GraphragInitResponse, graphrag, path=["response"])
-
- @parametrize
- async def test_raw_response_init(self, async_client: AsyncCasedev) -> None:
- response = await async_client.vault.graphrag.with_raw_response.init(
- "id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- graphrag = await response.parse()
- assert_matches_type(GraphragInitResponse, graphrag, path=["response"])
-
- @parametrize
- async def test_streaming_response_init(self, async_client: AsyncCasedev) -> None:
- async with async_client.vault.graphrag.with_streaming_response.init(
- "id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- graphrag = await response.parse()
- assert_matches_type(GraphragInitResponse, graphrag, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_init(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- await async_client.vault.graphrag.with_raw_response.init(
- "",
- )
-
- @parametrize
- async def test_method_process_object(self, async_client: AsyncCasedev) -> None:
- graphrag = await async_client.vault.graphrag.process_object(
- object_id="objectId",
- id="id",
- )
- assert_matches_type(GraphragProcessObjectResponse, graphrag, path=["response"])
-
- @parametrize
- async def test_raw_response_process_object(self, async_client: AsyncCasedev) -> None:
- response = await async_client.vault.graphrag.with_raw_response.process_object(
- object_id="objectId",
- id="id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- graphrag = await response.parse()
- assert_matches_type(GraphragProcessObjectResponse, graphrag, path=["response"])
-
- @parametrize
- async def test_streaming_response_process_object(self, async_client: AsyncCasedev) -> None:
- async with async_client.vault.graphrag.with_streaming_response.process_object(
- object_id="objectId",
- id="id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- graphrag = await response.parse()
- assert_matches_type(GraphragProcessObjectResponse, graphrag, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_process_object(self, async_client: AsyncCasedev) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- await async_client.vault.graphrag.with_raw_response.process_object(
- object_id="objectId",
- id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `object_id` but received ''"):
- await async_client.vault.graphrag.with_raw_response.process_object(
- object_id="",
- id="id",
- )
diff --git a/tests/api_resources/vault/test_multipart.py b/tests/api_resources/vault/test_multipart.py
index 14eac091..29e3a5d8 100644
--- a/tests/api_resources/vault/test_multipart.py
+++ b/tests/api_resources/vault/test_multipart.py
@@ -9,7 +9,10 @@
from casedev import Casedev, AsyncCasedev
from tests.utils import assert_matches_type
-from casedev.types.vault import MultipartGetPartURLsResponse
+from casedev.types.vault import (
+ MultipartInitResponse,
+ MultipartGetPartURLsResponse,
+)
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -63,6 +66,80 @@ def test_path_params_abort(self, client: Casedev) -> None:
upload_id="uploadId",
)
+ @parametrize
+ def test_method_complete(self, client: Casedev) -> None:
+ multipart = client.vault.multipart.complete(
+ id="id",
+ object_id="objectId",
+ parts=[
+ {
+ "etag": "etag",
+ "part_number": 1,
+ }
+ ],
+ size_bytes=1,
+ upload_id="uploadId",
+ )
+ assert multipart is None
+
+ @parametrize
+ def test_raw_response_complete(self, client: Casedev) -> None:
+ response = client.vault.multipart.with_raw_response.complete(
+ id="id",
+ object_id="objectId",
+ parts=[
+ {
+ "etag": "etag",
+ "part_number": 1,
+ }
+ ],
+ size_bytes=1,
+ upload_id="uploadId",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ multipart = response.parse()
+ assert multipart is None
+
+ @parametrize
+ def test_streaming_response_complete(self, client: Casedev) -> None:
+ with client.vault.multipart.with_streaming_response.complete(
+ id="id",
+ object_id="objectId",
+ parts=[
+ {
+ "etag": "etag",
+ "part_number": 1,
+ }
+ ],
+ size_bytes=1,
+ upload_id="uploadId",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ multipart = response.parse()
+ assert multipart is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_complete(self, client: Casedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.vault.multipart.with_raw_response.complete(
+ id="",
+ object_id="objectId",
+ parts=[
+ {
+ "etag": "etag",
+ "part_number": 1,
+ }
+ ],
+ size_bytes=1,
+ upload_id="uploadId",
+ )
+
@parametrize
def test_method_get_part_urls(self, client: Casedev) -> None:
multipart = client.vault.multipart.get_part_urls(
@@ -133,6 +210,71 @@ def test_path_params_get_part_urls(self, client: Casedev) -> None:
upload_id="uploadId",
)
+ @parametrize
+ def test_method_init(self, client: Casedev) -> None:
+ multipart = client.vault.multipart.init(
+ id="id",
+ content_type="contentType",
+ filename="filename",
+ size_bytes=1,
+ )
+ assert_matches_type(MultipartInitResponse, multipart, path=["response"])
+
+ @parametrize
+ def test_method_init_with_all_params(self, client: Casedev) -> None:
+ multipart = client.vault.multipart.init(
+ id="id",
+ content_type="contentType",
+ filename="filename",
+ size_bytes=1,
+ auto_index=True,
+ is_ai_generated=True,
+ metadata={},
+ part_size_bytes=5242880,
+ path="path",
+ )
+ assert_matches_type(MultipartInitResponse, multipart, path=["response"])
+
+ @parametrize
+ def test_raw_response_init(self, client: Casedev) -> None:
+ response = client.vault.multipart.with_raw_response.init(
+ id="id",
+ content_type="contentType",
+ filename="filename",
+ size_bytes=1,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ multipart = response.parse()
+ assert_matches_type(MultipartInitResponse, multipart, path=["response"])
+
+ @parametrize
+ def test_streaming_response_init(self, client: Casedev) -> None:
+ with client.vault.multipart.with_streaming_response.init(
+ id="id",
+ content_type="contentType",
+ filename="filename",
+ size_bytes=1,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ multipart = response.parse()
+ assert_matches_type(MultipartInitResponse, multipart, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_init(self, client: Casedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.vault.multipart.with_raw_response.init(
+ id="",
+ content_type="contentType",
+ filename="filename",
+ size_bytes=1,
+ )
+
class TestAsyncMultipart:
parametrize = pytest.mark.parametrize(
@@ -185,6 +327,80 @@ async def test_path_params_abort(self, async_client: AsyncCasedev) -> None:
upload_id="uploadId",
)
+ @parametrize
+ async def test_method_complete(self, async_client: AsyncCasedev) -> None:
+ multipart = await async_client.vault.multipart.complete(
+ id="id",
+ object_id="objectId",
+ parts=[
+ {
+ "etag": "etag",
+ "part_number": 1,
+ }
+ ],
+ size_bytes=1,
+ upload_id="uploadId",
+ )
+ assert multipart is None
+
+ @parametrize
+ async def test_raw_response_complete(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.vault.multipart.with_raw_response.complete(
+ id="id",
+ object_id="objectId",
+ parts=[
+ {
+ "etag": "etag",
+ "part_number": 1,
+ }
+ ],
+ size_bytes=1,
+ upload_id="uploadId",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ multipart = await response.parse()
+ assert multipart is None
+
+ @parametrize
+ async def test_streaming_response_complete(self, async_client: AsyncCasedev) -> None:
+ async with async_client.vault.multipart.with_streaming_response.complete(
+ id="id",
+ object_id="objectId",
+ parts=[
+ {
+ "etag": "etag",
+ "part_number": 1,
+ }
+ ],
+ size_bytes=1,
+ upload_id="uploadId",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ multipart = await response.parse()
+ assert multipart is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_complete(self, async_client: AsyncCasedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.vault.multipart.with_raw_response.complete(
+ id="",
+ object_id="objectId",
+ parts=[
+ {
+ "etag": "etag",
+ "part_number": 1,
+ }
+ ],
+ size_bytes=1,
+ upload_id="uploadId",
+ )
+
@parametrize
async def test_method_get_part_urls(self, async_client: AsyncCasedev) -> None:
multipart = await async_client.vault.multipart.get_part_urls(
@@ -254,3 +470,68 @@ async def test_path_params_get_part_urls(self, async_client: AsyncCasedev) -> No
],
upload_id="uploadId",
)
+
+ @parametrize
+ async def test_method_init(self, async_client: AsyncCasedev) -> None:
+ multipart = await async_client.vault.multipart.init(
+ id="id",
+ content_type="contentType",
+ filename="filename",
+ size_bytes=1,
+ )
+ assert_matches_type(MultipartInitResponse, multipart, path=["response"])
+
+ @parametrize
+ async def test_method_init_with_all_params(self, async_client: AsyncCasedev) -> None:
+ multipart = await async_client.vault.multipart.init(
+ id="id",
+ content_type="contentType",
+ filename="filename",
+ size_bytes=1,
+ auto_index=True,
+ is_ai_generated=True,
+ metadata={},
+ part_size_bytes=5242880,
+ path="path",
+ )
+ assert_matches_type(MultipartInitResponse, multipart, path=["response"])
+
+ @parametrize
+ async def test_raw_response_init(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.vault.multipart.with_raw_response.init(
+ id="id",
+ content_type="contentType",
+ filename="filename",
+ size_bytes=1,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ multipart = await response.parse()
+ assert_matches_type(MultipartInitResponse, multipart, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_init(self, async_client: AsyncCasedev) -> None:
+ async with async_client.vault.multipart.with_streaming_response.init(
+ id="id",
+ content_type="contentType",
+ filename="filename",
+ size_bytes=1,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ multipart = await response.parse()
+ assert_matches_type(MultipartInitResponse, multipart, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_init(self, async_client: AsyncCasedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.vault.multipart.with_raw_response.init(
+ id="",
+ content_type="contentType",
+ filename="filename",
+ size_bytes=1,
+ )
diff --git a/tests/api_resources/vault/test_objects.py b/tests/api_resources/vault/test_objects.py
index ddf0e8bf..d47f7070 100644
--- a/tests/api_resources/vault/test_objects.py
+++ b/tests/api_resources/vault/test_objects.py
@@ -19,6 +19,8 @@
)
from casedev.types.vault import (
ObjectListResponse,
+ ObjectMergeResponse,
+ ObjectAppendResponse,
ObjectDeleteResponse,
ObjectUpdateResponse,
ObjectGetTextResponse,
@@ -26,7 +28,6 @@
ObjectRetrieveResponse,
ObjectGetChunksResponse,
ObjectGetOcrWordsResponse,
- ObjectGetSummarizeJobResponse,
ObjectCreatePresignedURLResponse,
)
@@ -146,14 +147,22 @@ def test_path_params_update(self, client: Casedev) -> None:
@parametrize
def test_method_list(self, client: Casedev) -> None:
object_ = client.vault.objects.list(
- "id",
+ id="id",
+ )
+ assert_matches_type(ObjectListResponse, object_, path=["response"])
+
+ @parametrize
+ def test_method_list_with_all_params(self, client: Casedev) -> None:
+ object_ = client.vault.objects.list(
+ id="id",
+ include_unconfirmed=True,
)
assert_matches_type(ObjectListResponse, object_, path=["response"])
@parametrize
def test_raw_response_list(self, client: Casedev) -> None:
response = client.vault.objects.with_raw_response.list(
- "id",
+ id="id",
)
assert response.is_closed is True
@@ -164,7 +173,7 @@ def test_raw_response_list(self, client: Casedev) -> None:
@parametrize
def test_streaming_response_list(self, client: Casedev) -> None:
with client.vault.objects.with_streaming_response.list(
- "id",
+ id="id",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -178,7 +187,7 @@ def test_streaming_response_list(self, client: Casedev) -> None:
def test_path_params_list(self, client: Casedev) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
client.vault.objects.with_raw_response.list(
- "",
+ id="",
)
@parametrize
@@ -238,6 +247,78 @@ def test_path_params_delete(self, client: Casedev) -> None:
id="id",
)
+ @parametrize
+ def test_method_append(self, client: Casedev) -> None:
+ object_ = client.vault.objects.append(
+ object_id="objectId",
+ id="id",
+ append_object_ids=["string"],
+ )
+ assert_matches_type(ObjectAppendResponse, object_, path=["response"])
+
+ @parametrize
+ def test_method_append_with_all_params(self, client: Casedev) -> None:
+ object_ = client.vault.objects.append(
+ object_id="objectId",
+ id="id",
+ append_object_ids=["string"],
+ back_links=True,
+ back_links_text="backLinksText",
+ bates={
+ "enabled": True,
+ "pad_to": 0,
+ "prefix": "prefix",
+ "start": 1,
+ "suffix": "suffix",
+ },
+ rewrite_links=True,
+ )
+ assert_matches_type(ObjectAppendResponse, object_, path=["response"])
+
+ @parametrize
+ def test_raw_response_append(self, client: Casedev) -> None:
+ response = client.vault.objects.with_raw_response.append(
+ object_id="objectId",
+ id="id",
+ append_object_ids=["string"],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ object_ = response.parse()
+ assert_matches_type(ObjectAppendResponse, object_, path=["response"])
+
+ @parametrize
+ def test_streaming_response_append(self, client: Casedev) -> None:
+ with client.vault.objects.with_streaming_response.append(
+ object_id="objectId",
+ id="id",
+ append_object_ids=["string"],
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ object_ = response.parse()
+ assert_matches_type(ObjectAppendResponse, object_, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_append(self, client: Casedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.vault.objects.with_raw_response.append(
+ object_id="objectId",
+ id="",
+ append_object_ids=["string"],
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `object_id` but received ''"):
+ client.vault.objects.with_raw_response.append(
+ object_id="",
+ id="id",
+ append_object_ids=["string"],
+ )
+
@parametrize
def test_method_create_presigned_url(self, client: Casedev) -> None:
object_ = client.vault.objects.create_presigned_url(
@@ -540,111 +621,123 @@ def test_path_params_get_pages(self, client: Casedev) -> None:
)
@parametrize
- def test_method_get_summarize_job(self, client: Casedev) -> None:
- object_ = client.vault.objects.get_summarize_job(
- job_id="jobId",
- id="id",
+ def test_method_get_text(self, client: Casedev) -> None:
+ object_ = client.vault.objects.get_text(
object_id="objectId",
+ id="id",
)
- assert_matches_type(ObjectGetSummarizeJobResponse, object_, path=["response"])
+ assert_matches_type(ObjectGetTextResponse, object_, path=["response"])
@parametrize
- def test_raw_response_get_summarize_job(self, client: Casedev) -> None:
- response = client.vault.objects.with_raw_response.get_summarize_job(
- job_id="jobId",
- id="id",
+ def test_raw_response_get_text(self, client: Casedev) -> None:
+ response = client.vault.objects.with_raw_response.get_text(
object_id="objectId",
+ id="id",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
object_ = response.parse()
- assert_matches_type(ObjectGetSummarizeJobResponse, object_, path=["response"])
+ assert_matches_type(ObjectGetTextResponse, object_, path=["response"])
@parametrize
- def test_streaming_response_get_summarize_job(self, client: Casedev) -> None:
- with client.vault.objects.with_streaming_response.get_summarize_job(
- job_id="jobId",
- id="id",
+ def test_streaming_response_get_text(self, client: Casedev) -> None:
+ with client.vault.objects.with_streaming_response.get_text(
object_id="objectId",
+ id="id",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
object_ = response.parse()
- assert_matches_type(ObjectGetSummarizeJobResponse, object_, path=["response"])
+ assert_matches_type(ObjectGetTextResponse, object_, path=["response"])
assert cast(Any, response.is_closed) is True
@parametrize
- def test_path_params_get_summarize_job(self, client: Casedev) -> None:
+ def test_path_params_get_text(self, client: Casedev) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.vault.objects.with_raw_response.get_summarize_job(
- job_id="jobId",
- id="",
+ client.vault.objects.with_raw_response.get_text(
object_id="objectId",
+ id="",
)
with pytest.raises(ValueError, match=r"Expected a non-empty value for `object_id` but received ''"):
- client.vault.objects.with_raw_response.get_summarize_job(
- job_id="jobId",
- id="id",
+ client.vault.objects.with_raw_response.get_text(
object_id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `job_id` but received ''"):
- client.vault.objects.with_raw_response.get_summarize_job(
- job_id="",
id="id",
- object_id="objectId",
)
@parametrize
- def test_method_get_text(self, client: Casedev) -> None:
- object_ = client.vault.objects.get_text(
- object_id="objectId",
+ def test_method_merge(self, client: Casedev) -> None:
+ object_ = client.vault.objects.merge(
id="id",
+ filename="filename",
+ source_object_ids=["string"],
+ source_rendition="original",
+ idempotency_key="x",
)
- assert_matches_type(ObjectGetTextResponse, object_, path=["response"])
+ assert_matches_type(ObjectMergeResponse, object_, path=["response"])
+
+ @parametrize
+ def test_method_merge_with_all_params(self, client: Casedev) -> None:
+ object_ = client.vault.objects.merge(
+ id="id",
+ filename="filename",
+ source_object_ids=["string"],
+ source_rendition="original",
+ idempotency_key="x",
+ bates={
+ "pad_to": 0,
+ "prefix": "prefix",
+ "start": 1,
+ "suffix": "suffix",
+ },
+ client_reference="clientReference",
+ )
+ assert_matches_type(ObjectMergeResponse, object_, path=["response"])
@parametrize
- def test_raw_response_get_text(self, client: Casedev) -> None:
- response = client.vault.objects.with_raw_response.get_text(
- object_id="objectId",
+ def test_raw_response_merge(self, client: Casedev) -> None:
+ response = client.vault.objects.with_raw_response.merge(
id="id",
+ filename="filename",
+ source_object_ids=["string"],
+ source_rendition="original",
+ idempotency_key="x",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
object_ = response.parse()
- assert_matches_type(ObjectGetTextResponse, object_, path=["response"])
+ assert_matches_type(ObjectMergeResponse, object_, path=["response"])
@parametrize
- def test_streaming_response_get_text(self, client: Casedev) -> None:
- with client.vault.objects.with_streaming_response.get_text(
- object_id="objectId",
+ def test_streaming_response_merge(self, client: Casedev) -> None:
+ with client.vault.objects.with_streaming_response.merge(
id="id",
+ filename="filename",
+ source_object_ids=["string"],
+ source_rendition="original",
+ idempotency_key="x",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
object_ = response.parse()
- assert_matches_type(ObjectGetTextResponse, object_, path=["response"])
+ assert_matches_type(ObjectMergeResponse, object_, path=["response"])
assert cast(Any, response.is_closed) is True
@parametrize
- def test_path_params_get_text(self, client: Casedev) -> None:
+ def test_path_params_merge(self, client: Casedev) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.vault.objects.with_raw_response.get_text(
- object_id="objectId",
+ client.vault.objects.with_raw_response.merge(
id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `object_id` but received ''"):
- client.vault.objects.with_raw_response.get_text(
- object_id="",
- id="id",
+ filename="filename",
+ source_object_ids=["string"],
+ source_rendition="original",
+ idempotency_key="x",
)
@@ -763,14 +856,22 @@ async def test_path_params_update(self, async_client: AsyncCasedev) -> None:
@parametrize
async def test_method_list(self, async_client: AsyncCasedev) -> None:
object_ = await async_client.vault.objects.list(
- "id",
+ id="id",
+ )
+ assert_matches_type(ObjectListResponse, object_, path=["response"])
+
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncCasedev) -> None:
+ object_ = await async_client.vault.objects.list(
+ id="id",
+ include_unconfirmed=True,
)
assert_matches_type(ObjectListResponse, object_, path=["response"])
@parametrize
async def test_raw_response_list(self, async_client: AsyncCasedev) -> None:
response = await async_client.vault.objects.with_raw_response.list(
- "id",
+ id="id",
)
assert response.is_closed is True
@@ -781,7 +882,7 @@ async def test_raw_response_list(self, async_client: AsyncCasedev) -> None:
@parametrize
async def test_streaming_response_list(self, async_client: AsyncCasedev) -> None:
async with async_client.vault.objects.with_streaming_response.list(
- "id",
+ id="id",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -795,7 +896,7 @@ async def test_streaming_response_list(self, async_client: AsyncCasedev) -> None
async def test_path_params_list(self, async_client: AsyncCasedev) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
await async_client.vault.objects.with_raw_response.list(
- "",
+ id="",
)
@parametrize
@@ -855,6 +956,78 @@ async def test_path_params_delete(self, async_client: AsyncCasedev) -> None:
id="id",
)
+ @parametrize
+ async def test_method_append(self, async_client: AsyncCasedev) -> None:
+ object_ = await async_client.vault.objects.append(
+ object_id="objectId",
+ id="id",
+ append_object_ids=["string"],
+ )
+ assert_matches_type(ObjectAppendResponse, object_, path=["response"])
+
+ @parametrize
+ async def test_method_append_with_all_params(self, async_client: AsyncCasedev) -> None:
+ object_ = await async_client.vault.objects.append(
+ object_id="objectId",
+ id="id",
+ append_object_ids=["string"],
+ back_links=True,
+ back_links_text="backLinksText",
+ bates={
+ "enabled": True,
+ "pad_to": 0,
+ "prefix": "prefix",
+ "start": 1,
+ "suffix": "suffix",
+ },
+ rewrite_links=True,
+ )
+ assert_matches_type(ObjectAppendResponse, object_, path=["response"])
+
+ @parametrize
+ async def test_raw_response_append(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.vault.objects.with_raw_response.append(
+ object_id="objectId",
+ id="id",
+ append_object_ids=["string"],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ object_ = await response.parse()
+ assert_matches_type(ObjectAppendResponse, object_, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_append(self, async_client: AsyncCasedev) -> None:
+ async with async_client.vault.objects.with_streaming_response.append(
+ object_id="objectId",
+ id="id",
+ append_object_ids=["string"],
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ object_ = await response.parse()
+ assert_matches_type(ObjectAppendResponse, object_, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_append(self, async_client: AsyncCasedev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.vault.objects.with_raw_response.append(
+ object_id="objectId",
+ id="",
+ append_object_ids=["string"],
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `object_id` but received ''"):
+ await async_client.vault.objects.with_raw_response.append(
+ object_id="",
+ id="id",
+ append_object_ids=["string"],
+ )
+
@parametrize
async def test_method_create_presigned_url(self, async_client: AsyncCasedev) -> None:
object_ = await async_client.vault.objects.create_presigned_url(
@@ -1157,109 +1330,121 @@ async def test_path_params_get_pages(self, async_client: AsyncCasedev) -> None:
)
@parametrize
- async def test_method_get_summarize_job(self, async_client: AsyncCasedev) -> None:
- object_ = await async_client.vault.objects.get_summarize_job(
- job_id="jobId",
- id="id",
+ async def test_method_get_text(self, async_client: AsyncCasedev) -> None:
+ object_ = await async_client.vault.objects.get_text(
object_id="objectId",
+ id="id",
)
- assert_matches_type(ObjectGetSummarizeJobResponse, object_, path=["response"])
+ assert_matches_type(ObjectGetTextResponse, object_, path=["response"])
@parametrize
- async def test_raw_response_get_summarize_job(self, async_client: AsyncCasedev) -> None:
- response = await async_client.vault.objects.with_raw_response.get_summarize_job(
- job_id="jobId",
- id="id",
+ async def test_raw_response_get_text(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.vault.objects.with_raw_response.get_text(
object_id="objectId",
+ id="id",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
object_ = await response.parse()
- assert_matches_type(ObjectGetSummarizeJobResponse, object_, path=["response"])
+ assert_matches_type(ObjectGetTextResponse, object_, path=["response"])
@parametrize
- async def test_streaming_response_get_summarize_job(self, async_client: AsyncCasedev) -> None:
- async with async_client.vault.objects.with_streaming_response.get_summarize_job(
- job_id="jobId",
- id="id",
+ async def test_streaming_response_get_text(self, async_client: AsyncCasedev) -> None:
+ async with async_client.vault.objects.with_streaming_response.get_text(
object_id="objectId",
+ id="id",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
object_ = await response.parse()
- assert_matches_type(ObjectGetSummarizeJobResponse, object_, path=["response"])
+ assert_matches_type(ObjectGetTextResponse, object_, path=["response"])
assert cast(Any, response.is_closed) is True
@parametrize
- async def test_path_params_get_summarize_job(self, async_client: AsyncCasedev) -> None:
+ async def test_path_params_get_text(self, async_client: AsyncCasedev) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- await async_client.vault.objects.with_raw_response.get_summarize_job(
- job_id="jobId",
- id="",
+ await async_client.vault.objects.with_raw_response.get_text(
object_id="objectId",
+ id="",
)
with pytest.raises(ValueError, match=r"Expected a non-empty value for `object_id` but received ''"):
- await async_client.vault.objects.with_raw_response.get_summarize_job(
- job_id="jobId",
- id="id",
+ await async_client.vault.objects.with_raw_response.get_text(
object_id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `job_id` but received ''"):
- await async_client.vault.objects.with_raw_response.get_summarize_job(
- job_id="",
id="id",
- object_id="objectId",
)
@parametrize
- async def test_method_get_text(self, async_client: AsyncCasedev) -> None:
- object_ = await async_client.vault.objects.get_text(
- object_id="objectId",
+ async def test_method_merge(self, async_client: AsyncCasedev) -> None:
+ object_ = await async_client.vault.objects.merge(
id="id",
+ filename="filename",
+ source_object_ids=["string"],
+ source_rendition="original",
+ idempotency_key="x",
)
- assert_matches_type(ObjectGetTextResponse, object_, path=["response"])
+ assert_matches_type(ObjectMergeResponse, object_, path=["response"])
+
+ @parametrize
+ async def test_method_merge_with_all_params(self, async_client: AsyncCasedev) -> None:
+ object_ = await async_client.vault.objects.merge(
+ id="id",
+ filename="filename",
+ source_object_ids=["string"],
+ source_rendition="original",
+ idempotency_key="x",
+ bates={
+ "pad_to": 0,
+ "prefix": "prefix",
+ "start": 1,
+ "suffix": "suffix",
+ },
+ client_reference="clientReference",
+ )
+ assert_matches_type(ObjectMergeResponse, object_, path=["response"])
@parametrize
- async def test_raw_response_get_text(self, async_client: AsyncCasedev) -> None:
- response = await async_client.vault.objects.with_raw_response.get_text(
- object_id="objectId",
+ async def test_raw_response_merge(self, async_client: AsyncCasedev) -> None:
+ response = await async_client.vault.objects.with_raw_response.merge(
id="id",
+ filename="filename",
+ source_object_ids=["string"],
+ source_rendition="original",
+ idempotency_key="x",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
object_ = await response.parse()
- assert_matches_type(ObjectGetTextResponse, object_, path=["response"])
+ assert_matches_type(ObjectMergeResponse, object_, path=["response"])
@parametrize
- async def test_streaming_response_get_text(self, async_client: AsyncCasedev) -> None:
- async with async_client.vault.objects.with_streaming_response.get_text(
- object_id="objectId",
+ async def test_streaming_response_merge(self, async_client: AsyncCasedev) -> None:
+ async with async_client.vault.objects.with_streaming_response.merge(
id="id",
+ filename="filename",
+ source_object_ids=["string"],
+ source_rendition="original",
+ idempotency_key="x",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
object_ = await response.parse()
- assert_matches_type(ObjectGetTextResponse, object_, path=["response"])
+ assert_matches_type(ObjectMergeResponse, object_, path=["response"])
assert cast(Any, response.is_closed) is True
@parametrize
- async def test_path_params_get_text(self, async_client: AsyncCasedev) -> None:
+ async def test_path_params_merge(self, async_client: AsyncCasedev) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- await async_client.vault.objects.with_raw_response.get_text(
- object_id="objectId",
+ await async_client.vault.objects.with_raw_response.merge(
id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `object_id` but received ''"):
- await async_client.vault.objects.with_raw_response.get_text(
- object_id="",
- id="id",
+ filename="filename",
+ source_object_ids=["string"],
+ source_rendition="original",
+ idempotency_key="x",
)