From a938605e0f4058ac882b2c96396aa6d6bb851f11 Mon Sep 17 00:00:00 2001 From: Scott Lessans Date: Tue, 5 Aug 2025 10:23:26 -0700 Subject: [PATCH 1/7] add back aarch --- .github/workflows/CI.yml | 8 ++++---- pyproject.toml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index ce9fd19..7832a69 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -28,8 +28,8 @@ jobs: target: x86_64 - runner: ubuntu-22.04 target: x86 - # - runner: ubuntu-22.04 - # target: aarch64 + - runner: ubuntu-22.04 + target: aarch64 - runner: ubuntu-22.04 target: armv7 # - runner: ubuntu-22.04 @@ -45,7 +45,7 @@ jobs: uses: PyO3/maturin-action@v1 with: target: ${{ matrix.platform.target }} - args: --release --out dist --find-interpreter + args: -F python-binding --release --out dist --find-interpreter sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} manylinux: auto - name: Upload wheels @@ -76,7 +76,7 @@ jobs: uses: PyO3/maturin-action@v1 with: target: ${{ matrix.platform.target }} - args: --release --out dist --find-interpreter + args: -F python-binding --release --out dist --find-interpreter sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} manylinux: musllinux_1_2 - name: Upload wheels diff --git a/pyproject.toml b/pyproject.toml index a89a2e6..5836c58 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,10 +16,10 @@ description = "OpenAI's response format for its open-weight model series gpt-oss readme = "README.md" [project.optional-dependencies] -demo = ["uvicorn", "fastapi"] +demo = [] [tool.maturin] -features = ["pyo3/extension-module"] +features = ["python-binding", "pyo3/extension-module"] module-name = "openai_harmony" python-source = "python" From 2d077f3745f4af8c7910911d0a442f6e3763ed4f Mon Sep 17 00:00:00 2001 From: Scott Lessans Date: Tue, 5 Aug 2025 10:32:20 -0700 Subject: [PATCH 2/7] ring fixes --- .github/workflows/CI.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 7832a69..c5a0264 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -43,6 +43,9 @@ jobs: python-version: 3.x - name: Build wheels uses: PyO3/maturin-action@v1 + env: + # Ensure ring's ARM assembly sees an explicit architecture on aarch64 (glibc) + CFLAGS_aarch64_unknown_linux_gnu: -D__ARM_ARCH=8 with: target: ${{ matrix.platform.target }} args: -F python-binding --release --out dist --find-interpreter @@ -74,6 +77,9 @@ jobs: python-version: 3.x - name: Build wheels uses: PyO3/maturin-action@v1 + env: + # Ensure ring's ARM assembly sees an explicit architecture on aarch64 (musl) + CFLAGS_aarch64_unknown_linux_musl: -D__ARM_ARCH=8 with: target: ${{ matrix.platform.target }} args: -F python-binding --release --out dist --find-interpreter From b16552ff24c07ead0d7975004e1de9f4ab70b79f Mon Sep 17 00:00:00 2001 From: Scott Lessans Date: Tue, 5 Aug 2025 10:36:49 -0700 Subject: [PATCH 3/7] cleanup flags and platforms --- .github/workflows/CI.yml | 12 ++++-------- README.md | 4 ++-- pyproject.toml | 2 +- test_python.sh | 2 +- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index c5a0264..29518e7 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -32,10 +32,6 @@ jobs: target: aarch64 - runner: ubuntu-22.04 target: armv7 - # - runner: ubuntu-22.04 - # target: s390x - # - runner: ubuntu-22.04 - # target: ppc64le steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 @@ -48,7 +44,7 @@ jobs: CFLAGS_aarch64_unknown_linux_gnu: -D__ARM_ARCH=8 with: target: ${{ matrix.platform.target }} - args: -F python-binding --release --out dist --find-interpreter + args: --release --out dist --find-interpreter sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} manylinux: auto - name: Upload wheels @@ -82,7 +78,7 @@ jobs: CFLAGS_aarch64_unknown_linux_musl: -D__ARM_ARCH=8 with: target: ${{ matrix.platform.target }} - args: -F python-binding --release --out dist --find-interpreter + args: --release --out dist --find-interpreter sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} manylinux: musllinux_1_2 - name: Upload wheels @@ -110,7 +106,7 @@ jobs: uses: PyO3/maturin-action@v1 with: target: ${{ matrix.platform.target }} - args: -F python-binding --release --out dist --find-interpreter + args: --release --out dist --find-interpreter sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} - name: Upload wheels uses: actions/upload-artifact@v4 @@ -136,7 +132,7 @@ jobs: uses: PyO3/maturin-action@v1 with: target: ${{ matrix.platform.target }} - args: -F python-binding --release --out dist --find-interpreter + args: --release --out dist --find-interpreter sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} - name: Upload wheels uses: actions/upload-artifact@v4 diff --git a/README.md b/README.md index 1b9d4f4..6ce4885 100644 --- a/README.md +++ b/README.md @@ -177,10 +177,10 @@ source .venv/bin/activate # Install maturin and test dependencies pip install maturin pytest mypy ruff # tailor to your workflow # Compile the Rust crate *and* install the Python package in editable mode -maturin develop -F python-binding --release +maturin develop --release ``` -`maturin develop -F python-binding` builds _harmony_ with Cargo, produces a native extension +`maturin develop` builds _harmony_ with Cargo, produces a native extension (`openai_harmony..so`) and places it in your virtualenv next to the pure- Python wrapper – similar to `pip install -e .` for pure Python projects. diff --git a/pyproject.toml b/pyproject.toml index 5836c58..4c8ad8c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,7 @@ description = "OpenAI's response format for its open-weight model series gpt-oss readme = "README.md" [project.optional-dependencies] -demo = [] +demo = ["uvicorn", "fastapi"] [tool.maturin] features = ["python-binding", "pyo3/extension-module"] diff --git a/test_python.sh b/test_python.sh index 09a24de..51176a7 100755 --- a/test_python.sh +++ b/test_python.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash set -e source .venv/bin/activate -maturin develop -F python-binding --release +maturin develop --release pytest "$@" From d2ba5c0daa81ac047997ef9c2b5354c28048b2d2 Mon Sep 17 00:00:00 2001 From: Scott Lessans Date: Tue, 5 Aug 2025 10:41:34 -0700 Subject: [PATCH 4/7] alpha bump --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b774e8..6dae6d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1317,7 +1317,7 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "openai-harmony" -version = "0.0.2" +version = "0.0.2-alpha.1" dependencies = [ "anyhow", "base64", diff --git a/Cargo.toml b/Cargo.toml index 53cd425..ea43da9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openai-harmony" -version = "0.0.2" +version = "0.0.2-alpha.1" edition = "2021" license = "Apache-2.0" repository = "https://github.com/openai/harmony" From 658206a36eab91652c6354325f4ac7eaa901e7f2 Mon Sep 17 00:00:00 2001 From: michaelfeil Date: Tue, 5 Aug 2025 17:41:48 +0000 Subject: [PATCH 5/7] cross compile bindings --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 53cd425..da0d25b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,7 +42,7 @@ reqwest = { version = "0.12.5", default-features = false, features = [ ] } futures = "0.3" clap = { version = "4", features = ["derive"] } -pyo3 = { version = "0.25.0", optional = true, features = ["extension-module"] } +pyo3 = { version = "0.25.0", optional = true, features = ["extension-module", "abi3-py38"] } wasm-bindgen = { version = "0.2.100", optional = true, features = [ "serde-serialize", ] } From 4cf923e7c48a47261c0b94942896538cd9c135c4 Mon Sep 17 00:00:00 2001 From: CharlesCNorton <135471798+CharlesCNorton@users.noreply.github.com> Date: Tue, 5 Aug 2025 13:58:39 -0400 Subject: [PATCH 6/7] docs: fix typo in README.md (premables -> preambles) Fix typo in harmony format documentation Changed "premables" to "preambles" in the description of the harmony response format capabilities. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6ce4885..73cc841 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ The [gpt-oss models][gpt-oss] were trained on the [harmony response format][harmony-format] for defining conversation structures, generating reasoning output and structuring function calls. If you are not using gpt-oss directly but through an API or a provider like HuggingFace, Ollama, or vLLM, you will not have to be concerned about this as your inference solution will handle the formatting. If you are building your own inference solution, this guide will walk you through the prompt format. The format is designed to mimic the OpenAI Responses API, so if you have used that API before, this format should hopefully feel familiar to you. gpt-oss should not be used without using the harmony format as it will not work correctly. -The format enables the model to output to multiple different channels for chain of thought, and tool calling premables along with regular responses. It also enables specifying various tool namespaces, and structured outputs along with a clear instruction hierarchy. [Check out the guide][harmony-format] to learn more about the format itself. +The format enables the model to output to multiple different channels for chain of thought, and tool calling preambles along with regular responses. It also enables specifying various tool namespaces, and structured outputs along with a clear instruction hierarchy. [Check out the guide][harmony-format] to learn more about the format itself. ``` <|start|>system<|message|>You are ChatGPT, a large language model trained by OpenAI. From b1b6c5fe9a88db4166f3908d080a71bdba2ace56 Mon Sep 17 00:00:00 2001 From: Scott Lessans Date: Tue, 5 Aug 2025 11:18:34 -0700 Subject: [PATCH 7/7] fixed readme rust sample, added readme to lib.rs docs for doctest, bumped version --- Cargo.lock | 2 +- Cargo.toml | 7 +++++-- README.md | 14 +++++++------- src/lib.rs | 2 ++ 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6dae6d9..6b774e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1317,7 +1317,7 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "openai-harmony" -version = "0.0.2-alpha.1" +version = "0.0.2" dependencies = [ "anyhow", "base64", diff --git a/Cargo.toml b/Cargo.toml index f57dd14..12ebc27 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openai-harmony" -version = "0.0.2-alpha.1" +version = "0.0.2" edition = "2021" license = "Apache-2.0" repository = "https://github.com/openai/harmony" @@ -42,7 +42,10 @@ reqwest = { version = "0.12.5", default-features = false, features = [ ] } futures = "0.3" clap = { version = "4", features = ["derive"] } -pyo3 = { version = "0.25.0", optional = true, features = ["extension-module", "abi3-py38"] } +pyo3 = { version = "0.25.0", optional = true, features = [ + "extension-module", + "abi3-py38", +] } wasm-bindgen = { version = "0.2.100", optional = true, features = [ "serde-serialize", ] } diff --git a/README.md b/README.md index 73cc841..d9c5f13 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ The [gpt-oss models][gpt-oss] were trained on the [harmony response format][harm The format enables the model to output to multiple different channels for chain of thought, and tool calling preambles along with regular responses. It also enables specifying various tool namespaces, and structured outputs along with a clear instruction hierarchy. [Check out the guide][harmony-format] to learn more about the format itself. -``` +```text <|start|>system<|message|>You are ChatGPT, a large language model trained by OpenAI. Knowledge cutoff: 2024-06 Current date: 2025-06-28 @@ -114,12 +114,12 @@ openai-harmony = { git = "https://github.com/openai/harmony" } ```rust use openai_harmony::chat::{Message, Role, Conversation}; use openai_harmony::{HarmonyEncodingName, load_harmony_encoding}; + fn main() -> anyhow::Result<()> { let enc = load_harmony_encoding(HarmonyEncodingName::HarmonyGptOss)?; - let convo = Conversation::from_messages([ - Message::from_role_and_content(Role::User, "Hello there!"), - ]); - let tokens = enc.render_conversation_for_completion(&convo, Role::Assistant)?; + let convo = + Conversation::from_messages([Message::from_role_and_content(Role::User, "Hello there!")]); + let tokens = enc.render_conversation_for_completion(&convo, Role::Assistant, None)?; println!("{:?}", tokens); Ok(()) } @@ -130,7 +130,7 @@ fn main() -> anyhow::Result<()> { The majority of the rendering and parsing is built in Rust for performance and exposed to Python through thin [`pyo3`](https://pyo3.rs/) bindings. -``` +```text ┌──────────────────┐ ┌───────────────────────────┐ │ Python code │ │ Rust core (this repo) │ │ (dataclasses, │────► │ • chat / encoding logic │ @@ -140,7 +140,7 @@ through thin [`pyo3`](https://pyo3.rs/) bindings. ### Repository layout -``` +```text . ├── src/ # Rust crate │ ├── chat.rs # High-level data-structures (Role, Message, …) diff --git a/src/lib.rs b/src/lib.rs index 2535e1c..acd572a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ +#![doc = include_str!("../README.md")] + pub mod chat; mod encoding; mod registry;