commit 81511072c6be1d2c93b029e548d55c46102956f5
Author: retoor <retoor@molodetz.nl>
Date:   Tue Dec 3 17:52:00 2024 +0100

    New build.

diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml
new file mode 100644
index 0000000..48d3cb2
--- /dev/null
+++ b/.gitea/workflows/build.yaml
@@ -0,0 +1,26 @@
+name: Build package
+run-name: Build package
+on: [push]
+
+jobs:
+  Build:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Check out repository code
+        uses: actions/checkout@v4
+      - name: Update repo
+        run: git pull
+      - name: List files in the repository
+        run: |
+          ls ${{ gitea.workspace }}
+      - name: Update apt
+        run: apt update
+      - name: Installing system dependencies
+        run: apt install python3 python3-pip python3-venv make -y
+      - name: Run Make
+        run: make
+      - run: git add .
+      - run: git config --global user.email "bot@molodetz.com"
+      - run: git config --global user.name "bot"
+      - run: git commit -a -m "Automated update of new package."
+      - run: git push
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a501307
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+.vscode
+.venv
+.history
+__pycache__
+
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..3aa9ff7
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,24 @@
+BIN = ./.venv/bin/
+PYTHON = ./.venv/bin/python
+PIP = ./.venv/bin/pip
+
+all: build
+
+ensure_env:
+	-@python3 -m venv .venv 
+
+format: ensure_env
+	$(PIP) install shed
+	. $(BIN)/activate && shed
+
+build: format
+	$(PIP) install -e . 
+	$(PIP) install build
+	$(PYTHON) -m build 
+
+serve: ensure_env
+	$(BIN)rbabel.serve --host=0.0.0.0 --port=3011 --url=wss://flock.molodetz.nl
+
+bench: ensure_env
+	$(BIN)rbabel.bench --url=http://localhost:3011/
+
diff --git a/dist/Rbabel-1.3.37-py3-none-any.whl b/dist/Rbabel-1.3.37-py3-none-any.whl
new file mode 100644
index 0000000..754a056
Binary files /dev/null and b/dist/Rbabel-1.3.37-py3-none-any.whl differ
diff --git a/dist/rbabel-1.0.0-py3-none-any.whl b/dist/rbabel-1.0.0-py3-none-any.whl
new file mode 100644
index 0000000..5630668
Binary files /dev/null and b/dist/rbabel-1.0.0-py3-none-any.whl differ
diff --git a/dist/rbabel-1.0.0.tar.gz b/dist/rbabel-1.0.0.tar.gz
new file mode 100644
index 0000000..4d17259
Binary files /dev/null and b/dist/rbabel-1.0.0.tar.gz differ
diff --git a/dist/rbabel-1.3.37-py3-none-any.whl b/dist/rbabel-1.3.37-py3-none-any.whl
new file mode 100644
index 0000000..934488b
Binary files /dev/null and b/dist/rbabel-1.3.37-py3-none-any.whl differ
diff --git a/dist/rbabel-1.3.37.tar.gz b/dist/rbabel-1.3.37.tar.gz
new file mode 100644
index 0000000..3afa8a0
Binary files /dev/null and b/dist/rbabel-1.3.37.tar.gz differ
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..07de284
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,3 @@
+[build-system]
+requires = ["setuptools", "wheel"]
+build-backend = "setuptools.build_meta"
\ No newline at end of file
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..fd96aea
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,28 @@
+[metadata]
+name = rbabel
+version = 1.0.0
+description = English sentence corrector
+author = Retoor
+author_email = retoor@molodetz.nl
+license = MIT
+long_description = file: README.md
+long_description_content_type = text/markdown
+
+[options]
+packages = find:
+package_dir =
+    = src
+python_requires = >=3.7
+install_requires =
+   aiohttp
+   dataset 
+   yura @ git+https://retoor.molodetz.nl/retoor/yura.git@main
+
+[options.packages.find]
+where = src
+
+[options.entry_points]
+console_scripts =
+    rbabel.serve = rbabel.__main__:main
+    rbabel.bench = rbabel.cli:cli_bench
+    rbabel = rbabel.cli:main
diff --git a/src/Rbabel.egg-info/PKG-INFO b/src/Rbabel.egg-info/PKG-INFO
new file mode 100644
index 0000000..e6be732
--- /dev/null
+++ b/src/Rbabel.egg-info/PKG-INFO
@@ -0,0 +1,12 @@
+Metadata-Version: 2.1
+Name: Rbabel
+Version: 1.3.37
+Summary: English sentence corrector
+Author: Retoor
+Author-email: retoor@molodetz.nl
+License: MIT
+Requires-Python: >=3.7
+Description-Content-Type: text/markdown
+Requires-Dist: aiohttp
+Requires-Dist: dataset
+Requires-Dist: yura@ git+https://retoor.molodetz.nl/retoor/yura.git@main
diff --git a/src/Rbabel.egg-info/SOURCES.txt b/src/Rbabel.egg-info/SOURCES.txt
new file mode 100644
index 0000000..a98f322
--- /dev/null
+++ b/src/Rbabel.egg-info/SOURCES.txt
@@ -0,0 +1,13 @@
+pyproject.toml
+setup.cfg
+src/Rbabel.egg-info/PKG-INFO
+src/Rbabel.egg-info/SOURCES.txt
+src/Rbabel.egg-info/dependency_links.txt
+src/Rbabel.egg-info/entry_points.txt
+src/Rbabel.egg-info/requires.txt
+src/Rbabel.egg-info/top_level.txt
+src/rbabel/__init__.py
+src/rbabel/__main__.py
+src/rbabel/app.py
+src/rbabel/args.py
+src/rbabel/cli.py
\ No newline at end of file
diff --git a/src/Rbabel.egg-info/dependency_links.txt b/src/Rbabel.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/src/Rbabel.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/src/Rbabel.egg-info/entry_points.txt b/src/Rbabel.egg-info/entry_points.txt
new file mode 100644
index 0000000..c731308
--- /dev/null
+++ b/src/Rbabel.egg-info/entry_points.txt
@@ -0,0 +1,3 @@
+[console_scripts]
+rbabel = rbabel.cli:main
+rbabel.serve = rbabel.__main__:main
diff --git a/src/Rbabel.egg-info/requires.txt b/src/Rbabel.egg-info/requires.txt
new file mode 100644
index 0000000..d179af3
--- /dev/null
+++ b/src/Rbabel.egg-info/requires.txt
@@ -0,0 +1,3 @@
+aiohttp
+dataset
+yura@ git+https://retoor.molodetz.nl/retoor/yura.git@main
diff --git a/src/Rbabel.egg-info/top_level.txt b/src/Rbabel.egg-info/top_level.txt
new file mode 100644
index 0000000..08daaf4
--- /dev/null
+++ b/src/Rbabel.egg-info/top_level.txt
@@ -0,0 +1 @@
+rbabel
diff --git a/src/rbabel.egg-info/PKG-INFO b/src/rbabel.egg-info/PKG-INFO
new file mode 100644
index 0000000..a0ebe06
--- /dev/null
+++ b/src/rbabel.egg-info/PKG-INFO
@@ -0,0 +1,12 @@
+Metadata-Version: 2.1
+Name: rbabel
+Version: 1.0.0
+Summary: English sentence corrector
+Author: Retoor
+Author-email: retoor@molodetz.nl
+License: MIT
+Requires-Python: >=3.7
+Description-Content-Type: text/markdown
+Requires-Dist: aiohttp
+Requires-Dist: dataset
+Requires-Dist: yura@ git+https://retoor.molodetz.nl/retoor/yura.git@main
diff --git a/src/rbabel.egg-info/SOURCES.txt b/src/rbabel.egg-info/SOURCES.txt
new file mode 100644
index 0000000..eadca91
--- /dev/null
+++ b/src/rbabel.egg-info/SOURCES.txt
@@ -0,0 +1,13 @@
+pyproject.toml
+setup.cfg
+src/rbabel/__init__.py
+src/rbabel/__main__.py
+src/rbabel/app.py
+src/rbabel/args.py
+src/rbabel/cli.py
+src/rbabel.egg-info/PKG-INFO
+src/rbabel.egg-info/SOURCES.txt
+src/rbabel.egg-info/dependency_links.txt
+src/rbabel.egg-info/entry_points.txt
+src/rbabel.egg-info/requires.txt
+src/rbabel.egg-info/top_level.txt
\ No newline at end of file
diff --git a/src/rbabel.egg-info/dependency_links.txt b/src/rbabel.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/src/rbabel.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/src/rbabel.egg-info/entry_points.txt b/src/rbabel.egg-info/entry_points.txt
new file mode 100644
index 0000000..be7cc35
--- /dev/null
+++ b/src/rbabel.egg-info/entry_points.txt
@@ -0,0 +1,4 @@
+[console_scripts]
+rbabel = rbabel.cli:main
+rbabel.bench = rbabel.cli:cli_bench
+rbabel.serve = rbabel.__main__:main
diff --git a/src/rbabel.egg-info/requires.txt b/src/rbabel.egg-info/requires.txt
new file mode 100644
index 0000000..d179af3
--- /dev/null
+++ b/src/rbabel.egg-info/requires.txt
@@ -0,0 +1,3 @@
+aiohttp
+dataset
+yura@ git+https://retoor.molodetz.nl/retoor/yura.git@main
diff --git a/src/rbabel.egg-info/top_level.txt b/src/rbabel.egg-info/top_level.txt
new file mode 100644
index 0000000..08daaf4
--- /dev/null
+++ b/src/rbabel.egg-info/top_level.txt
@@ -0,0 +1 @@
+rbabel
diff --git a/src/rbabel/__init__.py b/src/rbabel/__init__.py
new file mode 100644
index 0000000..7e315cc
--- /dev/null
+++ b/src/rbabel/__init__.py
@@ -0,0 +1,9 @@
+import logging 
+
+logging.basicConfig(
+    level=logging.DEBUG,
+    format='%(asctime)s - %(levelname)s - %(message)s', 
+    datefmt='%Y-%m-%d %H:%M:%S'
+)
+
+log = logging.getLogger(__name__)
diff --git a/src/rbabel/__main__.py b/src/rbabel/__main__.py
new file mode 100644
index 0000000..23d38fd
--- /dev/null
+++ b/src/rbabel/__main__.py
@@ -0,0 +1,13 @@
+from aiohttp import web 
+from rbabel.app import create_app
+from rbabel.args import parse_args
+
+def main():
+    args = parse_args()
+    app = create_app(args.url)
+    web.run_app(app,host=args.host,port=args.port)
+
+
+if __name__ == '__main__':
+    nain()
+
diff --git a/src/rbabel/app.py b/src/rbabel/app.py
new file mode 100644
index 0000000..216f8a2
--- /dev/null
+++ b/src/rbabel/app.py
@@ -0,0 +1,50 @@
+from aiohttp import web
+from yura.client import AsyncClient as LLMClient 
+
+from rbabel import log 
+
+LLM_NAME = "rbabel"
+LLM_CONTEXT = "You are an English grammar corrector. You repsond with only the corrected English of by user given prompt and nothing more. Also replace numbers with the word variant."
+LLM_MODEL = "gemma2:latest"
+
+class Application(web.Application):
+
+
+    def __init__(self, llm_url=None, llm_name=LLM_NAME, llm_model=LLM_MODEL,llm_context=LLM_CONTEXT,  *args, **kwargs):
+        self.llm_url = llm_url
+        self.llm_name = llm_name
+        self.llm_model = LLM_MODEL
+        self.llm_context = llm_context
+        super().__init__(*args, **kwargs)
+        self.on_startup.append(self.create_llm)
+        self.router.add_post("/", self.optimize_grammar_handler)
+
+    async def create_llm(self, app):
+        llm_client = LLMClient(self.llm_url)
+        log.info("Creating LLM named {}.".format(self.llm_name))
+        success = await llm_client.create(self.llm_name, self.llm_model, self.llm_context)
+        assert(success)
+        log.info("LLM {} created.".format(self.llm_name))
+        await llm_client.close()
+
+    async def fix_grammar(self, content):
+        corrected_content = []
+        llm_client = LLMClient(self.llm_url)
+        token = await llm_client.connect(self.llm_name)
+        async for chunk in llm_client.chat(token, content):
+            corrected_content.append(chunk['content'])
+        await llm_client.close()
+        return "".join(corrected_content)
+
+    async def optimize_grammar_handler(self,request):
+        text = await request.json()
+        assert(type(text) ==str)
+        corrected = await self.fix_grammar(text)
+        print("was:",text)
+        print("became:",corrected)
+        return web.json_response(corrected,content_type="application/json")
+
+
+def create_app(llm_url):
+    return Application(llm_url, LLM_NAME, LLM_MODEL, LLM_CONTEXT)
+
diff --git a/src/rbabel/args.py b/src/rbabel/args.py
new file mode 100644
index 0000000..6277288
--- /dev/null
+++ b/src/rbabel/args.py
@@ -0,0 +1,35 @@
+import argparse 
+
+def parse_args():
+    parser = argparse.ArgumentParser(
+        description="AI enabled English corrector. Only minor improvements."
+    )
+
+    parser.add_argument(
+        '--url',
+        type=str,
+        required=False,
+        default="http://127.0.0.1:3011/",
+        help='URL of Katya LLM Server.'
+    )
+
+    parser.add_argument(
+        '--host',
+        type=str,
+        default="127.0.0.1",
+        required=False,
+        help='Host to bind to.'
+    )
+
+
+    parser.add_argument(
+        '--port',
+        type=int,
+        default=3011,
+        required=False,
+        help='Port to bind to.'
+    )
+
+    return parser.parse_args()
+
+
diff --git a/src/rbabel/cli.py b/src/rbabel/cli.py
new file mode 100644
index 0000000..865c918
--- /dev/null
+++ b/src/rbabel/cli.py
@@ -0,0 +1,50 @@
+import asyncio
+from aiohttp import ClientSession
+from rbabel.args import parse_args
+import time 
+
+
+async def cli_client(url):
+    
+    while True:
+        sentence = input("> ")
+        async with ClientSession() as session:
+            async with session.post("http://localhost:8080",json=sentence) as response:
+                try:
+                    print(await response.json())
+                except Exception as ex:
+                    print(ex)
+                    print(await response.text())
+
+async def bench(url):
+    index = 0
+    while True:
+        index += 1
+        sentence = "I bougt {} woden shoe".format(index)
+        time_start = time.time()
+        async with ClientSession() as session:
+            async with session.post(url,json=sentence) as response:
+                try:
+                    print(await response.json())
+                except Exception as ex:
+                    print(ex)
+                    print(await response.text())
+        time_end = time.time()
+        print("Duration: {}".format(time_end-time_start))
+        
+
+def cli_bench():
+    args = parse_args()
+    asyncio.run(bench(args.url))
+
+
+def main():
+    args = parse_args()
+    asyncio.run(cli_client(args.url))
+
+if __name__ == '__main__':
+    main()
+
+
+
+