Skip to content

Commit 55810d0

Browse files
authored
Merge pull request #30 from kayba-ai/revert-27-no-opik-warning
Revert "fix: eliminate Opik integration warnings for base installs"
2 parents de5e537 + 060be70 commit 55810d0

13 files changed

Lines changed: 136 additions & 248 deletions

File tree

ace/llm_providers/litellm_client.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -240,13 +240,6 @@ def _setup_router(self) -> None:
240240

241241
def _setup_opik_integration(self) -> None:
242242
"""Set up Opik integration for automatic token and cost tracking."""
243-
# Check if explicitly disabled
244-
if os.environ.get("OPIK_DISABLED", "").lower() in ("true", "1", "yes"):
245-
logger.debug(
246-
"Opik integration disabled via OPIK_DISABLED environment variable"
247-
)
248-
return
249-
250243
try:
251244
# Import observability module
252245
from ..observability import get_integration

ace/observability/opik_integration.py

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from __future__ import annotations
99

1010
import logging
11-
import os
1211
from datetime import datetime
1312
from typing import Any, Dict, List, Optional, Union
1413
from dataclasses import asdict
@@ -49,11 +48,6 @@ def decorator(func):
4948
logger = logging.getLogger(__name__)
5049

5150

52-
def _should_skip_opik() -> bool:
53-
"""Check if Opik should be disabled via environment variable."""
54-
return os.environ.get("OPIK_DISABLED", "").lower() in ("true", "1", "yes")
55-
56-
5751
class OpikIntegration:
5852
"""
5953
Main integration class for ACE + Opik observability.
@@ -86,12 +80,10 @@ def __init__(
8680
opik.configure(use_local=True)
8781
logger.info(f"Opik configured locally for project: {project_name}")
8882
except Exception as e:
89-
logger.debug(f"Opik configuration skipped: {e}")
83+
logger.warning(f"Failed to configure Opik: {e}")
9084
self.enabled = False
9185
elif not OPIK_AVAILABLE:
92-
logger.debug(
93-
"Opik not available. Install with: pip install ace-framework[observability]"
94-
)
86+
logger.warning("Opik not available. Install with: pip install opik")
9587

9688
def log_bullet_evolution(
9789
self,
@@ -343,12 +335,7 @@ def get_integration() -> OpikIntegration:
343335
"""Get or create global Opik integration instance."""
344336
global _global_integration
345337
if _global_integration is None:
346-
if _should_skip_opik():
347-
# Return disabled integration
348-
_global_integration = OpikIntegration(enable_auto_config=False)
349-
_global_integration.enabled = False
350-
else:
351-
_global_integration = OpikIntegration()
338+
_global_integration = OpikIntegration()
352339
return _global_integration
353340

354341

examples/LMstudio/lmstudio_starter_template.py

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,12 @@ def check_lm_studio_running():
2323
response = requests.get("http://localhost:1234/v1/models", timeout=5)
2424
if response.status_code == 200:
2525
models = response.json()
26-
if models.get("data"):
27-
return True, models["data"][0]["id"] # Return first available model
26+
if models.get('data'):
27+
return True, models['data'][0]['id'] # Return first available model
2828
return False, "No models loaded in LM Studio"
2929
return False, f"LM Studio responded with status {response.status_code}"
3030
except requests.ConnectionError:
31-
return (
32-
False,
33-
"Cannot connect to LM Studio. Make sure it's running on port 1234.",
34-
)
31+
return False, "Cannot connect to LM Studio. Make sure it's running on port 1234."
3532
except Exception as e:
3633
return False, f"Error checking LM Studio: {e}"
3734

@@ -57,15 +54,14 @@ def main():
5754

5855
# LM Studio configuration for LiteLLM
5956
import os
60-
6157
os.environ["LM_STUDIO_API_BASE"] = "http://localhost:1234/v1"
6258

6359
agent = ACELiteLLM(
6460
model="lm_studio/qwen3-vl-8b",
6561
max_tokens=1024,
6662
temperature=0.2,
6763
is_learning=True,
68-
playbook_path=str(playbook_path) if playbook_path.exists() else None,
64+
playbook_path=str(playbook_path) if playbook_path.exists() else None
6965
)
7066

7167
# 2. Try asking questions before learning
@@ -110,7 +106,7 @@ def main():
110106
"What is 3+3?",
111107
"What color is grass?",
112108
"What is the capital of Italy?",
113-
"Which planet is closest to the Sun?",
109+
"Which planet is closest to the Sun?"
114110
]
115111

116112
for question in test_questions:
@@ -129,11 +125,7 @@ def main():
129125
helpful = bullet.helpful
130126
harmful = bullet.harmful
131127
score = f"(+{helpful}/-{harmful})"
132-
content_preview = (
133-
bullet.content[:80] + "..."
134-
if len(bullet.content) > 80
135-
else bullet.content
136-
)
128+
content_preview = bullet.content[:80] + "..." if len(bullet.content) > 80 else bullet.content
137129
print(f" {i}. {content_preview} {score}")
138130

139131
# 7. Save learned knowledge for future use
@@ -148,4 +140,4 @@ def main():
148140

149141

150142
if __name__ == "__main__":
151-
main()
143+
main()

examples/browser-use/TEMPLATE.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ async def main():
2020
"""Minimal ACE browser automation example."""
2121

2222
# Create ACE agent
23-
agent = ACEAgent(llm=ChatBrowserUse(), ace_model="gpt-4o-mini")
23+
agent = ACEAgent(
24+
llm=ChatBrowserUse(),
25+
ace_model="gpt-4o-mini"
26+
)
2427

2528
# Define your tasks
2629
tasks = [
@@ -44,4 +47,4 @@ async def main():
4447

4548

4649
if __name__ == "__main__":
47-
asyncio.run(main())
50+
asyncio.run(main())

examples/browser-use/domain-checker/ace_domain_checker.py

Lines changed: 33 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,11 @@
3232
from ace.observability import configure_opik
3333
from browser_use import ChatBrowserUse
3434

35-
3635
# Utility function for timeout calculation
3736
def calculate_timeout_steps(timeout_seconds: float) -> int:
3837
"""Calculate steps for timeout based on 1 step per 12 seconds."""
3938
return int(timeout_seconds // 12)
4039

41-
4240
# Import domain-specific utilities
4341
from domain_utils import get_test_domains
4442

@@ -68,9 +66,7 @@ def calculate_timeout_steps(timeout_seconds: float) -> int:
6866
"""
6967

