Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
55ba10d
feat: Add comprehensive Oracle Cloud Infrastructure (OCI) client support
fede-kamel Jan 26, 2026
0fa14f0
fix: Correct OCI client request signing and response transformation
fede-kamel Jan 26, 2026
aa05c33
feat: Add V2 API support for OCI with Command A models
fede-kamel Jan 26, 2026
8cf06de
style: Fix ruff linting issues in OCI client
fede-kamel Jan 26, 2026
f7edabd
chore: Remove temporary development summary files
fede-kamel Jan 26, 2026
90b3295
fix: Address OCI pip extras installation and streaming [DONE] signal …
fede-kamel Jan 26, 2026
4ec13e6
feat: Add OCI session-based (security token) authentication support
fede-kamel Jan 26, 2026
6b483e1
docs: Add session-based authentication to OCI documentation
fede-kamel Jan 26, 2026
836b6dc
fix: Replace httpx.Headers object instead of updating it for OCI sign…
fede-kamel Jan 26, 2026
6753582
Fix OCI client V2 support and address copilot issues
fede-kamel Jan 26, 2026
e924300
docs: Add OCI model availability limitations and improve docstrings
fede-kamel Jan 26, 2026
ce147f9
fix: Address PR feedback - V2 detection and security token path expan…
fede-kamel Jan 26, 2026
ed7e6e4
fix: Address PR feedback for OCI client
fede-kamel Jan 26, 2026
1fd94dc
feat: Add thinking parameter support for Command A Reasoning models
fede-kamel Feb 4, 2026
690ca72
Address cursor[bot] review feedback for OCI client
fede-kamel Feb 6, 2026
473e9b9
Fix token_budget casing and add toolCalls conversion
fede-kamel Feb 6, 2026
de0ec71
fix: Use UUID for generation_id instead of modelId
fede-kamel Feb 24, 2026
d35cb22
fix: Address Bugbot feedback for OCI client
fede-kamel Feb 24, 2026
ab99ad9
fix(oci): align auth and v2 request handling
fede-kamel Mar 14, 2026
72cdabe
test(oci): cover auth mapping and stream behavior
fede-kamel Mar 14, 2026
ffa62a1
fix(oci): tighten mixed v1 v2 stream coverage
fede-kamel Mar 14, 2026
0e0b3b3
fix(oci): preserve v1 stream end finish reason
fede-kamel Mar 15, 2026
72504a3
test(oci): skip embed-light when region lacks model
fede-kamel Mar 15, 2026
8bc5f5d
test(oci): stub httpx_sse in unit bootstrap
fede-kamel Mar 15, 2026
9f1e924
fix(oci): resolve remaining stream and usage edge cases
fede-kamel Mar 15, 2026
687ef1e
fix(oci): always populate billed units from OCI usage
fede-kamel Mar 15, 2026
1b658bd
fix(oci): close remaining review gaps
fede-kamel Mar 16, 2026
80ed0d7
test(oci): remove unsupported live scenarios
fede-kamel Mar 16, 2026
14b5c6e
fix(oci): keep fallback stream index in sync
fede-kamel Mar 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,111 @@ for event in response:
print(event.delta.message.content.text, end="")
```

## Oracle Cloud Infrastructure (OCI)

The SDK supports Oracle Cloud Infrastructure (OCI) Generative AI service. First, install the OCI SDK:

```
pip install 'cohere[oci]'
```

Then use the `OciClient` or `OciClientV2`:

```Python
import cohere

# Using OCI config file authentication (default: ~/.oci/config)
co = cohere.OciClient(
oci_region="us-chicago-1",
oci_compartment_id="ocid1.compartment.oc1...",
)

response = co.embed(
model="embed-english-v3.0",
texts=["Hello world"],
input_type="search_document",
)

