Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ on:
required: false
type: string
push:
branches:
- main
tags:
- 'v*'

Expand Down Expand Up @@ -85,12 +87,6 @@ jobs:
sed -i "s/version = \".*\"/version = \"$NEW_VERSION\"/" pyproject.toml
echo "Updated pyproject.toml with version $NEW_VERSION"

- name: Run pre-commit checks
run: |
echo "Running code quality checks..."
uv run ruff check .
uv run ruff format --check .

- name: Build package
run: |
echo "Building package..."
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ where = ["src"]
expert = ["prompts/*.md"]

[tool.ruff]
line-length = 88
line-length = 100
target-version = "py313"

[tool.ruff.lint]
Expand Down
34 changes: 23 additions & 11 deletions src/expert/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def __init__(self, config: Config):
self.agent = None
self.checkpointer = InMemorySaver()
self._load_prompts()
self.opik_config = None

def _load_prompts(self):
"""Load prompt templates from files."""
Expand Down Expand Up @@ -91,19 +92,28 @@ async def setup(self):
prompt=self.system_prompt,
)

# Initialize Opik tracer if configured
# Store Opik configuration if configured
if self.config.opik_api_key:
opik_config = self.config.opik_config
project_name = opik_config.get("project_name", "invopop-expert")

self.tracer = OpikTracer(
graph=self.agent.get_graph(xray=True), project_name=project_name
)
self.opik_config = self.config.opik_config
project_name = self.opik_config.get("project_name", "invopop-expert")
print(f"✅ Opik tracing enabled for project: {project_name}")
else:
self.tracer = None
self.opik_config = None
print("⚠️ Opik tracing disabled - missing API key")
Comment thread
pmenendz marked this conversation as resolved.

def _create_opik_tracer(self, user_thread_id: str) -> OpikTracer | None:
"""Create a new OpikTracer instance for the given thread_id."""
if not self.opik_config:
return None

project_name = self.opik_config.get("project_name", "invopop-expert")

# Create tracer with user thread_id in metadata for proper thread tracking
tracer = OpikTracer(
graph=self.agent.get_graph(xray=True), project_name=project_name, tags=[user_thread_id]
)
return tracer

async def get_response(self, user_input: str, thread_id: str) -> str:
"""Get response from the agent for a given input."""
if not self.agent:
Expand All @@ -113,9 +123,11 @@ async def get_response(self, user_input: str, thread_id: str) -> str:
"configurable": {"thread_id": thread_id},
}

# Add tracer callback if available
if self.tracer:
thread_config["callbacks"] = [self.tracer]
# Create a new tracer instance for this conversation
# The tracer uses the original thread_id in metadata for proper Opik thread tracking
tracer = self._create_opik_tracer(thread_id)
if tracer:
thread_config["callbacks"] = [tracer]

async for chunk in self.agent.astream(
{"messages": [{"role": "user", "content": user_input}]}, thread_config
Expand Down
8 changes: 2 additions & 6 deletions src/expert/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@ def _load_config(self) -> dict[str, Any]:
with open(self.config_path) as f:
return yaml.safe_load(f)
except FileNotFoundError as e:
raise FileNotFoundError(
f"Configuration file not found: {self.config_path}"
) from e
raise FileNotFoundError(f"Configuration file not found: {self.config_path}") from e
except yaml.YAMLError as e:
raise ValueError(f"Invalid YAML configuration: {e}") from e

Expand Down Expand Up @@ -92,9 +90,7 @@ def mcp_config(self) -> dict[str, Any]:
# Expand home directory paths
for server_config in config.values():
if "args" in server_config:
server_config["args"] = [
os.path.expanduser(arg) for arg in server_config["args"]
]
server_config["args"] = [os.path.expanduser(arg) for arg in server_config["args"]]

return config

Expand Down
Loading