Giter Site home page Giter Site logo

njbbaer / simulacra Goto Github PK

View Code? Open in Web Editor NEW
2.0 3.0 0.0 339 KB

Build Telegram bots with advanced personalities and memory using the GPT-4 API.

License: MIT License

Python 98.47% Dockerfile 0.51% Makefile 1.03%
ai gpt gpt-4 openai openai-api telegram telegram-bot python

simulacra's Introduction

Simulacra

build codecov

OpenAI Python Telegram Docker

Simulacra is a platform for building GPT-4 powered Telegram bots with a template-based personality system.

This project is under active development and breaking changes may occur at any time.

If this project interests you, show your support by starring it on GitHub.

Usage

For Docker specific usage, see the Docker section.

Install dependencies with Pipenv

pipenv install

If you wish to include development dependencies, add --dev.

Configure your bot

Modify the example configuration file example/config.toml with your TELEGRAM_API_TOKEN and TELEGRAM_USERNAME.

  • Interact with @BotFather to create a new bot and get its API token.

For more information, see the Configuration section.

Run the application

pipenv run app examples/config.toml

Interact with your bot on Telegram

Send a message to your bot and it will respond. Bots can also see and understand images, if the model supports this.

Send /help to see a list of commands:

Actions
/new - Start a new conversation
/retry - Retry the last response
/reply - Reply immediately
/undo - Undo the last exchange
/clear - Clear the current conversation
/remember <text> - Add text to memory

Information
/stats - Show conversation statistics
/help - Show this help message

Configuration

The application is configured by a config file and one or more context files.

Config file

The config TOML file initializes one or more bots and defines the paths to their context files.

See example/config.toml for a template config file:

[[simulacra]]
context_filepath = "example/context.yml"
telegram_token = "TELEGRAM_API_TOKEN"
authorized_users = [ "TELEGRAM_USERNAME" ] # [ "@username", ... ]

Context file

Note: This section no longer reflects the current state of the application.

The context file is a YAML file that defines a bot's personality prompts, stores its conversation history, and memory.

See example/context.yml for a sample context file.

A config file contains the following top-level YAML keys:

Key Description
names Contains two sub-keys assistant and user which identify the names of the bot and user.
chat_prompt The system prompt. Describe the bot's personality and its instructions here. Write as much detail as you can. See the Prompt Design section.
reinforcement_chat_prompt An optional extra system message provided very last in the context window. Use this to briefly reinforce the bot's personality and instructions. Keep it short.
conversations This key will be generated by the application and contains the bot's conversation history and memory. You may edit this section at any time to manually modify the bot's memory.

Changes to the context file take effect immediately. You do not need to restart the application.

Docker

This project publishes a Docker image to GHCR ghcr.io/njbbaer/simulacra.

Configure your container with the following:

  • Mount a directory containing your config and context files to /config.
  • Set the path to your config file in the environment as CONFIG_FILEPATH.
  • Set your OpenAI API key in the environment as OPENAI_API_KEY.

Ensure the context file paths in your config are accessible within the container (i.e. /config).

Docker examples

Docker run

docker run --name simulacra \
  --volume /var/lib/simulacra:/config \
  --env OPENAI_API_KEY=your_openai_api_key \
  --env CONFIG_FILEPATH=/config/config.toml \
  --restart unless-stopped \
  ghcr.io/njbbaer/simulacra:latest

Docker Compose

services:
  simulacra:
    image: ghcr.io/njbbaer/simulacra:latest
    container_name: simulacra
    volumes:
      - /var/lib/simulacra:/config
    environment:
      - OPENAI_API_KEY={{ your_openai_api_key }}
      - CONFIG_FILEPATH=/config/config.toml
    restart: unless-stopped

Development

Code reloading

Enable code reloading with development mode. Create a .env file or add the following to your environment:

export ENVIRONMENT=development

Note: Development mode can only run a single bot at once.

Pre-commit hooks

Install pre-commit hooks to run code formatting and linting before committing:

pipenv run pre-commit install

Run tests

pipenv run test

Release a new version

New versions are released automatically by GitHub Actions when a new tag is pushed.

A shortcut script is provided to create a new tag and push it to the repository:

make release version=0.0.0

simulacra's People

Contributors

njbbaer avatar

Stargazers

 avatar  avatar

Watchers

 avatar Kostas Georgiou avatar  avatar

simulacra's Issues

Refactor tests

  • Switch to pytest
  • Create helper methods
  • Mock filesystem operations

Implement divide-and-conquer recursive summarization algorithm

  1. Start with a conversation transcript and a chunked memory document.
  2. Compress each chunk in parallel by about 20%.
  3. Iterate through the compressed chunks and merge consecutive items that sum to less than 2,000 chars.
  4. Summarize the conversation transcript and append it to the list of chunks.

Fix Telegram timeout error

Process Process-1:
Traceback (most recent call last):
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/anyio/streams/tls.py", line 133, in _call_sslobject_method
    result = func(*args)
  File "/usr/lib/python3.10/ssl.py", line 917, in read
    v = self._sslobj.read(len)
