Skip to content

Commit 65b120d

Browse files
Merge upstream main into feat/skills-api
2 parents 25e18f8 + ac205c4 commit 65b120d

25 files changed

Lines changed: 995 additions & 41 deletions

File tree

.github/workflows/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ OGX uses GitHub Actions for Continuous Integration (CI). Below is a table detail
1717
| Integration Auth Tests | [integration-auth-tests.yml](integration-auth-tests.yml) | Run the integration test suite with Kubernetes authentication |
1818
| Integration Responses, Conversations & Prompts Auth Tests | [integration-responses-conversations-auth-tests.yml](integration-responses-conversations-auth-tests.yml) | Run responses, conversations, and prompts auth tests with Kubernetes authentication |
1919
| SqlStore Integration Tests | [integration-sql-store-tests.yml](integration-sql-store-tests.yml) | Run the integration test suite with SqlStore |
20+
| Messages API - Claude Code CLI Smoke Test | [integration-tests-messages-cli.yml](integration-tests-messages-cli.yml) | Drive the real Claude Code CLI against /v1/messages (live, Ollama) |
2021
| Integration Tests (Replay) | [integration-tests.yml](integration-tests.yml) | Run the integration test suites from tests/integration in replay mode |
2122
| Vector IO Integration Tests | [integration-vector-io-tests.yml](integration-vector-io-tests.yml) | Run the integration test suite with various VectorIO providers |
2223
| OpenAPI Generator SDK Validation | [openapi-generator-validation.yml](openapi-generator-validation.yml) | Validate OpenAPI Generator SDK generation |
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
name: Messages API - Claude Code CLI Smoke Test
2+
3+
run-name: Drive the real Claude Code CLI against /v1/messages (live, Ollama)
4+
5+
on:
6+
push:
7+
branches:
8+
- main
9+
- 'release-[0-9]+.[0-9]+.x'
10+
pull_request:
11+
branches:
12+
- main
13+
- 'release-[0-9]+.[0-9]+.x'
14+
types: [opened, synchronize, reopened]
15+
paths:
16+
- 'src/ogx/providers/inline/messages/**'
17+
- 'src/ogx_api/**'
18+
- 'tests/integration/messages/**'
19+
- 'uv.lock'
20+
- 'pyproject.toml'
21+
- '.github/workflows/integration-tests-messages-cli.yml'
22+
- '.github/actions/setup-test-environment/action.yml'
23+
- '.github/actions/run-and-record-tests/action.yml'
24+
- 'scripts/integration-tests.sh'
25+
merge_group:
26+
branches:
27+
- main
28+
- 'release-[0-9]+.[0-9]+.x'
29+
workflow_dispatch:
30+
31+
concurrency:
32+
group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && github.run_id || github.ref }}
33+
cancel-in-progress: true
34+
35+
permissions:
36+
contents: read
37+
38+
env:
39+
# Pinned for reproducibility. The CLI bakes the cwd, date, and platform into
40+
# every request body, so its traffic cannot be recorded/replayed; this test
41+
# runs live against Ollama instead. Bumping only changes the client behavior
42+
# under test, not any committed recordings.
43+
CLAUDE_CODE_CLI_VERSION: '2.1.159'
44+
45+
jobs:
46+
claude-code-cli-smoke:
47+
name: Claude Code CLI smoke (ollama, live)
48+
runs-on: ubuntu-latest
49+
# CPU-only runners generate slowly; the live CLI session can take several
50+
# minutes against the Ollama model. Keep ample headroom over the test's own
51+
# 600s subprocess timeout plus environment setup.
52+
timeout-minutes: 30
53+
54+
steps:
55+
- name: Checkout repository
56+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
57+
58+
# Live mode (not replay) so the Ollama backend is provisioned and the
59+
# real CLI traffic reaches a real model.
60+
- name: Setup test environment
61+
uses: ./.github/actions/setup-test-environment
62+
with:
63+
python-version: '3.12'
64+
client-version: 'latest'
65+
setup: 'ollama'
66+
suite: 'messages'
67+
inference-mode: 'live'
68+
69+
- name: Install Claude Code CLI
70+
run: |
71+
curl -fsSL https://claude.ai/install.sh | bash -s -- "${CLAUDE_CODE_CLI_VERSION}"
72+
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
73+
"$HOME/.local/bin/claude" --version
74+
75+
- name: Run Claude Code CLI smoke test
76+
uses: ./.github/actions/run-and-record-tests
77+
with:
78+
stack-config: 'server:ci-tests'
79+
setup: 'ollama'
80+
suite: 'messages'
81+
inference-mode: 'live'
82+
pattern: 'test_claude_code_cli_smoke'

