-
Notifications
You must be signed in to change notification settings - Fork 321
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: make incognito work #44
Draft
barakplasma
wants to merge
6
commits into
iyaja:main
Choose a base branch
from
barakplasma:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from 1 commit
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
d0fead4
feat: make incognito work
barakplasma f317521
fix: import
barakplasma 8b6367b
fix:
barakplasma 0769694
fix: wont output json like this
barakplasma 9f230a9
fix:
barakplasma 238dbbb
feat: choose your own image model
barakplasma File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
// Use IntelliSense to learn about possible attributes. | ||
// Hover to view descriptions of existing attributes. | ||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | ||
"version": "0.2.0", | ||
"configurations": [ | ||
{ | ||
"name": "Python Debugger: FastAPI", | ||
"type": "debugpy", | ||
"request": "launch", | ||
"module": "uvicorn", | ||
"args": [ | ||
"server:app", | ||
"--reload" | ||
], | ||
"jinja": true | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,6 @@ ollama | |
chromadb | ||
llama-index | ||
litellm | ||
groq | ||
docx2txt | ||
colorama | ||
termcolor | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,30 @@ | ||
import asyncio | ||
import http | ||
import http.server | ||
import json | ||
import os | ||
from collections import defaultdict | ||
|
||
import agentops | ||
import colorama | ||
import ollama | ||
import weave | ||
from groq import AsyncGroq, Groq | ||
import litellm | ||
import ollama | ||
from llama_index.core import Document, SimpleDirectoryReader | ||
from llama_index.core.schema import ImageDocument | ||
from llama_index.core.node_parser import TokenTextSplitter | ||
from termcolor import colored | ||
|
||
from src import select_model | ||
|
||
|
||
# @weave.op() | ||
# @agentops.record_function("summarize") | ||
async def get_dir_summaries(path: str): | ||
async def get_dir_summaries(path: str, incognito=True): | ||
doc_dicts = load_documents(path) | ||
# metadata = process_metadata(doc_dicts) | ||
|
||
summaries = await get_summaries(doc_dicts) | ||
summaries = await get_summaries(doc_dicts, incognito=incognito) | ||
|
||
# Convert path to relative path | ||
for summary in summaries: | ||
|
@@ -90,7 +94,7 @@ def process_metadata(doc_dicts): | |
return metadata_list | ||
|
||
|
||
async def summarize_document(doc, client): | ||
async def summarize_document(doc, incognito = True): | ||
PROMPT = """ | ||
You will be provided with the contents of a file along with its metadata. Provide a summary of the contents. The purpose of the summary is to organize files based on their content. To this end provide a concise but informative summary. Make the summary as specific to the file as possible. | ||
|
||
|
@@ -108,12 +112,12 @@ async def summarize_document(doc, client): | |
attempt = 0 | ||
while attempt < max_retries: | ||
try: | ||
chat_completion = await client.chat.completions.create( | ||
chat_completion = litellm.completion( | ||
messages=[ | ||
{"role": "system", "content": PROMPT}, | ||
{"role": "user", "content": json.dumps(doc)}, | ||
], | ||
model="llama3-70b-8192", | ||
model=select_model(incognito), | ||
response_format={"type": "json_object"}, | ||
temperature=0, | ||
) | ||
|
@@ -135,7 +139,7 @@ async def summarize_document(doc, client): | |
return summary | ||
|
||
|
||
async def summarize_image_document(doc: ImageDocument, client): | ||
async def summarize_image_document(doc: ImageDocument): | ||
PROMPT = """ | ||
You will be provided with an image along with its metadata. Provide a summary of the image contents. The purpose of the summary is to organize files based on their content. To this end provide a concise but informative summary. Make the summary as specific to the file as possible. | ||
|
||
|
@@ -152,7 +156,6 @@ async def summarize_image_document(doc: ImageDocument, client): | |
client = ollama.AsyncClient() | ||
chat_completion = await client.chat( | ||
messages=[ | ||
# {"role": "system", "content": "Respond with one short sentence."}, | ||
{ | ||
"role": "user", | ||
"content": "Summarize the contents of this image.", | ||
|
@@ -162,7 +165,6 @@ async def summarize_image_document(doc: ImageDocument, client): | |
model="moondream", | ||
# format="json", | ||
# stream=True, | ||
options={"num_predict": 128}, | ||
) | ||
|
||
summary = { | ||
|
@@ -176,21 +178,18 @@ async def summarize_image_document(doc: ImageDocument, client): | |
return summary | ||
|
||
|
||
async def dispatch_summarize_document(doc, client): | ||
async def dispatch_summarize_document(doc, incognito=True): | ||
if isinstance(doc, ImageDocument): | ||
return await summarize_image_document(doc, client) | ||
return await summarize_image_document(doc) | ||
elif isinstance(doc, Document): | ||
return await summarize_document({"content": doc.text, **doc.metadata}, client) | ||
return await summarize_document({"content": doc.text, **doc.metadata}, incognito=incognito) | ||
else: | ||
raise ValueError("Document type not supported") | ||
|
||
|
||
async def get_summaries(documents): | ||
client = AsyncGroq( | ||
api_key=os.environ.get("GROQ_API_KEY"), | ||
) | ||
async def get_summaries(documents, incognito=True): | ||
summaries = await asyncio.gather( | ||
*[dispatch_summarize_document(doc, client) for doc in documents] | ||
*[dispatch_summarize_document(doc, incognito=incognito) for doc in documents] | ||
) | ||
return summaries | ||
|
||
|
@@ -219,88 +218,12 @@ def merge_summary_documents(summaries, metadata_list): | |
################################################################################################ | ||
|
||
|
||
def get_file_summary(path: str): | ||
client = Groq( | ||
api_key=os.environ.get("GROQ_API_KEY"), | ||
) | ||
def get_file_summary(path: str, incognito=True): | ||
reader = SimpleDirectoryReader(input_files=[path]).iter_data() | ||
|
||
docs = next(reader) | ||
splitter = TokenTextSplitter(chunk_size=6144) | ||
text = splitter.split_text("\n".join([d.text for d in docs]))[0] | ||
doc = Document(text=text, metadata=docs[0].metadata) | ||
summary = dispatch_summarize_document_sync(doc, client) | ||
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. all these sync methods should come back for watch_util; or be replaced by a sync wrapper around the async ones (like https://stackoverflow.com/a/62949043 ) (I got rid of these out of naivety and a dislike of duplication) |
||
return summary | ||
|
||
|
||
def dispatch_summarize_document_sync(doc, client): | ||
if isinstance(doc, ImageDocument): | ||
return summarize_image_document_sync(doc, client) | ||
elif isinstance(doc, Document): | ||
return summarize_document_sync({"content": doc.text, **doc.metadata}, client) | ||
else: | ||
raise ValueError("Document type not supported") | ||
|
||
|
||
def summarize_document_sync(doc, client): | ||
PROMPT = """ | ||
You will be provided with the contents of a file along with its metadata. Provide a summary of the contents. The purpose of the summary is to organize files based on their content. To this end provide a concise but informative summary. Make the summary as specific to the file as possible. | ||
|
||
Write your response a JSON object with the following schema: | ||
|
||
```json | ||
{ | ||
"file_path": "path to the file including name", | ||
"summary": "summary of the content" | ||
} | ||
``` | ||
""".strip() | ||
|
||
chat_completion = client.chat.completions.create( | ||
messages=[ | ||
{"role": "system", "content": PROMPT}, | ||
{"role": "user", "content": json.dumps(doc)}, | ||
], | ||
model="llama3-70b-8192", | ||
response_format={"type": "json_object"}, | ||
temperature=0, | ||
) | ||
summary = json.loads(chat_completion.choices[0].message.content) | ||
|
||
try: | ||
print(colored(summary["file_path"], "green")) # Print the filename in green | ||
print(summary["summary"]) # Print the summary of the contents | ||
print("-" * 80 + "\n") # Print a separator line with spacing for readability | ||
except KeyError as e: | ||
print(e) | ||
print(summary) | ||
|
||
return summary | ||
|
||
|
||
def summarize_image_document_sync(doc: ImageDocument, client): | ||
client = ollama.Client() | ||
chat_completion = client.chat( | ||
messages=[ | ||
{ | ||
"role": "user", | ||
"content": "Summarize the contents of this image.", | ||
"images": [doc.image_path], | ||
}, | ||
], | ||
model="moondream", | ||
# format="json", | ||
# stream=True, | ||
options={"num_predict": 128}, | ||
) | ||
|
||
summary = { | ||
"file_path": doc.image_path, | ||
"summary": chat_completion["message"]["content"], | ||
} | ||
|
||
print(colored(summary["file_path"], "green")) # Print the filename in green | ||
print(summary["summary"]) # Print the summary of the contents | ||
print("-" * 80 + "\n") # Print a separator line with spacing for readability | ||
|
||
summary = dispatch_summarize_document(doc, incognito=incognito) | ||
return summary |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from os import environ | ||
from litellm import validate_environment | ||
import warnings | ||
|
||
def select_model(incognito=True): | ||
model = "groq/llama3-70b-8192" if environ.get("GROQ_API_KEY") and incognito is False else environ.get("MODEL", "ollama/llama3") | ||
litellm_validation = validate_environment(model) | ||
if litellm_validation.get('keys_in_environment') is False: | ||
raise EnvironmentError({ | ||
"errno": 1, | ||
"strerr": f"missing environment variables for model {model}", | ||
"missing_keys": ','.join(litellm_validation.get("missing_keys")) | ||
}) | ||
if "ollama" not in model: | ||
warnings.warn(f"sending the contents of your files to {model}!") | ||
return model |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
I wanted to switch this to litellm as well, but they don't make it easy to send a local file for vision because of a dependency on requests https://github.com/BerriAI/litellm/blob/3a35a58859a145a4a568548316a1930340e7440a/litellm/llms/prompt_templates/factory.py#L624-L635