Compare commits

..

No commits in common. "master" and "CREWAI-integration" have entirely different histories.

5 changed files with 16 additions and 35 deletions

View File

@ -15,12 +15,12 @@ jobs:
- name: Install dependencies - name: Install dependencies
shell: bash shell: bash
run: | run: |
apt update -qq apt update && apt upgrade -y
apt install -y -qq python-is-python3 pip python3-venv libmagic-dev git apt install rustc cargo python-is-python3 pip python3-venv python3-virtualenv libmagic-dev git -y
python -m venv .venv virtualenv .venv
source .venv/bin/activate source .venv/bin/activate
pip install --upgrade pip -q pip install --upgrade pip
pip install -r requirements.txt --prefer-binary -q pip install -r requirements.txt
git config --global user.name "Blog Creator" git config --global user.name "Blog Creator"
git config --global user.email "ridgway.infrastructure@gmail.com" git config --global user.email "ridgway.infrastructure@gmail.com"
git config --global push.autoSetupRemote true git config --global push.autoSetupRemote true

View File

@ -17,19 +17,14 @@ journalist draft is chunked, embedded, and stored in a collection; the editor
receives the top-N most relevant chunks as context. receives the top-N most relevant chunks as context.
""" """
from __future__ import annotations
import json import json
import os import os
import random import random
import re import re
import string import string
from datetime import datetime from datetime import datetime
from typing import TYPE_CHECKING
if TYPE_CHECKING:
import chromadb # noqa: F811
import chromadb
from crewai.flow.flow import Flow, listen, start from crewai.flow.flow import Flow, listen, start
from ollama import Client from ollama import Client
from pydantic import BaseModel, ConfigDict from pydantic import BaseModel, ConfigDict
@ -90,21 +85,7 @@ class BlogFlow(Flow[BlogFlowState]):
) )
@staticmethod @staticmethod
def _get_chroma_client() -> "chromadb.HttpClient": def _get_chroma_client() -> chromadb.HttpClient:
# Lazily import chromadb here rather than at module level.
# chromadb unconditionally loads hnswlib (a native C++ library
# compiled with AVX instructions) even when using HttpClient
# to talk to an external ChromaDB server. Deferring the import
# avoids "Illegal instruction" (SIGILL) crashes in environments
# that lack AVX support (e.g. act, older CI runners).
try:
import chromadb
except ImportError as exc:
raise RuntimeError(
"chromadb is required for the editor phase but could not be "
f"imported: {exc}"
) from exc
chroma_port = int(os.environ["CHROMA_PORT"]) chroma_port = int(os.environ["CHROMA_PORT"])
return chromadb.HttpClient(host=os.environ["CHROMA_HOST"], port=chroma_port) return chromadb.HttpClient(host=os.environ["CHROMA_HOST"], port=chroma_port)
@ -146,7 +127,7 @@ class BlogFlow(Flow[BlogFlowState]):
print(f"Error generating embeddings: {exc}") print(f"Error generating embeddings: {exc}")
return [] return []
def _load_drafts_to_vector_db(self, drafts: list[str]) -> "chromadb.Collection": def _load_drafts_to_vector_db(self, drafts: list[str]) -> chromadb.Collection:
"""Load journalist drafts into a new ChromaDB collection and return it.""" """Load journalist drafts into a new ChromaDB collection and return it."""
chroma = self._get_chroma_client() chroma = self._get_chroma_client()
collection_name = ( collection_name = (
@ -184,7 +165,7 @@ class BlogFlow(Flow[BlogFlowState]):
return collection return collection
@staticmethod @staticmethod
def _query_vector_db(collection: "chromadb.Collection", query_text: str) -> str: def _query_vector_db(collection: chromadb.Collection, query_text: str) -> str:
"""Query the ChromaDB collection and return the most relevant """Query the ChromaDB collection and return the most relevant
document chunks joined as a single string.""" document chunks joined as a single string."""
ollama_client = BlogFlow._get_ollama_client() ollama_client = BlogFlow._get_ollama_client()

View File

@ -140,8 +140,8 @@ class OllamaGenerator:
) )
return response["message"]["content"] return response["message"]["content"]
# Retry mechanism with 60-minute timeout (bumped for large context models) # Retry mechanism with 30-minute timeout (same as the original)
timeout_seconds = 60 * 60 timeout_seconds = 30 * 60
max_retries = 3 max_retries = 3
for attempt in range(max_retries): for attempt in range(max_retries):

View File

@ -102,7 +102,7 @@ class OllamaWebSearchTool(BaseTool):
"Authorization": f"Bearer {api_key}", "Authorization": f"Bearer {api_key}",
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
timeout=60.0, timeout=30.0,
) )
# Raise for HTTP errors so we can catch them with specific messages # Raise for HTTP errors so we can catch them with specific messages

View File

@ -42,7 +42,7 @@ class GitRepository:
print(f"Cloning failed: {e}") print(f"Cloning failed: {e}")
return False return False
def fetch(self, remote_name="origin", ref_name="master"): def fetch(self, remote_name="origin", ref_name="main"):
"""Fetch updates from a remote repository with authentication""" """Fetch updates from a remote repository with authentication"""
try: try:
self.repo.remotes[remote_name].fetch(ref_name=ref_name) self.repo.remotes[remote_name].fetch(ref_name=ref_name)
@ -51,7 +51,7 @@ class GitRepository:
print(f"Fetching failed: {e}") print(f"Fetching failed: {e}")
return False return False
def pull(self, remote_name="origin", ref_name="master"): def pull(self, remote_name="origin", ref_name="main"):
"""Pull updates from a remote repository with authentication""" """Pull updates from a remote repository with authentication"""
print("Pulling Latest Updates (if any)") print("Pulling Latest Updates (if any)")
try: try:
@ -93,8 +93,8 @@ class GitRepository:
self.repo.git.checkout(title) self.repo.git.checkout(title)
self.pull(ref_name=title) self.pull(ref_name=title)
else: else:
# New branch, create from master # New branch, create from main
self.repo.git.checkout("-b", title, "origin/master") self.repo.git.checkout("-b", title, "origin/main")
# Ensure destination directory exists # Ensure destination directory exists
dest_dir = f"{self.repo_path}src/content/" dest_dir = f"{self.repo_path}src/content/"