print(response.embeddings)
```

### OCI Authentication Methods

**1. Config File (Default)**
```Python
co = cohere.OciClient(
oci_region="us-chicago-1",
oci_compartment_id="ocid1.compartment.oc1...",
# Uses ~/.oci/config with DEFAULT profile
)
```

**2. Custom Profile**
```Python
co = cohere.OciClient(
oci_profile="MY_PROFILE",
oci_region="us-chicago-1",
oci_compartment_id="ocid1.compartment.oc1...",
)
```

**3. Session-based Authentication (Security Token)**
```Python
# Works with OCI CLI session tokens
co = cohere.OciClient(
oci_profile="MY_SESSION_PROFILE", # Profile with security_token_file
oci_region="us-chicago-1",
oci_compartment_id="ocid1.compartment.oc1...",
)
```

**4. Direct Credentials**
```Python
co = cohere.OciClient(
oci_user_id="ocid1.user.oc1...",
oci_fingerprint="xx:xx:xx:...",
oci_tenancy_id="ocid1.tenancy.oc1...",
oci_private_key_path="~/.oci/key.pem",
oci_region="us-chicago-1",
oci_compartment_id="ocid1.compartment.oc1...",
)
```

**5. Instance Principal (for OCI Compute instances)**
```Python
co = cohere.OciClient(
auth_type="instance_principal",
oci_region="us-chicago-1",
oci_compartment_id="ocid1.compartment.oc1...",
)
```

### Supported OCI APIs

The OCI client supports the following Cohere APIs:
- **Embed**: Full support for all embedding models (embed-english-v3.0, embed-light-v3.0, embed-multilingual-v3.0)
- **Chat**: Full support with both V1 (`OciClient`) and V2 (`OciClientV2`) APIs
- Streaming available via `chat_stream()`
- Supports Command-R and Command-A model families

### OCI Model Availability and Limitations

**Available on OCI On-Demand Inference:**
- ✅ **Embed models**: embed-english-v3.0, embed-light-v3.0, embed-multilingual-v3.0
- ✅ **Chat models**: command-r-08-2024, command-r-plus, command-a-03-2025

**Not Available on OCI On-Demand Inference:**
- ❌ **Generate API**: OCI TEXT_GENERATION models are base models that require fine-tuning before deployment
- ❌ **Rerank API**: OCI TEXT_RERANK models are base models that require fine-tuning before deployment
- ❌ **Multiple Embedding Types**: OCI on-demand models only support single embedding type per request (cannot request both `float` and `int8` simultaneously)

**Note**: To use Generate or Rerank models on OCI, you need to:
1. Fine-tune the base model using OCI's fine-tuning service
2. Deploy the fine-tuned model to a dedicated endpoint
3. Update your code to use the deployed model endpoint

For the latest model availability, see the [OCI Generative AI documentation](https://docs.oracle.com/en-us/iaas/Content/generative-ai/home.htm).

## Contributing

While we value open-source contributions to this SDK, the code is generated programmatically. Additions made directly would have to be moved over to our generation code, otherwise they would be overwritten upon the next generated release. Feel free to open a PR as a proof of concept, but know that we will not be able to merge it as-is. We suggest opening an issue first to discuss with us!
Expand Down
4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ requests = "^2.0.0"
tokenizers = ">=0.15,<1"
types-requests = "^2.0.0"
typing_extensions = ">= 4.0.0"
oci = { version = "^2.165.0", optional = true }

[tool.poetry.extras]
oci = ["oci"]

[tool.poetry.group.dev.dependencies]
mypy = "==1.13.0"
Expand Down
4 changes: 4 additions & 0 deletions src/cohere/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,8 @@
"NotFoundError": ".errors",
"NotImplementedError": ".errors",
"OAuthAuthorizeResponse": ".types",
"OciClient": ".oci_client",
"OciClientV2": ".oci_client",
"ParseInfo": ".types",
"RerankDocument": ".types",
"RerankRequestDocumentsItem": ".types",
Expand Down Expand Up @@ -851,6 +853,8 @@ def __dir__():
"NotFoundError",
"NotImplementedError",
"OAuthAuthorizeResponse",
"OciClient",
"OciClientV2",
"ParseInfo",
"RerankDocument",
"RerankRequestDocumentsItem",
Expand Down
15 changes: 3 additions & 12 deletions src/cohere/aws_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
import typing

import httpx
from httpx import URL, SyncByteStream, ByteStream
from httpx import URL, ByteStream

from . import GenerateStreamedResponse, Generation, \
NonStreamedChatResponse, EmbedResponse, StreamedChatResponse, RerankResponse, ApiMeta, ApiMetaTokens, \
ApiMetaBilledUnits
from .client import Client, ClientEnvironment
from .core import construct_type
from .manually_maintained.lazy_aws_deps import lazy_boto3, lazy_botocore
from .manually_maintained.streaming import Streamer
from .client_v2 import ClientV2

class AwsClient(Client):
Expand Down Expand Up @@ -112,16 +113,6 @@ def get_event_hooks(
})


class Streamer(SyncByteStream):
lines: typing.Iterator[bytes]

def __init__(self, lines: typing.Iterator[bytes]):
self.lines = lines

def __iter__(self) -> typing.Iterator[bytes]:
return self.lines


response_mapping: typing.Dict[str, typing.Any] = {
"chat": NonStreamedChatResponse,
"embed": EmbedResponse,
Expand Down Expand Up @@ -291,4 +282,4 @@ def get_api_version(*, version: str):
"v2": 2,
}

return int_version.get(version, 1)
return int_version.get(version, 1)
30 changes: 30 additions & 0 deletions src/cohere/manually_maintained/lazy_oci_deps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""Lazy loading for optional OCI SDK dependency."""

from typing import Any

OCI_INSTALLATION_MESSAGE = """
The OCI SDK is required to use OciClient or OciClientV2.

Install it with:
pip install oci

Or with the optional dependency group:
pip install cohere[oci]
"""


def lazy_oci() -> Any:
"""
Lazily import the OCI SDK.

Returns:
The oci module

Raises:
ImportError: If the OCI SDK is not installed
"""
try:
import oci
return oci
except ImportError:
raise ImportError(OCI_INSTALLATION_MESSAGE)
15 changes: 15 additions & 0 deletions src/cohere/manually_maintained/streaming.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import typing

from httpx import SyncByteStream


class Streamer(SyncByteStream):
"""Wrap an iterator of bytes for httpx streaming responses."""

lines: typing.Iterator[bytes]

def __init__(self, lines: typing.Iterator[bytes]):
self.lines = lines

def __iter__(self) -> typing.Iterator[bytes]:
return self.lines
Loading