.pre-commit-config.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,15 @@ repos:
217217
pass_filenames: false
218218
require_serial: true
219219
files: ^.github/workflows/.*$
220+
- id: target-model-matrix
221+
name: Generate target model matrix
222+
additional_dependencies:
223+
- *uv-dependency
224+
entry: ./scripts/uv-run-with-index.sh run ./scripts/generate_target_models_docs.py
225+
language: python
226+
pass_filenames: false
227+
require_serial: true
228+
files: ^tests/integration/(suites\.py|ci_matrix\.json|TARGET_MODELS\.md)$|^tests/integration/responses/recordings/.*\.json$|^scripts/(generate_target_models_docs|provider_compat_matrix)\.py$
220229
- id: ui-linter
221230
name: Format & Lint UI
222231
entry: bash ./scripts/run-ui-linter.sh
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
---
2+
slug: ogx-bedrock-aws-auth
3+
title: "Use Amazon Bedrock with OGX Without Managing Bearer Tokens"
4+
authors: [skamenan7]
5+
tags: [ogx, aws, bedrock, sigv4, sts]
6+
date: 2026-06-02
7+
---
8+
9+
OGX now signs Bedrock requests with standard AWS SigV4, so the server uses the same credential chain your platform already runs. No bearer tokens to manage, no custom auth plumbing in your application code.
10+
11+
If your team uses IAM roles, IRSA, or STS for Bedrock access, this means OGX fits into your existing AWS identity model without extra moving parts. Apps talk to one OpenAI-compatible API while OGX handles the provider-specific auth behind the scenes.
12+
13+
For the implementation details, see [issue #4730](https://github.com/ogx-ai/ogx/issues/4730) and [PR #5388](https://github.com/ogx-ai/ogx/pull/5388).
14+
15+
<!--truncate-->
16+
17+
## Why this helps teams adopt OGX
18+
19+
If you are evaluating OGX for production use, this change makes Bedrock easier to fit into an existing AWS environment:
20+
21+
- You can keep using existing OpenAI-compatible clients and agent frameworks.
22+
- You can use standard AWS identity flows, including IAM roles, IRSA, web identity, AWS profiles, and short-lived credentials.
23+
- You do not have to teach every app or service how Bedrock-specific auth works.
24+
- You can keep OGX as the abstraction layer, so switching between Bedrock and other providers stays an infrastructure choice instead of an application rewrite.
25+
26+
The practical effect is less custom auth plumbing at the application layer. Teams can use Bedrock through OGX without giving up the AWS identity flows they already operate.
27+
28+
## What shipped
29+
30+
The core change is a SigV4 path for the Bedrock inference adapter. When `aws_bedrock_bearer_token` is absent, OGX now signs Bedrock requests with AWS SigV4 instead of assuming every request will carry a precomputed bearer token.
31+
32+
That shipped with a few important pieces:
33+
34+
- SigV4 request signing for the Bedrock OpenAI-compatible runtime.
35+
- STS web identity support through `aws_role_arn` and `aws_web_identity_token_file`.
36+
- Automatic refresh of temporary credentials.
37+
- Shared Bedrock config updates so the AWS auth story is consistent across the Bedrock provider code.
38+
- Compatibility with existing bearer-token mode, so this is additive rather than breaking.
39+
40+
For users, the result is simple: if OGX has access to normal AWS credentials, it can talk to Bedrock without requiring a separate token-management workflow.
41+
42+
## How it fits together
43+
44+
From the application side, the client shape stays the same: point a standard client at OGX and let OGX handle the provider details.
45+
46+
```python
47+
import requests
48+
from openai import OpenAI
49+
50+
base_url = "http://localhost:8321"
51+
model_id = requests.get(f"{base_url}/v1/models", timeout=10).json()["data"][0]["id"]
52+
53+
client = OpenAI(base_url=f"{base_url}/v1", api_key="ogx")
54+
55+
response = client.chat.completions.create(
56+
model=model_id,
57+
messages=[{"role": "user", "content": "Explain why OGX is useful"}],
58+
)
59+
```
60+
61+
## Try it now
62+
63+
If you already have AWS credentials available through a profile, IAM role, IRSA, or web identity, this is a short path to a working Bedrock request through OGX.
64+
65+
### 1. Export your AWS environment
66+
67+
```bash
68+
export AWS_DEFAULT_REGION=us-west-2
69+
70+
# Pick the option that matches your environment:
71+
# export AWS_PROFILE=default
72+
# export AWS_ROLE_ARN=arn:aws:iam::<account-id>:role/<role-name>
73+
# For EKS IRSA:
74+
# export AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token
75+
```
76+
77+
### 2. Write a minimal `config.yaml`
78+
79+
```bash
80+
cat > config.yaml <<'EOF'
81+
version: 2
82+
distro_name: bedrock-sigv4-demo
83+
apis:
84+
- inference
85+
- models
86+
providers:
87+
inference:
88+
- provider_id: bedrock-inference
89+
provider_type: remote::bedrock
90+
config:
91+
# aws_bedrock_bearer_token intentionally omitted so OGX uses the AWS credential chain
92+
region_name: ${env.AWS_DEFAULT_REGION:=us-west-2}
93+
aws_role_arn: ${env.AWS_ROLE_ARN:=}
94+
aws_web_identity_token_file: ${env.AWS_WEB_IDENTITY_TOKEN_FILE:=}
95+
aws_role_session_name: ${env.AWS_ROLE_SESSION_NAME:=ogx-bedrock-demo}
96+
session_ttl: ${env.AWS_SESSION_TTL:=3600}
97+
98+
storage:
99+
backends:
100+
kv_default:
101+
type: kv_sqlite
102+
db_path: ./.ogx/kvstore.db
103+
sql_default:
104+
type: sql_sqlite
105+
db_path: ./.ogx/sql_store.db
106+
stores:
107+
metadata:
108+
namespace: registry
109+
backend: kv_default
110+
inference:
111+
table_name: inference_store
112+
backend: sql_default
113+
max_write_queue_size: 10000
114+
num_writers: 4
115+
prompts:
116+
namespace: prompts
117+
backend: kv_default
118+
119+
registered_resources:
120+
models:
121+
- metadata: {}
122+
model_id: openai.gpt-oss-20b-1:0
123+
provider_id: bedrock-inference
124+
provider_model_id: openai.gpt-oss-20b-1:0
125+
model_type: llm
126+
EOF
127+
```
128+
129+
### 3. Start OGX
130+
131+
```bash
132+
uv run ogx run --port 8321 ./config.yaml
133+
```
134+
135+
Leave that terminal running. In a second terminal, use the steps below.
136+
137+
### 4. Verify the model is available
138+
139+
```bash
140+
MODEL_ID=$(curl -s http://localhost:8321/v1/models | jq -r '.data[0].id // empty')
141+
test -n "$MODEL_ID" && echo "Using model: $MODEL_ID"
142+
```
143+
144+
If you want to inspect the full model list:
145+
146+
```bash
147+
curl -s http://localhost:8321/v1/models | jq
148+
```
149+
150+
### 5. Send your first request with `curl`
151+
152+
```bash
153+
curl -s -X POST "http://localhost:8321/v1/chat/completions" \
154+
-H "Content-Type: application/json" \
155+
-d "{
156+
\"model\": \"$MODEL_ID\",
157+
\"messages\": [{\"role\": \"user\", \"content\": \"Which planet do humans live on?\"}],
158+
\"stream\": false
159+
}" | jq -r '.choices[0].message.content'
160+
```
161+
162+
### 6. Send the same request from the OpenAI Python client
163+
164+
```bash
165+
uv run python - <<'PY'
166+
import requests
167+
from openai import OpenAI
168+
169+
base_url = "http://localhost:8321"
170+
model_id = requests.get(f"{base_url}/v1/models", timeout=10).json()["data"][0]["id"]
171+
172+
client = OpenAI(base_url=f"{base_url}/v1", api_key="ogx")
173+
174+
response = client.chat.completions.create(
175+
model=model_id,
176+
messages=[{"role": "user", "content": "Which planet do humans live on?"}],
177+
stream=False,
178+
)
179+
180+
print(response.choices[0].message.content)
181+
PY
182+
```
183+
184+
If you are only doing a quick local spike and already have a pre-signed Bedrock bearer token, that path still works. For long-running deployments, leave bearer auth unset and let OGX use the standard AWS identity flow instead.
185+
186+
If you do use a bearer token, make sure it was generated for the same AWS Region that OGX is using. A token scoped to `us-east-2` will be rejected by a Bedrock endpoint configured for `us-west-2`, and vice versa.
187+
188+
There are two common paths here: direct SigV4-backed inference for `chat/completions`, and a Bedrock-backed `Responses` path for higher-level workflows such as tool calling. The steps above focus on the shorter `chat/completions` path.
189+
190+
That path has been exercised end to end through the standard OGX surface: model resolution from `/v1/models`, non-streaming and streaming `chat/completions`, fallback to SigV4 when empty bearer overrides are supplied, successful bearer-token overrides when explicitly provided, rejection of invalid bearer overrides, concurrent request isolation, and repeated request smoke checks. For someone evaluating OGX, that is the important part: the AWS-native path works through the same API shape your applications already use.
191+
192+
## Migration
193+
194+
If your config already uses `api_key` or `aws_bearer_token_bedrock`, it still works. No changes required. OGX accepts both the old and new field names through Pydantic aliases.
195+
196+
For new deployments, use the canonical name `aws_bedrock_bearer_token` in your config and `AWS_BEDROCK_BEARER_TOKEN` as the environment variable. Per-request bearer overrides via the `x-ogx-provider-data` header also accept both old and new field names.

docs/blog/authors.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,8 @@ gyliu513:
4242
name: Guangya Liu
4343
url: https://github.com/gyliu513
4444
image_url: https://github.com/gyliu513.png
45+
46+
skamenan7:
47+
name: Sumanth Kamenani
48+
url: https://github.com/skamenan7
49+
image_url: https://github.com/skamenan7.png

docs/docs/providers/file_processors/inline_docling.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,12 @@ See [Docling's documentation](https://docling-project.github.io/docling/) for mo
9797
|-------|------|----------|---------|-------------|
9898
| `default_chunk_size_tokens` | `int` | No | 800 | Default chunk size in tokens when chunking_strategy type is 'auto' |
9999
| `default_chunk_overlap_tokens` | `int` | No | 400 | Default chunk overlap in tokens when chunking_strategy type is 'auto' |
100+
| `do_ocr` | `bool` | No | True | Enable OCR for scanned documents. Set to False for digital PDFs (with embedded text) to improve processing speed by ~3x for non-scanned PDFs. Note: Setting to False on scanned PDFs will result in minimal text extraction. |
100101

101102
## Sample Configuration
102103

103104
```yaml
104105
default_chunk_size_tokens: 800
105106
default_chunk_overlap_tokens: 400
107+
do_ocr: true
106108
```

docs/docs/providers/inference/remote_bedrock.mdx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
description: "AWS Bedrock inference provider using OpenAI compatible endpoint."
2+
description: "AWS Bedrock inference provider for the OpenAI-compatible runtime, with AWS credential-chain auth by default and an optional bearer-token override."
33
sidebar_label: Remote - Bedrock
44
title: remote::bedrock
55
---
@@ -8,15 +8,15 @@ title: remote::bedrock
88

99
## Description
1010

11-
AWS Bedrock inference provider using OpenAI compatible endpoint.
11+
AWS Bedrock inference provider for the OpenAI-compatible runtime, with AWS credential-chain auth by default and an optional bearer-token override.
1212

1313
## Configuration
1414

1515
| Field | Type | Required | Default | Description |
1616
|-------|------|----------|---------|-------------|
1717
| `allowed_models` | `list[str] \| None` | No | | List of models that should be registered with the model registry. If None, all models are allowed. |
1818
| `refresh_models` | `bool` | No | False | Whether to refresh models periodically from the provider |
19-
| `api_key` | `SecretStr \| None` | No | | Authentication credential for the provider |
19+
| `aws_bedrock_bearer_token` | `SecretStr \| None` | No | | Optional bearer token for Amazon Bedrock's OpenAI-compatible runtime. Leave unset to use the server's AWS credential chain (recommended). |
2020
| `network` | `NetworkConfig \| None` | No | | Network configuration including TLS, proxy, and timeout settings. |
2121
| `network.tls` | `TLSConfig \| None` | No | | TLS/SSL configuration for secure connections. |
2222
| `network.tls.verify` | `bool \| Path` | No | True | Whether to verify TLS certificates. Can be a boolean or a path to a CA certificate file. |
@@ -51,7 +51,7 @@ AWS Bedrock inference provider using OpenAI compatible endpoint.
5151
## Sample Configuration
5252

5353
```yaml
54-
api_key: ${env.AWS_BEARER_TOKEN_BEDROCK:=}
54+
aws_bedrock_bearer_token: ${env.AWS_BEDROCK_BEARER_TOKEN:=}
5555
region_name: ${env.AWS_DEFAULT_REGION:=us-east-2}
5656
aws_role_arn: ${env.AWS_ROLE_ARN:=}
5757
aws_web_identity_token_file: ${env.AWS_WEB_IDENTITY_TOKEN_FILE:=}

scripts/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ scripts/
1212
provider_codegen.py # Regenerate provider registry and routing code
1313
generate_ci_matrix.py # Generate CI test matrix from provider/distribution data
1414
gen-ci-docs.py # Generate CI documentation
15+
generate_target_models_docs.py # Generate integration target model documentation
1516
run_openapi_generator.sh # Run OpenAPI spec generation
1617
check-api-conformance.sh # Check API conformance
1718
check_file_size.py # Check file sizes

0 commit comments

Comments
 (0)