ssl.SSLWantReadError: The operation did not complete (read) (_ssl.c:2578)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/anyio/_core/_tasks.py", line 115, in fail_after
    yield cancel_scope
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/httpcore/_backends/anyio.py", line 34, in read
    return await self._stream.receive(max_bytes=max_bytes)
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/anyio/streams/tls.py", line 198, in receive
    data = await self._call_sslobject_method(self._ssl_object.read, max_bytes)
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/anyio/streams/tls.py", line 140, in _call_sslobject_method
    data = await self.transport_stream.receive()
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 1103, in receive
    await self._protocol.read_event.wait()
  File "/usr/lib/python3.10/asyncio/locks.py", line 214, in wait
    await fut
asyncio.exceptions.CancelledError: Cancelled by cancel scope 7fd1470cc6d0

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/httpcore/_exceptions.py", line 10, in map_exceptions
    yield
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/httpcore/_backends/anyio.py", line 32, in read
    with anyio.fail_after(timeout):
  File "/usr/lib/python3.10/contextlib.py", line 153, in __exit__
    self.gen.throw(typ, value, traceback)
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/anyio/_core/_tasks.py", line 118, in fail_after
    raise TimeoutError
TimeoutError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/httpx/_transports/default.py", line 60, in map_httpcore_exceptions
    yield
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/httpx/_transports/default.py", line 353, in handle_async_request
    resp = await self._pool.handle_async_request(req)
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/httpcore/_async/connection_pool.py", line 262, in handle_async_request
    raise exc
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/httpcore/_async/connection_pool.py", line 245, in handle_async_request
    response = await connection.handle_async_request(request)
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/httpcore/_async/connection.py", line 96, in handle_async_request
    return await self._connection.handle_async_request(request)
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/httpcore/_async/http11.py", line 121, in handle_async_request
    raise exc
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/httpcore/_async/http11.py", line 99, in handle_async_request
    ) = await self._receive_response_headers(**kwargs)
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/httpcore/_async/http11.py", line 164, in _receive_response_headers
    event = await self._receive_event(timeout=timeout)
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/httpcore/_async/http11.py", line 200, in _receive_event
    data = await self._network_stream.read(
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/httpcore/_backends/anyio.py", line 31, in read
    with map_exceptions(exc_map):
  File "/usr/lib/python3.10/contextlib.py", line 153, in __exit__
    self.gen.throw(typ, value, traceback)
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/httpcore/_exceptions.py", line 14, in map_exceptions
    raise to_exc(exc) from exc
httpcore.ReadTimeout

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/telegram/request/_httpxrequest.py", line 219, in do_request
    res = await self._client.request(
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/httpx/_client.py", line 1530, in request
    return await self.send(request, auth=auth, follow_redirects=follow_redirects)
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/httpx/_client.py", line 1617, in send
    response = await self._send_handling_auth(
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/httpx/_client.py", line 1645, in _send_handling_auth
    response = await self._send_handling_redirects(
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/httpx/_client.py", line 1682, in _send_handling_redirects
    response = await self._send_single_request(request)
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/httpx/_client.py", line 1719, in _send_single_request
    response = await transport.handle_async_request(request)
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/httpx/_transports/default.py", line 352, in handle_async_request
    with map_httpcore_exceptions():
  File "/usr/lib/python3.10/contextlib.py", line 153, in __exit__
    self.gen.throw(typ, value, traceback)
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/httpx/_transports/default.py", line 77, in map_httpcore_exceptions
    raise mapped_exc(message) from exc
httpx.ReadTimeout

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3.10/multiprocessing/process.py", line 314, in _bootstrap
    self.run()
  File "/usr/lib/python3.10/multiprocessing/process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "/home/nate/simulacra/start.py", line 12, in run_bot
    ).run()
  File "/home/nate/simulacra/src/telegram/telegram_bot.py", line 35, in run
    self.app.run_polling()
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/telegram/ext/_application.py", line 765, in run_polling
    return self.__run(
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/telegram/ext/_application.py", line 963, in __run
    loop.run_until_complete(self.updater.stop())  # type: ignore[union-attr]
  File "/usr/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
    return future.result()
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/telegram/ext/_updater.py", line 752, in stop
    await self._stop_polling()
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/telegram/ext/_updater.py", line 777, in _stop_polling
    await self.__polling_cleanup_cb()
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/telegram/ext/_updater.py", line 381, in _get_updates_cleanup
    await self.bot.get_updates(
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/telegram/ext/_extbot.py", line 553, in get_updates
    updates = await super().get_updates(
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/telegram/_bot.py", line 394, in decorator
    result = await func(self, *args, **kwargs)  # skipcq: PYL-E1102
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/telegram/_bot.py", line 3542, in get_updates
    await self._post(
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/telegram/_bot.py", line 482, in _post
    return await self._do_post(
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/telegram/ext/_extbot.py", line 335, in _do_post
    return await super()._do_post(
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/telegram/_bot.py", line 510, in _do_post
    return await request.post(
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/telegram/request/_baserequest.py", line 168, in post
    result = await self._request_wrapper(
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/telegram/request/_baserequest.py", line 288, in _request_wrapper
    raise exc
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/telegram/request/_baserequest.py", line 278, in _request_wrapper
    code, payload = await self.do_request(
  File "/home/nate/.local/share/virtualenvs/simulacra-YP_erhNu/lib/python3.10/site-packages/telegram/request/_httpxrequest.py", line 236, in do_request
    raise TimedOut from err
telegram.error.TimedOut: Timed out

Update README

How to:

  • Use Docker
  • Write config file
  • Write context file

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.