From 68c0b34135e4e7ee23c3173e04a58d2364ccefbb Mon Sep 17 00:00:00 2001 From: Aniket Dixit Date: Mon, 27 Jul 2026 01:30:25 +0530 Subject: [PATCH] modes cleanup --- README.md | 1 - docs/CLAUDE_SDK_USERS.md | 5 ++--- docs/opengradient/client/llm.md | 14 +++++--------- docs/opengradient/client/twins.md | 5 ++--- docs/opengradient/types.md | 16 +++++----------- examples/langchain_react_agent.py | 2 +- examples/llm_chat.py | 4 ++-- examples/llm_chat_streaming.py | 11 +++++------ integrationtest/llm/test_llm_chat.py | 4 ++-- src/opengradient/cli.py | 5 ++--- src/opengradient/client/llm.py | 2 -- src/opengradient/types.py | 16 ++++------------ stresstest/llm.py | 2 +- tests/client_test.py | 5 ++++- tutorials/01-verifiable-ai-agent.md | 14 +++----------- tutorials/02-streaming-multi-provider.md | 23 ++++++----------------- tutorials/03-verified-tool-calling.md | 4 ++-- 17 files changed, 46 insertions(+), 87 deletions(-) diff --git a/README.md b/README.md index 6c91e8c..d8ac399 100644 --- a/README.md +++ b/README.md @@ -439,7 +439,6 @@ OpenGradient supports multiple settlement modes through the x402 payment protoco - **PRIVATE**: Payment only, no input/output data on-chain (maximum privacy) - **BATCH_HASHED**: Aggregates inferences into a Merkle tree with input/output hashes and signatures (most cost-efficient, default) -- **INDIVIDUAL_FULL**: Records input, output, timestamp, and verification on-chain (maximum auditability) Specify settlement mode in your requests: ```python diff --git a/docs/CLAUDE_SDK_USERS.md b/docs/CLAUDE_SDK_USERS.md index 676d762..3889c60 100644 --- a/docs/CLAUDE_SDK_USERS.md +++ b/docs/CLAUDE_SDK_USERS.md @@ -282,9 +282,8 @@ og.InferenceMode.TEE # Trusted Execution Environment og.InferenceMode.ZKML # Zero-knowledge proof # x402 Payment Settlement Modes (for LLM calls) -og.x402SettlementMode.PRIVATE # Input/output hashes only (most private) -og.x402SettlementMode.BATCH_HASHED # Batch hashes (most cost-efficient, default) -og.x402SettlementMode.INDIVIDUAL_FULL # Full data and metadata on-chain +og.x402SettlementMode.PRIVATE # Payment only; inference data stays off-chain +og.x402SettlementMode.BATCH_HASHED # Batch hashes (most cost-efficient, default) # Workflow data types og.CandleType.OPEN, .HIGH, .LOW, .CLOSE, .VOLUME diff --git a/docs/opengradient/client/llm.md b/docs/opengradient/client/llm.md index 6d7f1c7..e00f52d 100644 --- a/docs/opengradient/client/llm.md +++ b/docs/opengradient/client/llm.md @@ -99,7 +99,6 @@ Perform inference on an LLM model using chat via TEE. * **`x402_settlement_mode (x402SettlementMode, optional)`**: Settlement mode for x402 payments. - PRIVATE: Payment only, no input/output data on-chain (most privacy-preserving). - BATCH_HASHED: Aggregates inferences into a Merkle tree with input/output hashes and signatures (default, most cost-efficient). - - INDIVIDUAL_FULL: Records input, output, timestamp, and verification on-chain (maximum auditability). Defaults to BATCH_HASHED. * **`stream (bool, optional)`**: Whether to stream the response. Default is False. @@ -115,9 +114,8 @@ Union[TextGenerationOutput, AsyncGenerator[StreamChunk, None]]: * **`data_settlement_transaction_hash`**: Blockchain transaction hash for the data settlement transaction. ``None`` when the provider does not return data settlement metadata. -* **`data_settlement_blob_id`**: Walrus blob ID for individual data - settlement. ``None`` for private/batch settlement or when the - provider does not return it. +* **`data_settlement_blob_id`**: Walrus blob ID for data settlement. + ``None`` when the provider does not return it. * **`finish_reason`**: Reason the model stopped generating (e.g. ``"stop"``, ``"tool_call"``, ``"error"``). Only populated for chat requests. @@ -179,7 +177,6 @@ Perform inference on an LLM model using completions via TEE. * **`x402_settlement_mode (x402SettlementMode, optional)`**: Settlement mode for x402 payments. - PRIVATE: Payment only, no input/output data on-chain (most privacy-preserving). - BATCH_HASHED: Aggregates inferences into a Merkle tree with input/output hashes and signatures (default, most cost-efficient). - - INDIVIDUAL_FULL: Records input, output, timestamp, and verification on-chain (maximum auditability). Defaults to BATCH_HASHED. **Returns** @@ -194,9 +191,8 @@ TextGenerationOutput: Generated text results including: * **`data_settlement_transaction_hash`**: Blockchain transaction hash for the data settlement transaction. ``None`` when the provider does not return data settlement metadata. -* **`data_settlement_blob_id`**: Walrus blob ID for individual data - settlement. ``None`` for private/batch settlement or when the - provider does not return it. +* **`data_settlement_blob_id`**: Walrus blob ID for data settlement. + ``None`` when the provider does not return it. * **`finish_reason`**: Reason the model stopped generating (e.g. ``"stop"``, ``"tool_call"``, ``"error"``). Only populated for chat requests. @@ -269,4 +265,4 @@ Resolve the current TEE or a specific active registry TEE. This is primarily for backend relays that need SDK-managed TEE routing, TLS pinning, and x402 clients without using the chat/completion helpers -directly, for example when forwarding OHTTP ciphertext. \ No newline at end of file +directly, for example when forwarding OHTTP ciphertext. diff --git a/docs/opengradient/client/twins.md b/docs/opengradient/client/twins.md index b20a8ae..233778a 100644 --- a/docs/opengradient/client/twins.md +++ b/docs/opengradient/client/twins.md @@ -58,9 +58,8 @@ TextGenerationOutput: Generated text results including chat_output and finish_re * **`data_settlement_transaction_hash`**: Blockchain transaction hash for the data settlement transaction. ``None`` when the provider does not return data settlement metadata. -* **`data_settlement_blob_id`**: Walrus blob ID for individual data - settlement. ``None`` for private/batch settlement or when the - provider does not return it. +* **`data_settlement_blob_id`**: Walrus blob ID for data settlement. + ``None`` when the provider does not return it. * **`finish_reason`**: Reason the model stopped generating (e.g. ``"stop"``, ``"tool_call"``, ``"error"``). Only populated for chat requests. diff --git a/docs/opengradient/types.md b/docs/opengradient/types.md index 5c95d89..5527bbd 100644 --- a/docs/opengradient/types.md +++ b/docs/opengradient/types.md @@ -352,7 +352,7 @@ usage information. * **`tee_payment_address`**: Payment address registered for the TEE (final chunk only) * **`data_settlement_transaction_hash`**: Transaction hash for the data settlement transaction, present on the final chunk when available. -* **`data_settlement_blob_id`**: Walrus blob ID for individual data settlement, +* **`data_settlement_blob_id`**: Walrus blob ID for data settlement, present on the final chunk when available. * **`images`**: Generated images returned by image-output models, present on the final chunk when available. Each entry is a ``data:`` URI. @@ -410,7 +410,7 @@ StreamChunk instance * **`tee_payment_address`**: Payment address registered for the TEE (final chunk only) * **`data_settlement_transaction_hash`**: Transaction hash for the data settlement transaction, present on the final chunk when available. -* **`data_settlement_blob_id`**: Walrus blob ID for individual data settlement, +* **`data_settlement_blob_id`**: Walrus blob ID for data settlement, present on the final chunk when available. * **`images`**: Generated images returned by image-output models, present on the final chunk when available. Each entry is a ``data:`` URI. @@ -557,9 +557,8 @@ Trust model: * **`data_settlement_transaction_hash`**: Blockchain transaction hash for the data settlement transaction. ``None`` when the provider does not return data settlement metadata. -* **`data_settlement_blob_id`**: Walrus blob ID for individual data - settlement. ``None`` for private/batch settlement or when the - provider does not return it. +* **`data_settlement_blob_id`**: Walrus blob ID for data settlement. + ``None`` when the provider does not return it. * **`finish_reason`**: Reason the model stopped generating (e.g. ``"stop"``, ``"tool_call"``, ``"error"``). Only populated for chat requests. @@ -633,9 +632,4 @@ privacy, and transaction costs. Aggregates multiple inferences into a single settlement transaction using a Merkle tree containing input hashes, output hashes, and signatures. Most cost-efficient for high-volume applications. - CLI usage: --settlement-mode batch-hashed -* **`INDIVIDUAL_FULL`**: Individual settlement with full metadata. - Records input data, output data, timestamp, and verification on-chain. - Provides maximum transparency and auditability. - Higher gas costs due to larger data storage. - CLI usage: --settlement-mode individual-full \ No newline at end of file + CLI usage: --settlement-mode batch-hashed \ No newline at end of file diff --git a/examples/langchain_react_agent.py b/examples/langchain_react_agent.py index 7d372ca..7004807 100644 --- a/examples/langchain_react_agent.py +++ b/examples/langchain_react_agent.py @@ -26,7 +26,7 @@ private_key=private_key, model_cid=og.TEE_LLM.GPT_4_1_2025_04_14, max_tokens=300, - x402_settlement_mode=og.x402SettlementMode.INDIVIDUAL_FULL, + x402_settlement_mode=og.x402SettlementMode.BATCH_HASHED, ) diff --git a/examples/llm_chat.py b/examples/llm_chat.py index 3204dc7..de9ce3f 100644 --- a/examples/llm_chat.py +++ b/examples/llm_chat.py @@ -16,12 +16,12 @@ async def main(): {"role": "user", "content": "What model are you?"}, ] - # Run inference with full public settlement + # Run inference with batched settlement result = await llm.chat( model=og.TEE_LLM.CLAUDE_OPUS_4_8, messages=messages, max_tokens=300, - x402_settlement_mode=og.x402SettlementMode.INDIVIDUAL_FULL, + x402_settlement_mode=og.x402SettlementMode.BATCH_HASHED, ) print(result.chat_output["content"]) diff --git a/examples/llm_chat_streaming.py b/examples/llm_chat_streaming.py index 3614d2d..5da4c6c 100644 --- a/examples/llm_chat_streaming.py +++ b/examples/llm_chat_streaming.py @@ -14,7 +14,7 @@ async def main(): {"role": "user", "content": "What makes it good for beginners?"}, ] - settlement_mode = og.x402SettlementMode.INDIVIDUAL_FULL + settlement_mode = og.x402SettlementMode.BATCH_HASHED stream = await llm.chat( model=og.TEE_LLM.GPT_4_1_2025_04_14, messages=messages, @@ -27,11 +27,10 @@ async def main(): if chunk.choices[0].delta.content: print(chunk.choices[0].delta.content, end="", flush=True) - if settlement_mode == og.x402SettlementMode.INDIVIDUAL_FULL: - if chunk.data_settlement_blob_id: - print("\n Data Settlement Blob ID: ", chunk.data_settlement_blob_id) - if chunk.data_settlement_transaction_hash: - print("\n Data Settlement Transaction Hash: ", chunk.data_settlement_transaction_hash) + if chunk.data_settlement_blob_id: + print("\n Data Settlement Blob ID: ", chunk.data_settlement_blob_id) + if chunk.data_settlement_transaction_hash: + print("\n Data Settlement Transaction Hash: ", chunk.data_settlement_transaction_hash) asyncio.run(main()) diff --git a/integrationtest/llm/test_llm_chat.py b/integrationtest/llm/test_llm_chat.py index b9c8cbe..305b54c 100644 --- a/integrationtest/llm/test_llm_chat.py +++ b/integrationtest/llm/test_llm_chat.py @@ -135,7 +135,7 @@ async def test_chat(llm_client): model=og.TEE_LLM.GEMINI_2_5_FLASH, messages=messages, max_tokens=50, - x402_settlement_mode=og.x402SettlementMode.INDIVIDUAL_FULL, + x402_settlement_mode=og.x402SettlementMode.BATCH_HASHED, ) assert result is not None @@ -152,7 +152,7 @@ async def test_chat_streaming(llm_client): model=og.TEE_LLM.GEMINI_2_5_FLASH, messages=messages, max_tokens=50, - x402_settlement_mode=og.x402SettlementMode.INDIVIDUAL_FULL, + x402_settlement_mode=og.x402SettlementMode.BATCH_HASHED, stream=True, ) diff --git a/src/opengradient/cli.py b/src/opengradient/cli.py index 7c3b016..183b886 100644 --- a/src/opengradient/cli.py +++ b/src/opengradient/cli.py @@ -73,7 +73,6 @@ def convert(self, value, param, ctx): x402SettlementModes = { "batch-hashed": x402SettlementMode.BATCH_HASHED, "private": x402SettlementMode.PRIVATE, - "individual-full": x402SettlementMode.INDIVIDUAL_FULL, } @@ -384,7 +383,7 @@ def infer(ctx, model_cid: str, inference_mode: str, input_data, input_file: Path "x402_settlement_mode", type=click.Choice(x402SettlementModes.keys()), default="batch-hashed", - help="Settlement mode for x402 payments: private (payment only), batch-hashed (default), individual-full (full data with verification)", + help="Settlement mode for x402 payments: private (payment only), batch-hashed (default)", ) @click.pass_context def completion( @@ -518,7 +517,7 @@ def print_llm_completion_result(model_cid, tx_hash, llm_output, is_vanilla=True, "--x402-settlement-mode", type=click.Choice(x402SettlementModes.keys()), default="batch-hashed", - help="Settlement mode for x402 payments: private (payment only), batch-hashed (default), individual-full (full data with verification)", + help="Settlement mode for x402 payments: private (payment only), batch-hashed (default)", ) @click.option("--stream", is_flag=True, default=False, help="Stream the output from the LLM") @click.pass_context diff --git a/src/opengradient/client/llm.py b/src/opengradient/client/llm.py index a568bae..5550ae5 100644 --- a/src/opengradient/client/llm.py +++ b/src/opengradient/client/llm.py @@ -339,7 +339,6 @@ async def completion( x402_settlement_mode (x402SettlementMode, optional): Settlement mode for x402 payments. - PRIVATE: Payment only, no input/output data on-chain (most privacy-preserving). - BATCH_HASHED: Aggregates inferences into a Merkle tree with input/output hashes and signatures (default, most cost-efficient). - - INDIVIDUAL_FULL: Records input, output, timestamp, and verification on-chain (maximum auditability). Defaults to BATCH_HASHED. Returns: @@ -427,7 +426,6 @@ async def chat( x402_settlement_mode (x402SettlementMode, optional): Settlement mode for x402 payments. - PRIVATE: Payment only, no input/output data on-chain (most privacy-preserving). - BATCH_HASHED: Aggregates inferences into a Merkle tree with input/output hashes and signatures (default, most cost-efficient). - - INDIVIDUAL_FULL: Records input, output, timestamp, and verification on-chain (maximum auditability). Defaults to BATCH_HASHED. stream (bool, optional): Whether to stream the response. Default is False. diff --git a/src/opengradient/types.py b/src/opengradient/types.py index 3d87bdd..f7bedf0 100644 --- a/src/opengradient/types.py +++ b/src/opengradient/types.py @@ -31,12 +31,6 @@ class x402SettlementMode(str, Enum): Most cost-efficient for high-volume applications. CLI usage: --settlement-mode batch-hashed - INDIVIDUAL_FULL: Individual settlement with full metadata. - Records input data, output data, timestamp, and verification on-chain. - Provides maximum transparency and auditability. - Higher gas costs due to larger data storage. - CLI usage: --settlement-mode individual-full - Examples: >>> from opengradient import x402SettlementMode >>> mode = x402SettlementMode.PRIVATE @@ -46,7 +40,6 @@ class x402SettlementMode(str, Enum): PRIVATE = "private" BATCH_HASHED = "batch" - INDIVIDUAL_FULL = "individual" class CandleOrder(IntEnum): @@ -242,7 +235,7 @@ class StreamChunk: tee_payment_address: Payment address registered for the TEE (final chunk only) data_settlement_transaction_hash: Transaction hash for the data settlement transaction, present on the final chunk when available. - data_settlement_blob_id: Walrus blob ID for individual data settlement, + data_settlement_blob_id: Walrus blob ID for data settlement, present on the final chunk when available. images: Generated images returned by image-output models, present on the final chunk when available. Each entry is a ``data:`` URI. @@ -430,9 +423,8 @@ class TextGenerationOutput: data_settlement_transaction_hash: Blockchain transaction hash for the data settlement transaction. ``None`` when the provider does not return data settlement metadata. - data_settlement_blob_id: Walrus blob ID for individual data - settlement. ``None`` for private/batch settlement or when the - provider does not return it. + data_settlement_blob_id: Walrus blob ID for data settlement. + ``None`` when the provider does not return it. finish_reason: Reason the model stopped generating (e.g. ``"stop"``, ``"tool_call"``, ``"error"``). Only populated for chat requests. @@ -453,7 +445,7 @@ class TextGenerationOutput: """Blockchain transaction hash for the data settlement transaction. ``None`` when unavailable.""" data_settlement_blob_id: Optional[str] = None - """Walrus blob ID for individual data settlement. ``None`` when unavailable.""" + """Walrus blob ID for data settlement. ``None`` when unavailable.""" finish_reason: Optional[str] = None """Reason the model stopped generating (e.g. ``"stop"``, ``"tool_call"``, ``"error"``). Only populated for chat requests.""" diff --git a/stresstest/llm.py b/stresstest/llm.py index a234cee..3039bae 100644 --- a/stresstest/llm.py +++ b/stresstest/llm.py @@ -17,7 +17,7 @@ async def main(private_key: str): async def run_prompt(prompt: str): messages = [{"role": "user", "content": prompt}] - await llm.chat(MODEL, messages=messages, max_tokens=50, x402_settlement_mode=og.x402SettlementMode.INDIVIDUAL_FULL) + await llm.chat(MODEL, messages=messages, max_tokens=50, x402_settlement_mode=og.x402SettlementMode.BATCH_HASHED) latencies, failures = await stress_test_wrapper(run_prompt, num_requests=NUM_REQUESTS) diff --git a/tests/client_test.py b/tests/client_test.py index 5ac6b55..e8d0598 100644 --- a/tests/client_test.py +++ b/tests/client_test.py @@ -210,4 +210,7 @@ def test_settlement_modes_values(self): """Test settlement mode enum values.""" assert x402SettlementMode.PRIVATE == "private" assert x402SettlementMode.BATCH_HASHED == "batch" - assert x402SettlementMode.INDIVIDUAL_FULL == "individual" + assert list(x402SettlementMode) == [ + x402SettlementMode.PRIVATE, + x402SettlementMode.BATCH_HASHED, + ] diff --git a/tutorials/01-verifiable-ai-agent.md b/tutorials/01-verifiable-ai-agent.md index 1b95089..b6c00b6 100644 --- a/tutorials/01-verifiable-ai-agent.md +++ b/tutorials/01-verifiable-ai-agent.md @@ -220,9 +220,8 @@ is recorded on-chain: | Mode | What's Stored | Best For | |------|--------------|----------| -| `PRIVATE` | Hashes of input and output only | **Privacy** -- proves execution happened without revealing content | +| `PRIVATE` | Payment only; no input/output data | **Privacy** -- keeps inference data off-chain | | `BATCH_HASHED` | Batch hash of multiple inferences | **Cost efficiency** -- reduces per-call gas costs (default) | -| `INDIVIDUAL_FULL` | Full model info, input, output, and metadata | **Transparency** -- complete auditability for compliance | Choose based on your requirements: @@ -234,13 +233,6 @@ llm_dev = og.agents.langchain_adapter( x402_settlement_mode=og.x402SettlementMode.BATCH_HASHED, ) -# For production financial applications -- full audit trail -llm_prod = og.agents.langchain_adapter( - private_key=os.environ["OG_PRIVATE_KEY"], - model_cid=og.TEE_LLM.GPT_4_1_2025_04_14, - x402_settlement_mode=og.x402SettlementMode.INDIVIDUAL_FULL, -) - # For privacy-sensitive applications -- minimal on-chain footprint llm_private = og.agents.langchain_adapter( private_key=os.environ["OG_PRIVATE_KEY"], @@ -354,5 +346,5 @@ if __name__ == "__main__": models deployed on OpenGradient. - **Read workflow results**: Use `og.alphasense.create_read_workflow_tool` to read from scheduled on-chain workflows that run models automatically. -- **Go to production**: Switch settlement mode to `INDIVIDUAL_FULL` and store the - payment hashes and transaction hashes for your compliance records. +- **Go to production**: Store payment hashes and transaction hashes for your + compliance records. diff --git a/tutorials/02-streaming-multi-provider.md b/tutorials/02-streaming-multi-provider.md index 1ab3baf..b30c181 100644 --- a/tutorials/02-streaming-multi-provider.md +++ b/tutorials/02-streaming-multi-provider.md @@ -163,16 +163,15 @@ Each `StreamChoice` contains a `StreamDelta` with optional `content`, `role`, an ## Step 4: Settlement Modes Every LLM call settles on-chain. The `x402_settlement_mode` parameter controls the -privacy/cost/transparency trade-off: +privacy/cost trade-off: | Mode | On-Chain Data | Use Case | |------|--------------|----------| -| `PRIVATE` | Input/output hashes only | **Privacy** -- prove execution without revealing content | +| `PRIVATE` | Payment only; no input/output data | **Privacy** -- keep inference data off-chain | | `BATCH_HASHED` | Batch digest of multiple calls | **Cost efficiency** -- lower gas per inference (default) | -| `INDIVIDUAL_FULL` | Full model, input, output, metadata | **Transparency** -- complete audit trail | ```python -# Privacy-first: only hashes stored on-chain +# Privacy-first: no inference data stored on-chain result_private = await llm.chat( model=og.TEE_LLM.CLAUDE_SONNET_4_6, messages=[{"role": "user", "content": "Sensitive query here."}], @@ -189,18 +188,9 @@ result_batch = await llm.chat( x402_settlement_mode=og.x402SettlementMode.BATCH_HASHED, ) print(f"Payment hash (BATCH_HASHED): {result_batch.payment_hash}") - -# Full transparency: everything on-chain -result_transparent = await llm.chat( - model=og.TEE_LLM.CLAUDE_SONNET_4_6, - messages=[{"role": "user", "content": "Auditable query."}], - max_tokens=100, - x402_settlement_mode=og.x402SettlementMode.INDIVIDUAL_FULL, -) -print(f"Payment hash (INDIVIDUAL_FULL): {result_transparent.payment_hash}") ``` -All three calls return a `payment_hash` you can look up on-chain. The difference is +Both calls return a `payment_hash` you can look up on-chain. The difference is how much detail the on-chain record contains. Store these hashes if you need an audit trail -- they are the on-chain receipts for each inference call. @@ -315,9 +305,8 @@ async def main(): # ── Settlement modes ────────────────────────────────────────────────── for mode_name, mode in [ - ("PRIVATE", og.x402SettlementMode.PRIVATE), - ("BATCH_HASHED", og.x402SettlementMode.BATCH_HASHED), - ("INDIVIDUAL_FULL", og.x402SettlementMode.INDIVIDUAL_FULL), + ("PRIVATE", og.x402SettlementMode.PRIVATE), + ("BATCH_HASHED", og.x402SettlementMode.BATCH_HASHED), ]: try: r = await llm.chat( diff --git a/tutorials/03-verified-tool-calling.md b/tutorials/03-verified-tool-calling.md index cc75f06..eb05734 100644 --- a/tutorials/03-verified-tool-calling.md +++ b/tutorials/03-verified-tool-calling.md @@ -414,5 +414,5 @@ if __name__ == "__main__": even during multi-turn tool loops. See **Tutorial 2** for streaming basics. - **Use different providers**: Swap `og.TEE_LLM.GPT_5` for `CLAUDE_SONNET_4_6` or `GEMINI_2_5_FLASH` -- tool calling works across all providers. -- **Add settlement transparency**: Switch to `INDIVIDUAL_FULL` to store the full - tool-calling reasoning chain on-chain for audit purposes. +- **Record settlement receipts**: Store payment hashes and transaction hashes for + audit purposes.