Skip to content

Commit f1aa789

Browse files
author
balogh.adam@icloud.com
committed
ete
1 parent 33184f7 commit f1aa789

1 file changed

Lines changed: 72 additions & 69 deletions

File tree

Lines changed: 72 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import asyncio
21
import os
3-
import unittest
2+
import time
43

4+
import pytest
55
from eth_account import Account
66
from web3 import Web3
77

@@ -76,71 +76,74 @@ def _fund_account(funder_key: str, recipient_address: str):
7676
if opg_receipt.status != 1:
7777
raise RuntimeError(f"OPG transfer failed: {opg_hash.hex()}")
7878

79+
# Wait for the recipient balance to be visible on the RPC node
80+
for _ in range(10):
81+
if w3.eth.get_balance(recipient) > 0:
82+
break
83+
time.sleep(1)
84+
else:
85+
raise RuntimeError("Recipient ETH balance is still 0 after funding")
7986

80-
class TestLLMChat(unittest.TestCase):
81-
@classmethod
82-
def setUpClass(cls):
83-
"""Create a fresh account and fund it from the funder wallet."""
84-
funder_key = os.environ.get("PRIVATE_KEY")
85-
if not funder_key:
86-
raise ValueError("PRIVATE_KEY environment variable is not set")
87-
88-
# Generate a fresh ephemeral account
89-
cls._test_account = Account.create()
90-
print(f"\nTest account: {cls._test_account.address}")
91-
92-
# Fund it with ETH + OPG from the funder
93-
_fund_account(funder_key, cls._test_account.address)
94-
print("Account funded with ETH and OPG")
95-
96-
# Initialize LLM client with the fresh account
97-
cls._llm = og.LLM(private_key=cls._test_account.key.hex())
98-
cls._llm.ensure_opg_approval(opg_amount=OPG_FUND_AMOUNT)
99-
print("Permit2 approval complete")
100-
101-
def test_chat(self):
102-
async def run():
103-
messages = [
104-
{"role": "user", "content": "What is the capital of France? Reply in one word."},
105-
]
106-
107-
result = await self._llm.chat(
108-
model=og.TEE_LLM.GEMINI_2_5_FLASH,
109-
messages=messages,
110-
max_tokens=50,
111-
x402_settlement_mode=og.x402SettlementMode.INDIVIDUAL_FULL,
112-
)
113-
114-
self.assertIsNotNone(result)
115-
self.assertIn("Paris", result.chat_output["content"])
116-
117-
asyncio.run(run())
118-
119-
def test_chat_streaming(self):
120-
async def run():
121-
messages = [
122-
{"role": "user", "content": "What is 2 + 2? Reply with just the number."},
123-
]
124-
125-
stream = await self._llm.chat(
126-
model=og.TEE_LLM.GEMINI_2_5_FLASH,
127-
messages=messages,
128-
max_tokens=50,
129-
x402_settlement_mode=og.x402SettlementMode.INDIVIDUAL_FULL,
130-
stream=True,
131-
)
132-
133-
chunks = []
134-
async for chunk in stream:
135-
if chunk.choices[0].delta.content:
136-
chunks.append(chunk.choices[0].delta.content)
137-
138-
full_response = "".join(chunks)
139-
self.assertTrue(len(chunks) > 0, "Expected at least one streamed chunk")
140-
self.assertIn("4", full_response)
141-
142-
asyncio.run(run())
143-
144-
145-
if __name__ == "__main__":
146-
unittest.main()
87+
88+
@pytest.fixture(scope="module")
89+
def llm_client():
90+
"""Create a fresh account, fund it, and return an initialized LLM client."""
91+
funder_key = os.environ.get("PRIVATE_KEY")
92+
if not funder_key:
93+
pytest.skip("PRIVATE_KEY environment variable is not set")
94+
95+
account = Account.create()
96+
print(f"\nTest account: {account.address}")
97+
98+
_fund_account(funder_key, account.address)
99+
print("Account funded with ETH and OPG")
100+
101+
llm = og.LLM(private_key=account.key.hex())
102+
llm.ensure_opg_approval(opg_amount=OPG_FUND_AMOUNT)
103+
print("Permit2 approval complete")
104+
105+
# Wait for the approval to propagate on-chain
106+
time.sleep(2)
107+
108+
return llm
109+
110+
111+
@pytest.mark.asyncio(loop_scope="module")
112+
async def test_chat(llm_client):
113+
messages = [
114+
{"role": "user", "content": "What is the capital of France? Reply in one word."},
115+
]
116+
117+
result = await llm_client.chat(
118+
model=og.TEE_LLM.GEMINI_2_5_FLASH,
119+
messages=messages,
120+
max_tokens=50,
121+
x402_settlement_mode=og.x402SettlementMode.INDIVIDUAL_FULL,
122+
)
123+
124+
assert result is not None
125+
assert "Paris" in result.chat_output["content"]
126+
127+
128+
@pytest.mark.asyncio(loop_scope="module")
129+
async def test_chat_streaming(llm_client):
130+
messages = [
131+
{"role": "user", "content": "What is 2 + 2? Reply with just the number."},
132+
]
133+
134+
stream = await llm_client.chat(
135+
model=og.TEE_LLM.GEMINI_2_5_FLASH,
136+
messages=messages,
137+
max_tokens=50,
138+
x402_settlement_mode=og.x402SettlementMode.INDIVIDUAL_FULL,
139+
stream=True,
140+
)
141+
142+
chunks = []
143+
async for chunk in stream:
144+
if chunk.choices[0].delta.content:
145+
chunks.append(chunk.choices[0].delta.content)
146+
147+
full_response = "".join(chunks)
148+
assert len(chunks) > 0, "Expected at least one streamed chunk"
149+
assert "4" in full_response

0 commit comments

Comments
 (0)