-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement AI streaming Implement AI features for single author Add the ability to download single author information.
- Loading branch information
1 parent
c497e40
commit 96f53ac
Showing
33 changed files
with
1,374 additions
and
76 deletions.
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 |
---|---|---|
@@ -1,3 +1,3 @@ | ||
REDIS_BROKER=redis://localhost:6379/0 | ||
REDIS_RESULT=redis://localhost:6379/0 | ||
MISTRAL_API_KEY=hSZCZCDRWdhsfd9N2XZWEIWNeeMB5trf | ||
REDIS_BACKEND=redis://localhost:6379/0 | ||
MISTRAL_API_KEY=cCpcQhIsggTkErjaa3ZVCtu6XAjetH0h |
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,28 @@ | ||
FROM python:3.12-slim-bullseye AS builder | ||
|
||
RUN pip install poetry==1.8.3 | ||
|
||
ENV POETRY_NO_INTERACTION=1 \ | ||
POETRY_VIRTUALENVS_IN_PROJECT=1 \ | ||
POETRY_VIRTUALENVS_CREATE=1 \ | ||
POETRY_CACHE_DIR=/tmp/poetry_cache | ||
|
||
WORKDIR /worker | ||
|
||
COPY pyproject.toml poetry.lock ./ | ||
RUN touch README.md | ||
|
||
RUN --mount=type=cache,target=$POETRY_CACHE_DIR poetry install --no-root | ||
|
||
FROM python:3.12-slim-bullseye AS runtime | ||
|
||
ENV VIRTUAL_ENV=/worker/.venv \ | ||
PATH="/worker/.venv/bin:$PATH" | ||
|
||
COPY --from=builder ${VIRTUAL_ENV} ${VIRTUAL_ENV} | ||
|
||
COPY . ./worker | ||
|
||
WORKDIR /worker | ||
|
||
ENTRYPOINT ["celery", "-A", "celery_app.celery", "worker", "--loglevel=info", "--pool=solo", "-Q", "ai"] |
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,14 +1,35 @@ | ||
import asyncio | ||
from io import StringIO | ||
import json | ||
import time | ||
|
||
from celery import current_app as celery | ||
from celery import Task | ||
from mistralapi import main as task_ai | ||
from mistralapi import async_main as async_task_ai | ||
from redis import Redis | ||
|
||
redis = Redis(host='redis', port=6379, db=1) | ||
|
||
@celery.task | ||
def process_model(data: dict): | ||
input_data = json.dumps(data) | ||
with StringIO(input_data) as in_buffer, StringIO() as out_buffer: | ||
task_ai(in_buffer, out_buffer) | ||
output_data = out_buffer.getvalue() | ||
return {'text': output_data} | ||
|
||
@celery.task(bind=True) | ||
def process_model_two(self: Task, data:dict): | ||
input_data = json.dumps(data) | ||
v = 0 | ||
with StringIO(input_data) as in_buffer, StringIO() as out_buffer: | ||
for chunk in async_task_ai(in_buffer, out_buffer): | ||
print(f"Chunk {chunk}") | ||
resp = redis.xadd(f"ai_completions_{self.request.id}", {b"data": chunk.encode(), "ts": time.time(), 'v': v}) | ||
v += 1 | ||
print(resp, v) | ||
output_data = out_buffer.getvalue() | ||
resp = redis.xadd(f"ai_completions_{self.request.id}", {b"data": "[END]".encode(), "ts": time.time(), 'v': v}) | ||
print(resp, v) | ||
return {'text': output_data} |
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,37 @@ | ||
import os | ||
from mistralai import Mistral | ||
import asyncio | ||
import text_io | ||
from io import StringIO | ||
|
||
from dotenv import load_dotenv | ||
load_dotenv() | ||
|
||
# Ensure the os module is imported | ||
api_key = os.environ["MISTRAL_API_KEY"] | ||
model = "open-mistral-nemo-2407" | ||
|
||
client = Mistral(api_key=api_key) | ||
|
||
|
||
async def main(): | ||
string = StringIO() | ||
# Calling the async method inside an async function | ||
async_response = client.chat.stream( | ||
model=model, | ||
messages=[ | ||
{ | ||
"role": "user", | ||
"content": "Who is the best French painter?", | ||
}, | ||
] | ||
) | ||
|
||
# Using async for loop inside an async function | ||
|
||
for chunk in async_response: | ||
print(chunk.data.choices[0].delta.content, end="", flush=True) | ||
#text_io.write_paragraph_to_file(chunk.data.choices[0].delta.content) | ||
|
||
# Run the async function using asyncio | ||
asyncio.run(main()) |
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
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
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
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,51 @@ | ||
import { useEffect, useState, useRef } from 'react'; | ||
export default function useStream<T = string>(url:string) { | ||
const [data, setData] = useState<T | null>(null); | ||
const [loading, setLoading] = useState(true); | ||
const [errorObject, setErrorObject] = useState<Error | null>(null); | ||
const text = useRef(""); | ||
|
||
useEffect(() => { | ||
const controller = new AbortController(); | ||
const run = async (controller:AbortController) => { | ||
setLoading(true) | ||
let response | ||
try { | ||
|
||
response = await fetch(url, { | ||
method: 'GET', | ||
signal: controller.signal, | ||
}) | ||
|
||
} catch (error) { | ||
if ((error as Error).name === "AbortError") { | ||
return; | ||
} | ||
setErrorObject(error as Error) | ||
} | ||
setLoading(false); | ||
|
||
const reader = response!.body!.getReader(); | ||
const chunks = []; | ||
let done, value; | ||
const dec = new TextDecoder() | ||
|
||
while (!done) { | ||
({ value, done } = await reader.read()); | ||
if (done) { | ||
return chunks; | ||
} | ||
const strval = dec.decode(value, { stream: true }) | ||
console.log(chunks, strval, text.current) | ||
chunks.push(strval); | ||
text.current += strval | ||
setData(text.current as T) | ||
} | ||
} | ||
run(controller) | ||
return () => controller.abort(); | ||
|
||
}, [url]); | ||
|
||
return { data, loading, error: errorObject}; | ||
} |
Oops, something went wrong.