-
Notifications
You must be signed in to change notification settings - Fork 103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Draft ollama test #566
base: dev
Are you sure you want to change the base?
Changes from all commits
c572e27
2de364b
8ebd9a7
9d0d96e
b4088be
b670697
bfe039d
6bc4f6a
96adcfb
c06c28d
edd681f
02b0109
a91e83e
326c418
92602aa
f2d0909
97465f1
73662b8
90d96aa
3a88b94
11442df
1dfb0dd
4c4723b
846c45e
2c0bfc8
91512cd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
name: test | gemini | ||
|
||
on: | ||
workflow_dispatch: | ||
pull_request: | ||
types: [labeled, synchronize] | ||
|
||
|
||
concurrency: | ||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | ||
cancel-in-progress: true | ||
|
||
jobs: | ||
run_simple_example_test: | ||
uses: ./.github/workflows/reusable_python_example.yml | ||
with: | ||
example-location: ./examples/python/simple_example.py | ||
secrets: | ||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} | ||
GRAPHISTRY_USERNAME: ${{ secrets.GRAPHISTRY_USERNAME }} | ||
GRAPHISTRY_PASSWORD: ${{ secrets.GRAPHISTRY_PASSWORD }} | ||
EMBEDDING_PROVIDER: "gemini" | ||
EMBEDDING_API_KEY: ${{ secrets.GEMINI_API_KEY }} | ||
EMBEDDING_MODEL: "gemini/text-embedding-004" | ||
EMBEDDING_ENDPOINT: "https://generativelanguage.googleapis.com/v1beta/models/text-embedding-004" | ||
EMBEDDING_API_VERSION: "v1beta" | ||
EMBEDDING_DIMENSIONS: 768 | ||
EMBEDDING_MAX_TOKENS: 8076 | ||
LLM_PROVIDER: "gemini" | ||
LLM_API_KEY: ${{ secrets.GEMINI_API_KEY }} | ||
LLM_MODEL: "gemini/gemini-1.5-flash" | ||
LLM_ENDPOINT: "https://generativelanguage.googleapis.com/" | ||
LLM_API_VERSION: "v1beta" | ||
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,84 @@ | ||||||||||||||
name: test | ollama | ||||||||||||||
|
||||||||||||||
on: | ||||||||||||||
workflow_dispatch: | ||||||||||||||
pull_request: | ||||||||||||||
types: [ labeled, synchronize ] | ||||||||||||||
|
||||||||||||||
jobs: | ||||||||||||||
|
||||||||||||||
run_simple_example_test: | ||||||||||||||
|
||||||||||||||
runs-on: ubuntu-latest | ||||||||||||||
services: | ||||||||||||||
ollama: | ||||||||||||||
image: ollama/ollama | ||||||||||||||
ports: | ||||||||||||||
- 11434:11434 | ||||||||||||||
|
||||||||||||||
steps: | ||||||||||||||
- name: Checkout repository | ||||||||||||||
uses: actions/checkout@v4 | ||||||||||||||
|
||||||||||||||
- name: Setup Python | ||||||||||||||
uses: actions/setup-python@v5 | ||||||||||||||
with: | ||||||||||||||
python-version: '3.12.x' | ||||||||||||||
|
||||||||||||||
- name: Install Poetry | ||||||||||||||
uses: snok/[email protected] | ||||||||||||||
with: | ||||||||||||||
virtualenvs-create: true | ||||||||||||||
virtualenvs-in-project: true | ||||||||||||||
installer-parallel: true | ||||||||||||||
|
||||||||||||||
- name: Install dependencies | ||||||||||||||
run: | | ||||||||||||||
poetry install --no-interaction --all-extras | ||||||||||||||
|
||||||||||||||
- name: Install ollama | ||||||||||||||
run: curl -fsSL https://ollama.com/install.sh | sh | ||||||||||||||
- name: Run ollama | ||||||||||||||
run: | | ||||||||||||||
ollama serve & | ||||||||||||||
ollama pull llama3.2 & | ||||||||||||||
ollama pull avr/sfr-embedding-mistral:latest | ||||||||||||||
- name: Call ollama API | ||||||||||||||
run: | | ||||||||||||||
curl -d '{"model": "llama3.2", "stream": false, "prompt":"Whatever I say, asnwer with Yes"}' http://localhost:11434/api/generate | ||||||||||||||
Comment on lines
+46
to
+48
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. API Call to Ollama: The API call appears functionally correct. However, note the typo in the prompt ("asnwer" should be "answer"). Correcting this will ensure clarity in the test. - curl -d '{"model": "llama3.2", "stream": false, "prompt":"Whatever I say, asnwer with Yes"}' http://localhost:11434/api/generate
+ curl -d '{"model": "llama3.2", "stream": false, "prompt":"Whatever I say, answer with Yes"}' http://localhost:11434/api/generate 📝 Committable suggestion
Suggested change
|
||||||||||||||
|
||||||||||||||
- name: Wait for Ollama to be ready | ||||||||||||||
run: | | ||||||||||||||
for i in {1..30}; do | ||||||||||||||
if curl -s http://localhost:11434/api/tags > /dev/null; then | ||||||||||||||
echo "Ollama is ready" | ||||||||||||||
exit 0 | ||||||||||||||
fi | ||||||||||||||
echo "Waiting for Ollama... attempt $i" | ||||||||||||||
sleep 2 | ||||||||||||||
done | ||||||||||||||
echo "Ollama failed to start" | ||||||||||||||
exit 1 | ||||||||||||||
|
||||||||||||||
- name: Dump Docker logs | ||||||||||||||
run: | | ||||||||||||||
docker ps | ||||||||||||||
docker logs $(docker ps --filter "ancestor=ollama/ollama" --format "{{.ID}}") | ||||||||||||||
|
||||||||||||||
|
||||||||||||||
- name: Run example test | ||||||||||||||
env: | ||||||||||||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} | ||||||||||||||
GRAPHISTRY_USERNAME: ${{ secrets.GRAPHISTRY_USERNAME }} | ||||||||||||||
GRAPHISTRY_PASSWORD: ${{ secrets.GRAPHISTRY_PASSWORD }} | ||||||||||||||
PYTHONFAULTHANDLER: 1 | ||||||||||||||
LLM_API_KEY: "ollama" | ||||||||||||||
LLM_PROVIDER: "ollama" | ||||||||||||||
LLM_ENDPOINT: "http://127.0.0.1:11434/api/generate" | ||||||||||||||
LLM_MODEL: "ollama/llama3.2" | ||||||||||||||
EMBEDDING_PROVIDER: "ollama" | ||||||||||||||
EMBEDDING_MODEL: "avr/sfr-embedding-mistral:latest" | ||||||||||||||
EMBEDDING_ENDPOINT: "http://127.0.0.1:11434/api/embeddings" | ||||||||||||||
EMBEDDING_DIMENSIONS: "4096" | ||||||||||||||
HUGGINGFACE_TOKENIZER: "Salesforce/SFR-Embedding-Mistral" | ||||||||||||||
run: poetry run python ./examples/python/simple_example.py | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix File Formatting: Append a Newline at File End 🧰 Tools🪛 YAMLlint (1.35.1)[error] 84-84: no new line character at the end of file (new-line-at-end-of-file) |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,20 +1,28 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from sys import api_version | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove unused import. The -from sys import api_version 📝 Committable suggestion
Suggested change
🧰 Tools🪛 GitHub Actions: lint | ruff format[error] 1-1: Ruff formatting check failed. The file would be reformatted. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from typing import Type | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from pydantic import BaseModel | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import instructor | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from cognee.infrastructure.llm.llm_interface import LLMInterface | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from cognee.infrastructure.llm.config import get_llm_config | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from openai import OpenAI | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import base64 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from pathlib import Path | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import os | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
class OllamaAPIAdapter(LLMInterface): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"""Adapter for a Generic API LLM provider using instructor with an OpenAI backend.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"""Adapter for a Ollama API LLM provider using instructor with an OpenAI backend.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
api_version: str | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
MAX_RETRIES = 5 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def __init__(self, endpoint: str, api_key: str, model: str, name: str, max_tokens: int): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def __init__(self, endpoint: str, api_key: str, model: str, name: str, max_tokens: int, api_version: str = None) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.name = name | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.model = model | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.api_key = api_key | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.endpoint = endpoint | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.max_tokens = max_tokens | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.api_version= api_version | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.aclient = instructor.from_openai( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OpenAI(base_url=self.endpoint, api_key=self.api_key), mode=instructor.Mode.JSON | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -42,3 +50,54 @@ async def acreate_structured_output( | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return response | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def create_transcript(self, input): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"""Generate a audio transcript from a user query.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if not os.path.isfile(input): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
raise FileNotFoundError(f"The file {input} does not exist.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# with open(input, 'rb') as audio_file: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# audio_data = audio_file.read() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
transcription = self.aclient.transcription( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
model=self.transcription_model, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
file=Path(input), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
api_key=self.api_key, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
api_base=self.endpoint, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
api_version=self.api_version, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
max_retries=self.MAX_RETRIES, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return transcription | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+55
to
+73
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix implementation issues in
Apply this diff to fix the issues: def create_transcript(self, input):
"""Generate a audio transcript from a user query."""
if not os.path.isfile(input):
raise FileNotFoundError(f"The file {input} does not exist.")
- # with open(input, 'rb') as audio_file:
- # audio_data = audio_file.read()
-
transcription = self.aclient.transcription(
- model=self.transcription_model,
+ model=self.model, # Use the model defined in __init__
file=Path(input),
api_key=self.api_key,
api_base=self.endpoint,
api_version=self.api_version,
max_retries=self.MAX_RETRIES,
)
return transcription 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def transcribe_image(self, input) -> BaseModel: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
with open(input, "rb") as image_file: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
encoded_image = base64.b64encode(image_file.read()).decode("utf-8") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return self.aclient.completion( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
model=self.model, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
messages=[ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"role": "user", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"content": [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"type": "text", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"text": "What’s in this image?", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"type": "image_url", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"image_url": { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"url": f"data:image/jpeg;base64,{encoded_image}", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
api_key=self.api_key, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
api_base=self.endpoint, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
api_version=self.api_version, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
max_tokens=300, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
max_retries=self.MAX_RETRIES, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Secrets Mismatch with Reusable Workflow
The job passes several secrets that are not defined in the reusable workflow (
reusable_python_example.yml
). According to the static analysis hints, onlyOPENAI_API_KEY
,GRAPHISTRY_USERNAME
,GRAPHISTRY_PASSWORD
, andLLM_API_KEY
are expected, yet the configuration includes additional secrets such as:EMBEDDING_PROVIDER
EMBEDDING_API_KEY
EMBEDDING_MODEL
EMBEDDING_ENDPOINT
EMBEDDING_API_VERSION
EMBEDDING_DIMENSIONS
EMBEDDING_MAX_TOKENS
LLM_PROVIDER
LLM_MODEL
LLM_ENDPOINT
LLM_API_VERSION
Please either update the reusable workflow file to accept these additional secrets (if they are necessary for the workflow’s operation) or remove them from here to avoid potential configuration issues.
🧰 Tools
🪛 actionlint (1.7.4)
22-22: secret "EMBEDDING_PROVIDER" is not defined in "./.github/workflows/reusable_python_example.yml" reusable workflow. defined secrets are "GRAPHISTRY_PASSWORD", "GRAPHISTRY_USERNAME", "LLM_API_KEY", "OPENAI_API_KEY"
(workflow-call)
23-23: secret "EMBEDDING_API_KEY" is not defined in "./.github/workflows/reusable_python_example.yml" reusable workflow. defined secrets are "GRAPHISTRY_PASSWORD", "GRAPHISTRY_USERNAME", "LLM_API_KEY", "OPENAI_API_KEY"
(workflow-call)
24-24: secret "EMBEDDING_MODEL" is not defined in "./.github/workflows/reusable_python_example.yml" reusable workflow. defined secrets are "GRAPHISTRY_PASSWORD", "GRAPHISTRY_USERNAME", "LLM_API_KEY", "OPENAI_API_KEY"
(workflow-call)
25-25: secret "EMBEDDING_ENDPOINT" is not defined in "./.github/workflows/reusable_python_example.yml" reusable workflow. defined secrets are "GRAPHISTRY_PASSWORD", "GRAPHISTRY_USERNAME", "LLM_API_KEY", "OPENAI_API_KEY"
(workflow-call)
26-26: secret "EMBEDDING_API_VERSION" is not defined in "./.github/workflows/reusable_python_example.yml" reusable workflow. defined secrets are "GRAPHISTRY_PASSWORD", "GRAPHISTRY_USERNAME", "LLM_API_KEY", "OPENAI_API_KEY"
(workflow-call)
27-27: secret "EMBEDDING_DIMENSIONS" is not defined in "./.github/workflows/reusable_python_example.yml" reusable workflow. defined secrets are "GRAPHISTRY_PASSWORD", "GRAPHISTRY_USERNAME", "LLM_API_KEY", "OPENAI_API_KEY"
(workflow-call)
28-28: secret "EMBEDDING_MAX_TOKENS" is not defined in "./.github/workflows/reusable_python_example.yml" reusable workflow. defined secrets are "GRAPHISTRY_PASSWORD", "GRAPHISTRY_USERNAME", "LLM_API_KEY", "OPENAI_API_KEY"
(workflow-call)
29-29: secret "LLM_PROVIDER" is not defined in "./.github/workflows/reusable_python_example.yml" reusable workflow. defined secrets are "GRAPHISTRY_PASSWORD", "GRAPHISTRY_USERNAME", "LLM_API_KEY", "OPENAI_API_KEY"
(workflow-call)
31-31: secret "LLM_MODEL" is not defined in "./.github/workflows/reusable_python_example.yml" reusable workflow. defined secrets are "GRAPHISTRY_PASSWORD", "GRAPHISTRY_USERNAME", "LLM_API_KEY", "OPENAI_API_KEY"
(workflow-call)
32-32: secret "LLM_ENDPOINT" is not defined in "./.github/workflows/reusable_python_example.yml" reusable workflow. defined secrets are "GRAPHISTRY_PASSWORD", "GRAPHISTRY_USERNAME", "LLM_API_KEY", "OPENAI_API_KEY"
(workflow-call)
33-33: secret "LLM_API_VERSION" is not defined in "./.github/workflows/reusable_python_example.yml" reusable workflow. defined secrets are "GRAPHISTRY_PASSWORD", "GRAPHISTRY_USERNAME", "LLM_API_KEY", "OPENAI_API_KEY"
(workflow-call)