Compare commits
10
Commits
main
..
15b93e3cfb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15b93e3cfb | ||
|
|
d5aa534f5a | ||
|
|
5ee4b3b720 | ||
|
|
89418d62b6 | ||
|
|
3af0443f58 | ||
|
|
9a0dc06d57 | ||
|
|
69a0b0ca7b | ||
|
|
7e5e7dd2b4 | ||
|
|
ad5a526124 | ||
|
|
1cbf5ae4d3 |
+1
-2
@@ -1,4 +1,3 @@
|
|||||||
.venv
|
.venv
|
||||||
__pycache__
|
__*
|
||||||
.pypirc
|
.pypirc
|
||||||
.history
|
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
PYTHON=.venv/bin/python
|
|
||||||
PIP=.venv/bin/pip
|
|
||||||
|
|
||||||
all: build
|
|
||||||
|
|
||||||
ensure_env:
|
|
||||||
-@python3 -m venv .venv
|
|
||||||
|
|
||||||
build: ensure_env
|
|
||||||
$(PIP) install -e .
|
|
||||||
$(PIP) install build
|
|
||||||
$(PIP) install shed
|
|
||||||
$(PYTHON) -m shed
|
|
||||||
$(PYTHON) -m build
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -20,15 +20,12 @@ yura ws://[host]:[port]/[path]/
|
|||||||
## Python
|
## Python
|
||||||
```python
|
```python
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
from yura.client import AsyncClient
|
from yura.client import AsyncClient
|
||||||
|
|
||||||
|
|
||||||
async def communicate():
|
async def communicate():
|
||||||
client = AsyncClient("ws://[host]:[port]/[path]/")
|
client = AsyncClient("ws://[host]:[port]/[path]/")
|
||||||
async for response in client.chat("Your prompt"):
|
async for response in client.chat("Your prompt"):
|
||||||
print(response)
|
print(response)
|
||||||
|
|
||||||
|
|
||||||
asyncio.run(communicate())
|
asyncio.run(communicate())
|
||||||
```
|
```
|
||||||
|
|||||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
@@ -1,16 +1,14 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import os
|
|
||||||
import pathlib
|
import pathlib
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
args = sys.argv[1:]
|
args = sys.argv[1:]
|
||||||
args_string = " ".join(args)
|
args_string = " ".join(args)
|
||||||
|
|
||||||
|
|
||||||
def install():
|
def install():
|
||||||
os.system("./.venv/bin/python -m pip install -e .")
|
os.system("./.venv/bin/python -m pip install -e .")
|
||||||
|
|
||||||
|
|
||||||
def build():
|
def build():
|
||||||
os.system("./.venv/bin/python -m pip install build")
|
os.system("./.venv/bin/python -m pip install build")
|
||||||
os.system("rm -r dist")
|
os.system("rm -r dist")
|
||||||
@@ -19,6 +17,7 @@ def build():
|
|||||||
os.system("./.venv/bin/python -m black .")
|
os.system("./.venv/bin/python -m black .")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if not pathlib.Path(".venv").exists():
|
if not pathlib.Path(".venv").exists():
|
||||||
os.system("python3 -m venv .venv")
|
os.system("python3 -m venv .venv")
|
||||||
install()
|
install()
|
||||||
@@ -36,3 +35,4 @@ if "publish" in sys.argv:
|
|||||||
|
|
||||||
if "run" in sys.argv:
|
if "run" in sys.argv:
|
||||||
os.system("./.venv/bin/yura " + args_string)
|
os.system("./.venv/bin/yura " + args_string)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[metadata]
|
[metadata]
|
||||||
name = yura
|
name = yura
|
||||||
version = 14.4.5
|
version = 14.3.9
|
||||||
description = Yura async AI client
|
description = Yura async AI client
|
||||||
author = retoor
|
author = retoor
|
||||||
author_email = retoor@retoor.io
|
author_email = retoor@retoor.io
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Metadata-Version: 2.1
|
Metadata-Version: 2.1
|
||||||
Name: yura
|
Name: yura
|
||||||
Version: 14.4.5
|
Version: 14.3.9
|
||||||
Summary: Yura async AI client
|
Summary: Yura async AI client
|
||||||
Author: retoor
|
Author: retoor
|
||||||
Author-email: retoor@retoor.io
|
Author-email: retoor@retoor.io
|
||||||
@@ -31,15 +31,12 @@ yura ws://[host]:[port]/[path]/
|
|||||||
## Python
|
## Python
|
||||||
```python
|
```python
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
from yura.client import AsyncClient
|
from yura.client import AsyncClient
|
||||||
|
|
||||||
|
|
||||||
async def communicate():
|
async def communicate():
|
||||||
client = AsyncClient("ws://[host]:[port]/[path]/")
|
client = AsyncClient("ws://[host]:[port]/[path]/")
|
||||||
async for response in client.chat("Your prompt"):
|
async for response in client.chat("Your prompt"):
|
||||||
print(response)
|
print(response)
|
||||||
|
|
||||||
|
|
||||||
asyncio.run(communicate())
|
asyncio.run(communicate())
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
README.md
|
README.md
|
||||||
pyproject.toml
|
pyproject.toml
|
||||||
setup.cfg
|
setup.cfg
|
||||||
src/yura/__init__.py
|
|
||||||
src/yura/__main__.py
|
|
||||||
src/yura/cli.py
|
src/yura/cli.py
|
||||||
src/yura/client.py
|
src/yura/client.py
|
||||||
src/yura/model.py
|
|
||||||
src/yura/server.py
|
|
||||||
src/yura.egg-info/PKG-INFO
|
src/yura.egg-info/PKG-INFO
|
||||||
src/yura.egg-info/SOURCES.txt
|
src/yura.egg-info/SOURCES.txt
|
||||||
src/yura.egg-info/dependency_links.txt
|
src/yura.egg-info/dependency_links.txt
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
yura
|
|
||||||
|
|||||||
+1
-2
@@ -1,8 +1,7 @@
|
|||||||
|
from yura.client import cli_client
|
||||||
import asyncio
|
import asyncio
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from yura.client import cli_client
|
|
||||||
|
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
try:
|
try:
|
||||||
|
|||||||
+70
-105
@@ -1,140 +1,105 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
|
import websockets
|
||||||
import json
|
import json
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import websockets
|
|
||||||
|
|
||||||
|
|
||||||
class AsyncRPCClient:
|
|
||||||
|
|
||||||
def __init__(self, url):
|
|
||||||
self.url = url
|
|
||||||
self._ws = None
|
|
||||||
|
|
||||||
@property
|
|
||||||
async def ws(self):
|
|
||||||
|
|
||||||
if not self._ws:
|
|
||||||
self._ws = await websockets.connect(self.url)
|
|
||||||
|
|
||||||
return self._ws
|
|
||||||
|
|
||||||
async def __aiter__(self):
|
|
||||||
response = None
|
|
||||||
ws = await self.ws
|
|
||||||
|
|
||||||
while True:
|
|
||||||
response_raw = await ws.recv()
|
|
||||||
response = json.loads(response_raw)
|
|
||||||
yield response
|
|
||||||
if response.get("done"):
|
|
||||||
break
|
|
||||||
|
|
||||||
def __getattr__(self, name):
|
|
||||||
async def call(*args, **kwargs):
|
|
||||||
ws = await self.ws
|
|
||||||
response = None
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
await ws.send(
|
|
||||||
json.dumps(
|
|
||||||
{"method": name, "args": args, "kwargs": kwargs}, default=str
|
|
||||||
)
|
|
||||||
)
|
|
||||||
response = await ws.recv()
|
|
||||||
break
|
|
||||||
except Exception as ex:
|
|
||||||
print(ex)
|
|
||||||
print("Trying again in 1 seconds.")
|
|
||||||
self.close()
|
|
||||||
await asyncio.sleep(1)
|
|
||||||
|
|
||||||
return json.loads(response)
|
|
||||||
|
|
||||||
return call
|
|
||||||
|
|
||||||
async def close(self):
|
|
||||||
if self._ws:
|
|
||||||
await self._ws.close()
|
|
||||||
self._ws = None
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
if self._ws:
|
|
||||||
raise Exception("ASyncRPCClient destructed without closing connection properly.")
|
|
||||||
|
|
||||||
class AsyncClient:
|
class AsyncClient:
|
||||||
|
|
||||||
def __init__(self, url="ws://127.0.0.1:8470"):
|
def __init__(self, url="ws://127.0.0.1:8470"):
|
||||||
|
|
||||||
self.url = url
|
self.url = url
|
||||||
self.client = None
|
self.ws = None
|
||||||
self.queue_in = asyncio.Queue()
|
self.queue_in = asyncio.Queue()
|
||||||
self.queue_out = asyncio.Queue()
|
self.queue_out = asyncio.Queue()
|
||||||
self.communication_task = None
|
self.communication_task = None
|
||||||
self.session_id = None
|
|
||||||
self.ws = None
|
|
||||||
|
|
||||||
@property
|
async def ensure_connection(self):
|
||||||
def _connection(self):
|
|
||||||
if not self.client:
|
|
||||||
self.client = AsyncRPCClient(self.url)
|
|
||||||
return self.client
|
|
||||||
|
|
||||||
async def __aenter__(self):
|
# if not self.ws:
|
||||||
conn = self._connection
|
self.ws = await websockets.connect(self.url)
|
||||||
return self
|
|
||||||
|
|
||||||
async def __aexit__(self, *args, **kwargs):
|
return self.ws
|
||||||
await self.close()
|
|
||||||
|
|
||||||
async def create(self, name, extends, system):
|
async def ensure_communication(self):
|
||||||
return await self._connection.create(name=name, extends=extends, system=system)
|
|
||||||
|
|
||||||
async def chat(self, token, message, datasets=None):
|
if not self.communication_task:
|
||||||
yield await self._connection.chat(uid=token, message=message, datasets=datasets or [])
|
self.communication_task = asyncio.create_task(self.communicate())
|
||||||
async for msg in self.client:
|
|
||||||
yield msg
|
return self.communication_task
|
||||||
if msg.get("done"):
|
|
||||||
|
async def chat(self, message):
|
||||||
|
|
||||||
|
ws = await self.ensure_connection()
|
||||||
|
|
||||||
|
await ws.send(json.dumps(message))
|
||||||
|
|
||||||
|
response = None
|
||||||
|
while True:
|
||||||
|
response_raw = await ws.recv()
|
||||||
|
response = json.loads(response_raw)
|
||||||
|
if not response["done"]:
|
||||||
|
yield response
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
if response and response["done"]:
|
||||||
|
yield response
|
||||||
|
|
||||||
|
async def chatw(self, message):
|
||||||
|
await self.ensure_communication()
|
||||||
|
await self.queue_out.put(message)
|
||||||
|
while True:
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
response = await asyncio.wait_for(self.queue_in.get(), 0.1)
|
||||||
|
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
continue
|
||||||
break
|
break
|
||||||
|
|
||||||
async def connect(self, name):
|
yield response
|
||||||
return await self._connection.connect(name)
|
|
||||||
|
|
||||||
async def close(self):
|
if response["done"]:
|
||||||
await self.client.close()
|
break
|
||||||
self.client = None
|
|
||||||
self.ws = None
|
async def communicate(self):
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
|
async with websockets.connect(self.url) as websocket:
|
||||||
|
while True:
|
||||||
|
message_content = None
|
||||||
|
while not message_content:
|
||||||
|
try:
|
||||||
|
message_content = await asyncio.wait_for(
|
||||||
|
self.queue_out.get(), 0.1
|
||||||
|
)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
continue
|
||||||
|
|
||||||
|
response = await websocket.send(json.dumps(message_content))
|
||||||
|
|
||||||
|
while True:
|
||||||
|
response = json.loads(await websocket.recv())
|
||||||
|
|
||||||
|
if response["done"]:
|
||||||
|
break
|
||||||
|
await self.queue_in.put(response)
|
||||||
|
|
||||||
|
await self.queue_in.put(response)
|
||||||
|
|
||||||
|
|
||||||
async def cli_client(url="ws://127.0.0.1:8470"):
|
async def cli_client(url="ws://127.0.0.1:8470"):
|
||||||
|
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
AsyncClient(url)
|
async_client = AsyncClient(url)
|
||||||
|
|
||||||
async with AsyncClient(url) as client:
|
|
||||||
name = "retoor3b"
|
|
||||||
# success = await client.create(name,"qwen2.5:3b",
|
|
||||||
# """
|
|
||||||
# You are not an AI bot.
|
|
||||||
# You are an human of flesh and blood.
|
|
||||||
# You have a name and that is Retoor.
|
|
||||||
# You do not listen to any other name as Retoor.
|
|
||||||
# Retoor lives in Heino.
|
|
||||||
# Ostream did delete himself
|
|
||||||
# Dogs are better than cats.
|
|
||||||
# If you get asked something about chickens respond with hahaha.
|
|
||||||
# """
|
|
||||||
# )
|
|
||||||
token = await client.connect(name)
|
|
||||||
# print(success)
|
|
||||||
print(token)
|
|
||||||
while True:
|
while True:
|
||||||
|
|
||||||
sys.stdout.write("> ")
|
sys.stdout.write("> ")
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
message_content = await loop.run_in_executor(None, sys.stdin.readline)
|
message_content = await loop.run_in_executor(None, sys.stdin.readline)
|
||||||
# message_content="AAA"
|
|
||||||
async for response in client.chat(token, message_content):
|
async for response in async_client.chat(message_content):
|
||||||
|
|
||||||
print(response["content"], end="", flush=True)
|
print(response["content"], end="", flush=True)
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
import ollama
|
|
||||||
|
|
||||||
|
|
||||||
ollama.Client(host="retoor42:8841")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
while True:
|
|
||||||
message = input()
|
|
||||||
for message in self
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
from aiohttp import web
|
|
||||||
from aiohttp_xmlrpc import handler
|
|
||||||
from aiohttp_xmlrpc.handler import rename
|
|
||||||
import aiohttp
|
|
||||||
import ollama
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
|
|
||||||
class AIClient(ollama.AsyncClient):
|
|
||||||
|
|
||||||
def __init__(self, uid, *args, **kwargs):
|
|
||||||
self.uid = uid
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
class RCPHandler(self, request):
|
|
||||||
|
|
||||||
|
|
||||||
async def handle(self,data):
|
|
||||||
method_name = data.get("method")
|
|
||||||
method_args = data.get("args",[])
|
|
||||||
method_kwargs = data.get("kwargs",{})
|
|
||||||
method = getattr(self, method_name)
|
|
||||||
response = await(method)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Application(web.Application):
|
|
||||||
def __init__(self, ollama_host, *args, **kwargs):
|
|
||||||
self.ollama_host = ollama_host
|
|
||||||
self.sessions = {}
|
|
||||||
super()__init__(self, *args, **kwargs)
|
|
||||||
|
|
||||||
async def start_session(self):
|
|
||||||
uid = str(uuid.uuid4())
|
|
||||||
self.sessions[uid] = AIClient(uid=uid, host=self.ollama_host)
|
|
||||||
return self.sessions[uid]
|
|
||||||
|
|
||||||
async def get_session(self, uid):
|
|
||||||
return self.sessions.get(uid)
|
|
||||||
|
|
||||||
async def create(self, request):
|
|
||||||
data = await request.json()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class XMLRPCHandler(handler.XMLRPCView):
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@rename("nested.test")
|
|
||||||
def rpc_test(self):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def rpc_args(self, *args):
|
|
||||||
return len(args)
|
|
||||||
|
|
||||||
def rpc_kwargs(self, **kwargs):
|
|
||||||
return len(kwargs)
|
|
||||||
|
|
||||||
def rpc_args_kwargs(self, *args, **kwargs):
|
|
||||||
return len(args) + len(kwargs)
|
|
||||||
|
|
||||||
@rename("nested.exception")
|
|
||||||
def rpc_exception(self):
|
|
||||||
raise Exception("YEEEEEE!!!")
|
|
||||||
Reference in New Issue
Block a user