SONUB home EN English 한국어 日本語 中文 हिन्दी বাংলা اردو Español Português Français Deutsch Русский العربية Bahasa Indonesia Tiếng Việt ไทย Türkçe

How to enable notifications

Notifications are unavailable in this browser or on this address. Try a supported browser on the secure SONUB site.

If notifications are blocked, allow them in your browser settings.

  1. Open the site controls beside the address bar, or your browser’s site settings. Set Notifications for this site to Allow.
  2. In your device settings, allow notifications for your browser and check Do Not Disturb or Focus.
  3. Return to SONUB, reload the page, and use the bell to enable notifications.

On iPhone or iPad, add SONUB to your Home Screen, open it there, then allow notifications.

XSML · From your first line to a conversation

Now, let's build your very own AI.

Type your own language model in this browser: prepare text, train a tiny GPT, then run your Runner and XChat. No pretrained weights or external AI API.

9

XChat

Create your own terminal chat client and complete the entire chain.

XChat is the interface, Runner is the execution service, and XSML is the learned model. xchat.py reads a question, adds the training format, sends an request and displays the text. It does not import the model or generate an answer itself.

This first client runs inside the browser terminal. Each question is independent: it does not yet send conversation history. A useful extension is to add history, while respecting the model’s small context. Fluency is not the graduation requirement; an actual request through your own trained model is.

Type and try

Leave the Runner running. Type xchat.py and launch it. At You>, type hi and press Enter. Type /exit to return to bash. Only then run the final kill command to stop the Runner. Export your complete project.

cd ~/xsml
nano xchat.py
python3 xchat.py
hi
/exit
kill "$(cat runner.pid)"
xchat.pyComplete source to type

input reads a line; Request creates the JSON POST; urlopen reads the real response. Connection errors are reported instead of replaced with a fake answer.

import json
from pathlib import Path
from urllib.request import Request, urlopen
from urllib.error import URLError


def ask(question):
    cfg = json.loads(Path('settings.json').read_text())
    body = {'prompt': 'Q: ' + question + '\nA:', 'tokens': cfg['tokens']}
    request = Request('http://127.0.0.1:' + str(cfg['port']) + '/generate',
                      data=json.dumps(body).encode(),
                      headers={'Content-Type': 'application/json'})
    with urlopen(request, timeout=120) as response:
        return json.load(response)['text']


if __name__ == '__main__':
    print('XChat -> Runner -> XSML | /exit')
    while True:
        try:
            question = input('You> ').strip()
            if question == '/exit':
                break
            if question:
                print('XSML>', ask(question))
        except (EOFError, KeyboardInterrupt):
            break
        except (URLError, TimeoutError) as error:
            print('Runner:', error)

Check your understanding

Show the chain XChat → HTTP Runner → loaded weights → generated text. Stop the Runner and try another chat: it must report a connection error. Restart it and verify chat works again. Explain each file to someone else.

If you get stuck

Do not type the kill command inside XChat; it would be sent as a question. Exit first. A successful network response with poor text still demonstrates the pipeline; improve data and training as your next experiment.