diff --git a/etc/services/continuwuity/compose.yml b/etc/services/continuwuity/compose.yml new file mode 100644 index 0000000..ed2a86f --- /dev/null +++ b/etc/services/continuwuity/compose.yml @@ -0,0 +1,23 @@ +services: + continuwuity: + image: forgejo.ellis.link/continuwuation/continuwuity:v0.5.5 + user: "${UID}:${GID}" + restart: unless-stopped + cap_drop: + - ALL + read_only: true + environment: + CONDUWUIT_CONFIG: /etc/continuwuity/continuwuity.toml + CONDUWUIT_DATABASE_PATH: /var/lib/continuwuity + ports: + - "${SERVICE_CONTINUWUITY_BIND_PORT_CLIENT_API}:6167" + volumes: + - ../../etc/services/continuwuity/config:/etc/continuwuity:ro + - ./continuwuity/data:/var/lib/continuwuity + tmpfs: + - /tmp:rw,noexec,nosuid,size=500m + +networks: + default: + name: ${NETWORK_NAME} + external: true diff --git a/etc/services/continuwuity/config/continuwuity.toml b/etc/services/continuwuity/config/continuwuity.toml new file mode 100644 index 0000000..5165a70 --- /dev/null +++ b/etc/services/continuwuity/config/continuwuity.toml @@ -0,0 +1,19 @@ +[global] +server_name = "continuwuity.127.0.0.1.nip.io" + +address = "0.0.0.0" +port = 6167 + +database_path = "/var/lib/continuwuity" + +allow_registration = true +yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse = true + +new_user_displayname_suffix = "" + +max_request_size = 20_000_000 + +allow_federation = false +trusted_servers = ["matrix.org"] + +log = "info,state_res=warn,rocket=off,_=off,sled=off" diff --git a/etc/services/continuwuity/register-user.sh b/etc/services/continuwuity/register-user.sh new file mode 100755 index 0000000..539f37b --- /dev/null +++ b/etc/services/continuwuity/register-user.sh @@ -0,0 +1,48 @@ +#!/bin/sh +set -eu + +if [ $# -ne 3 ]; then + echo "Usage: $0 " + exit 1 +fi + +ENV_FILE="$1" +USERNAME="$2" +PASSWORD="$3" + +SERVER="http://$(grep '^SERVICE_CONTINUWUITY_BIND_PORT_CLIENT_API=' "${ENV_FILE}" | cut -d= -f2)" +REGISTER_URL="${SERVER}/_matrix/client/v3/register" + +echo "Registering user '${USERNAME}' on ${SERVER}..." + +SESSION_RESPONSE=$(curl -s -X POST "${REGISTER_URL}" \ + -H 'Content-Type: application/json' \ + -d "{\"username\": \"${USERNAME}\", \"password\": \"${PASSWORD}\"}") + +SESSION_ID=$(echo "${SESSION_RESPONSE}" | grep -o '"session":"[^"]*"' | head -1 | cut -d'"' -f4) +if [ -z "${SESSION_ID}" ]; then + echo "Error: Could not get session ID. Response: ${SESSION_RESPONSE}" + exit 1 +fi + +# Determine the required auth flow from the server response. +# The first user requires m.login.registration_token (bootstrap token from logs). +# Subsequent users use m.login.dummy (open registration). +if echo "${SESSION_RESPONSE}" | grep -q 'm.login.registration_token'; then + CONTAINER_ID=$(docker ps -q --filter name=baibot-continuwuity-continuwuity) + REG_TOKEN=$(docker logs "${CONTAINER_ID}" 2>&1 | sed 's/\x1b\[[0-9;]*m//g' | grep 'using the registration token' | grep -oP 'registration token \K[A-Za-z0-9]+' | head -1) + AUTH_BODY="{\"type\": \"m.login.registration_token\", \"token\": \"${REG_TOKEN}\", \"session\": \"${SESSION_ID}\"}" +else + AUTH_BODY="{\"type\": \"m.login.dummy\", \"session\": \"${SESSION_ID}\"}" +fi + +RESULT=$(curl -s -X POST "${REGISTER_URL}" \ + -H 'Content-Type: application/json' \ + -d "{\"username\": \"${USERNAME}\", \"password\": \"${PASSWORD}\", \"auth\": ${AUTH_BODY}}") + +if echo "${RESULT}" | grep -q '"user_id"'; then + echo "Successfully registered user: $(echo "${RESULT}" | grep -o '"user_id":"[^"]*"' | cut -d'"' -f4)" +else + echo "Registration failed. Response: ${RESULT}" + exit 1 +fi diff --git a/etc/services/env.dist b/etc/services/env.dist index bb034f0..71939a9 100644 --- a/etc/services/env.dist +++ b/etc/services/env.dist @@ -3,6 +3,8 @@ SERVICE_SYNAPSE_BIND_PORT_FEDERATION_API=127.0.0.1:42028 SERVICE_ELEMENT_WEB_BIND_PORT_HTTP=127.0.0.1:42025 +SERVICE_CONTINUWUITY_BIND_PORT_CLIENT_API=127.0.0.1:42030 + SERVICE_OLLAMA_BIND_PORT_HTTP=127.0.0.1:42026 # See https://localai.io/basics/container/#all-in-one-images for the list of available images diff --git a/justfile b/justfile index a86cde5..e5aceaa 100644 --- a/justfile +++ b/justfile @@ -2,6 +2,11 @@ project_name := "baibot" container_image_name := "localhost/baibot" project_container_network := "baibot" +admin_username := "admin" +admin_password := "admin" +bot_username := "baibot" +bot_password := "baibot" + mise_data_dir := env("MISE_DATA_DIR", justfile_directory() / "var/mise") mise_trusted_config_paths := justfile_directory() / "mise.toml" @@ -80,6 +85,10 @@ docker-compose-localai *extra_args: docker-compose-ollama *extra_args: just docker-compose ollama {{ extra_args }} +# Runs a docker-compose command against the continuwuity services +docker-compose-continuwuity *extra_args: + just docker-compose continuwuity {{ extra_args }} + # Runs all core dependency components (in the background) services-start: services-prepare (docker-compose-core "up" "-d") @@ -116,6 +125,27 @@ ollama-tail-logs: (docker-compose-ollama "logs" "-f") # Prepares Ollama for running ollama-prepare: _prepare-var-services-env _prepare-var-services-ollama _prepare-container-network +# Runs Continuwuity (in the background) +continuwuity-start: continuwuity-prepare (docker-compose-continuwuity "up" "-d") + +# Stops Continuwuity +continuwuity-stop: (docker-compose-continuwuity "down") + +# Tails the logs for Continuwuity +continuwuity-tail-logs: (docker-compose-continuwuity "logs" "-f") + +# Prepares Continuwuity for running +continuwuity-prepare: _prepare-var-services-env _prepare-var-services-continuwuity _prepare-container-network + +# Registers a user on Continuwuity via the Matrix Client-Server API +continuwuity-register-user username password: + {{ justfile_directory() }}/etc/services/continuwuity/register-user.sh {{ justfile_directory() }}/var/services/env {{ username }} {{ password }} + +# Prepares the Continuwuity user accounts +continuwuity-users-prepare: + just -f {{ justfile_directory() }}/justfile continuwuity-register-user "{{ admin_username }}" "{{ admin_password }}" + just -f {{ justfile_directory() }}/justfile continuwuity-register-user "{{ bot_username }}" "{{ bot_password }}" + # Pulls an Ollama model ollama-pull-model model_id: just -f {{ justfile_directory() }}/justfile docker-compose-ollama \ @@ -130,8 +160,8 @@ app-container-prepare: _prepare-var-app-container-config_yml _prepare-var-app-co # Prepares the user accounts users-prepare: services-prepare - just -f {{ justfile_directory() }}/justfile synapse-register-admin-user "admin" "admin" - just -f {{ justfile_directory() }}/justfile synapse-register-regular-user "baibot" "baibot" + just -f {{ justfile_directory() }}/justfile synapse-register-admin-user "{{ admin_username }}" "{{ admin_password }}" + just -f {{ justfile_directory() }}/justfile synapse-register-regular-user "{{ bot_username }}" "{{ bot_password }}" # Starts a Postgres CLI (psql) postgres-cli: services-prepare (docker-compose-core "exec" "postgres" "/bin/sh" "-c" "'PGUSER=synapse PGPASSWORD=synapse-password PGDATABASE=homeserver psql -h postgres'") @@ -237,6 +267,14 @@ _prepare-var-services-ollama: mkdir -p var/services/ollama fi +_prepare-var-services-continuwuity: + #!/bin/sh + cd {{ justfile_directory() }}; + + if [ ! -f var/services/continuwuity ]; then + mkdir -p var/services/continuwuity/data + fi + _prepare-var-services-localai: #!/bin/sh cd {{ justfile_directory() }};