7068

71-
def get_ace_token_usage(
72-
run_start_time: datetime.datetime = None,
73-
) -> tuple[int, int, int, int]:
69+
def get_ace_token_usage(run_start_time: datetime.datetime = None) -> tuple[int, int, int, int]:
7470
"""Query Opik for ACE token usage only.
7571
7672
Returns:
@@ -112,7 +108,9 @@ def get_ace_token_usage(
112108
filter_string=f'start_time >= "{recent_time}"',
113109
max_results=50,
114110
)
115-
print(f" 📊 Found {len(traces)} recent traces in '{project}' project")
111+
print(
112+
f" 📊 Found {len(traces)} recent traces in '{project}' project"
113+
)
116114
all_traces.extend(traces)
117115
except Exception as e:
118116
print(f" ⚠️ Failed to search '{project}' project: {e}")
@@ -196,32 +194,21 @@ def parse_domain_result(output: str, domain: str) -> dict:
196194
return {"status": "TAKEN"}
197195

198196
# Check for natural language indicators of availability
199-
elif (
200-
("AVAILABLE" in output_upper and domain_upper in output_upper)
201-
or ("ADD TO CART" in output_upper and domain_upper in output_upper)
202-
or ("PRICE:" in output_upper and domain_upper in output_upper)
203-
or (
204-
"REGISTRATION" in output_upper
205-
and "AVAILABLE" in output_upper
206-
and domain_upper in output_upper
207-
)
208-
):
197+
elif ("AVAILABLE" in output_upper and domain_upper in output_upper) or \
198+
("ADD TO CART" in output_upper and domain_upper in output_upper) or \
199+
("PRICE:" in output_upper and domain_upper in output_upper) or \
200+
("REGISTRATION" in output_upper and "AVAILABLE" in output_upper and domain_upper in output_upper):
209201
return {"status": "AVAILABLE"}
210202

211203
# Check for natural language indicators of taken/unavailable
212-
elif (
213-
("TAKEN" in output_upper and domain_upper in output_upper)
214-
or ("REGISTERED" in output_upper and domain_upper in output_upper)
215-
or ("NOT AVAILABLE" in output_upper and domain_upper in output_upper)
216-
or ("UNAVAILABLE" in output_upper and domain_upper in output_upper)
217-
):
204+
elif ("TAKEN" in output_upper and domain_upper in output_upper) or \
205+
("REGISTERED" in output_upper and domain_upper in output_upper) or \
206+
("NOT AVAILABLE" in output_upper and domain_upper in output_upper) or \
207+
("UNAVAILABLE" in output_upper and domain_upper in output_upper):
218208
return {"status": "TAKEN"}
219209

220210
else:
221-
return {
222-
"status": "ERROR",
223-
"reason": f"Could not parse result: {output[:100]}...",
224-
}
211+
return {"status": "ERROR", "reason": f"Could not parse result: {output[:100]}..."}
225212

226213

227214
async def check_single_domain(agent: ACEAgent, domain: str) -> dict:
@@ -236,6 +223,7 @@ async def check_single_domain(agent: ACEAgent, domain: str) -> dict:
236223
# Track browser-use tokens across all attempts
237224
total_browseruse_tokens = 0
238225

226+
239227
for attempt in range(max_retries):
240228
print(f" 🔄 Attempt {attempt + 1}/{max_retries}")
241229

@@ -245,7 +233,8 @@ async def check_single_domain(agent: ACEAgent, domain: str) -> dict:
245233

246234
# Run domain check with ACE learning (with timeout like baseline)
247235
history = await asyncio.wait_for(
248-
agent.run(task=task, max_steps=25), timeout=180.0
236+
agent.run(task=task, max_steps=25),
237+
timeout=180.0
249238
)
250239

251240
# Extract results
@@ -302,12 +291,10 @@ async def check_single_domain(agent: ACEAgent, domain: str) -> dict:
302291
print(f" ⚠️ Could not get tokens from history: {e}")
303292

304293
# Method 2: Try agent internal token tracking (ACEAgent specific)
305-
if attempt_tokens == 0 and hasattr(agent, "browser_llm"):
294+
if attempt_tokens == 0 and hasattr(agent, 'browser_llm'):
306295
try:
307296
# ACEAgent uses browser_use Agent internally, check if it has token tracking
308-
if hasattr(agent, "_last_agent") and hasattr(
309-
agent._last_agent, "token_cost_service"
310-
):
297+
if hasattr(agent, '_last_agent') and hasattr(agent._last_agent, 'token_cost_service'):
311298
usage_summary = (
312299
await agent._last_agent.token_cost_service.get_usage_summary()
313300
)
@@ -367,13 +354,9 @@ async def check_single_domain(agent: ACEAgent, domain: str) -> dict:
367354

368355
steps = actual_steps + timeout_steps
369356
total_steps += steps
370-
attempt_details.append(
371-
f"attempt {attempt + 1}: {steps} steps (timeout, +{timeout_steps} for duration)"
372-
)
357+
attempt_details.append(f"attempt {attempt + 1}: {steps} steps (timeout, +{timeout_steps} for duration)")
373358
last_error = f"Timeout on attempt {attempt + 1}"
374-
print(
375-
f" ⏰ Timeout after {actual_steps} steps (+{timeout_steps} timeout penalty)"
376-
)
359+
print(f" ⏰ Timeout after {actual_steps} steps (+{timeout_steps} timeout penalty)")
377360

378361
except Exception as e:
379362
# Get actual steps even on error
@@ -426,12 +409,10 @@ async def check_single_domain(agent: ACEAgent, domain: str) -> dict:
426409
print(f" ⚠️ Could not get tokens from history: {e}")
427410

428411
# Method 2: Try agent internal token tracking (ACEAgent specific)
429-
if attempt_tokens == 0 and hasattr(agent, "browser_llm"):
412+
if attempt_tokens == 0 and hasattr(agent, 'browser_llm'):
430413
try:
431414
# ACEAgent uses browser_use Agent internally, check if it has token tracking
432-
if hasattr(agent, "_last_agent") and hasattr(
433-
agent._last_agent, "token_cost_service"
434-
):
415+
if hasattr(agent, '_last_agent') and hasattr(agent._last_agent, 'token_cost_service'):
435416
usage_summary = (
436417
await agent._last_agent.token_cost_service.get_usage_summary()
437418
)
@@ -451,6 +432,7 @@ async def check_single_domain(agent: ACEAgent, domain: str) -> dict:
451432
f" 🤖 Attempt {attempt + 1} tokens: {attempt_tokens} (total: {total_browseruse_tokens})"
452433
)
453434

435+
454436
# All retries failed - use accumulated tokens from all attempts
455437
print(f" ❌ All {max_retries} attempts failed")
456438
return {
@@ -459,7 +441,7 @@ async def check_single_domain(agent: ACEAgent, domain: str) -> dict:
459441
"success": False,
460442
"correct": False,
461443
"expected": "AVAILABLE",
462-
"steps": steps if "steps" in locals() else 0,
444+
"steps": steps if 'steps' in locals() else 0,
463445
"total_steps": total_steps,
464446
"error": f"Failed after {max_retries} attempts. Last error: {last_error}",
465447
"attempt": max_retries,
@@ -490,12 +472,12 @@ async def main():
490472

491473
# Create ACE agent - handles everything automatically!
492474
agent = ACEAgent(
493-
llm=ChatBrowserUse(), # Browser automation LLM
494-
ace_model="claude-haiku-4-5-20251001", # ACE learning LLM
495-
ace_max_tokens=4096, # Enough for domain check analysis
475+
llm=ChatBrowserUse(), # Browser automation LLM
476+
ace_model="claude-haiku-4-5-20251001", # ACE learning LLM
477+
ace_max_tokens=4096, # Enough for domain check analysis
496478
playbook_path=str(playbook_path) if playbook_path.exists() else None,
497-
max_steps=25, # Browser automation steps
498-
calculate_cost=True, # Track usage
479+
max_steps=25, # Browser automation steps
480+
calculate_cost=True # Track usage
499481
)
500482

501483
# Show current knowledge
@@ -562,9 +544,7 @@ async def main():
562544
print(f"\n{'='*60}")
563545
print("📊 DOMAIN CHECK RESULTS")
564546
print("=" * 60)
565-
print(
566-
f"{'#':<3} {'Domain':<25} {'Status':<10} {'Acc':<4} {'Steps':<8} {'Browser-Tokens':<13} {'Details'}"
567-
)
547+
print(f"{'#':<3} {'Domain':<25} {'Status':<10} {'Acc':<4} {'Steps':<8} {'Browser-Tokens':<13} {'Details'}")
568548
print("-" * 93)
569549

570550
total_steps = 0
@@ -593,9 +573,7 @@ async def main():
593573
accuracy_indicator = "✓" if correct else "✗"
594574
browseruse_tokens = result.get("browseruse_tokens", 0)
595575

596-
print(
597-
f"{i:<3} {result['domain']:<25} {result['status']:<10} {accuracy_indicator:<4} {total_steps_domain:<8} {browseruse_tokens:<12} {step_details}"
598-
)
576+
print(f"{i:<3} {result['domain']:<25} {result['status']:<10} {accuracy_indicator:<4} {total_steps_domain:<8} {browseruse_tokens:<12} {step_details}")
599577

600578
if not correct and result["success"]:
601579
expected = result.get("expected", "UNKNOWN")
@@ -652,9 +630,7 @@ async def main():
652630
for i, bullet in enumerate(recent_strategies, 1):
653631
helpful = bullet.helpful
654632
harmful = bullet.harmful
655-
effectiveness = (
656-
"✅" if helpful > harmful else "⚠️" if helpful == harmful else "❌"
657-
)
633+
effectiveness = "✅" if helpful > harmful else "⚠️" if helpful == harmful else "❌"
658634
print(f"{i}. {effectiveness} {bullet.content}")
659635
print(f" (+{helpful}/-{harmful})")
660636

@@ -670,4 +646,4 @@ async def main():
670646

671647

672648
if __name__ == "__main__":
673-
asyncio.run(main())
649+
asyncio.run(main())

examples/browser-use/domain-checker/baseline_domain_checker.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,11 @@
1818
# Import common utilities from parent directory
1919
import sys
2020

21-
2221
# Utility function for timeout calculation
2322
def calculate_timeout_steps(timeout_seconds: float) -> int:
2423
"""Calculate steps for timeout based on 1 step per 12 seconds."""
2524
return int(timeout_seconds // 12)
2625

27-
2826
# Import domain-specific utilities from local module
2927
from domain_utils import (
3028
get_test_domains,
@@ -71,6 +69,7 @@ async def check_domain(domain: str, headless: bool = True):
7169
# Run with timeout
7270
history = await asyncio.wait_for(agent.run(), timeout=180.0)
7371

72+
7473
# Parse result (back to original working logic)
7574
output = history.final_result() if hasattr(history, "final_result") else ""
7675
steps = (

0 commit comments

Comments
 (0)