Skip to content

Commit

Permalink
Updated how config is handled
Browse files Browse the repository at this point in the history
Signed-off-by: JonahSussman <sussmanjonah@gmail.com>
  • Loading branch information
JonahSussman committed Aug 29, 2024
1 parent f370353 commit f765975
Show file tree
Hide file tree
Showing 18 changed files with 283 additions and 116 deletions.
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ CWD := $(shell pwd)
KAI_PYTHON_PATH="$(CWD)/kai:$(PYTHONPATH)"
LOGLEVEL ?= info
NUM_WORKERS ?= 8
DEMO_MODE ?= False
KAI__DEMO_MODE ?= False
DROP_TABLES ?= False
HUB_URL ?= ""
IMPORTER_ARGS ?= ""
Expand All @@ -13,8 +13,9 @@ POSTGRES_RUN_ARGS ?=
run-postgres:
$(CONTAINER_RUNTIME) run -it $(POSTGRES_RUN_ARGS) -v data:/var/lib/postgresql/data -e POSTGRES_USER=kai -e POSTGRES_PASSWORD=dog8code -e POSTGRES_DB=kai -p 5432:5432 docker.io/library/postgres:16.3

# FIXME: This does not currently work
run-server:
PYTHONPATH=$(KAI_PYTHON_PATH) LOGLEVEL=$(LOGLEVEL) DEMO_MODE=$(DEMO_MODE) gunicorn --timeout 3600 -w $(NUM_WORKERS) --bind localhost:8080 --worker-class aiohttp.GunicornWebWorker 'kai.server:app()'
PYTHONPATH=$(KAI_PYTHON_PATH) python kai/server.py

run-konveyor-importer:
PYTHONPATH=$(KAI_PYTHON_PATH) python ./kai/hub_importer.py --loglevel ${LOGLEVEL} --config_filepath ./kai/config.toml ${IMPORTER_ARGS} ${HUB_URL}
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ The quickest way to get running is to leverage sample data committed into the Ka
version: "3"

x-kai-variables: &kai-variables
- DEMO_MODE: "False"
+ DEMO_MODE: "True"
- KAI__DEMO_MODE: "False"
+ KAI__DEMO_MODE: "True"
HUB_URL: ${HUB_URL:-https://tackle-konveyor-tackle.apps.example.com/hub}
IMPORTER_ARGS:
LOG_LEVEL: info
Expand Down
16 changes: 15 additions & 1 deletion build/Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,25 @@ RUN echo -e "[almalinux9-appstream]" \
"\nbaseurl = https://repo.almalinux.org/almalinux/9/AppStream/\$basearch/os/" \
"\nenabled = 1" \
"\ngpgcheck = 0" > /etc/yum.repos.d/almalinux.repo

RUN dnf -y install postgresql && dnf clean all
USER 1001
COPY --chown=1001:1001 . /kai

# Directories required for the build
# Contains entrypoint.sh
COPY --chown=1001:1001 ./build /kai/build
# Contains the kai source code
COPY --chown=1001:1001 ./kai /kai/kai
# Contains initial data for the database
COPY --chown=1001:1001 ./samples /kai/samples

# Files required for the build
COPY --chown=1001:1001 ./pyproject.toml /kai/pyproject.toml
COPY --chown=1001:1001 ./requirements.txt /kai/requirements.txt

RUN pip install --no-cache -r /kai/requirements.txt
RUN pip install --no-cache -e /kai

RUN cd /kai/samples && ./fetch_apps.py
COPY build/entrypoint.sh /usr/local/bin/entrypoint.sh
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
19 changes: 8 additions & 11 deletions build/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
#!/bin/bash

# If we are using podman or docker compose use the repo config.toml
if [[ -f /podman_compose/kai/config.toml ]]; then
cp /podman_compose/kai/config.toml /kai/kai/config.toml
sed -i "s/^host =.*/host = \"${POSTGRESQL_HOST}\"/g" /kai/kai/config.toml
sed -i "s/^database =.*/database = \"${POSTGRESQL_DATABASE}\"/g" /kai/kai/config.toml
sed -i "s/^user =.*/user = \"${POSTGRESQL_USER}\"/g" /kai/kai/config.toml
sed -i "s/^password =.*/password =\"${POSTGRESQL_PASSWORD}\"/g" /kai/kai/config.toml
# If a custom config is specified, use it
if [[ -f /podman_compose/build/config.toml ]]; then
printf "Using custom config.toml\n"
cp /podman_compose/build/config.toml /kai/kai/config.toml
fi

until PGPASSWORD="${POSTGRESQL_PASSWORD}" pg_isready -q -h "${POSTGRESQL_HOST}" -U "${POSTGRESQL_USER}" -d "${POSTGRESQL_DATABASE}"; do
until PGPASSWORD="${KAI__INCIDENT_STORE__ARGS__PASSWORD}" pg_isready -q -h "${KAI__INCIDENT_STORE__ARGS__HOST}" -U "${KAI__INCIDENT_STORE__ARGS__USER}" -d "${KAI__INCIDENT_STORE__ARGS__DATABASE}"; do
sleep 1
done

Expand All @@ -19,7 +16,7 @@ if [[ ${MODE} != "importer" ]]; then
SQL_EXISTS=$(printf "\dt %s" "${TABLE}")
STDERR="Did not find any relation"
# trunk-ignore(shellcheck/SC2312)
if PGPASSWORD="${POSTGRESQL_PASSWORD}" psql -h "${POSTGRESQL_HOST}" -U "${POSTGRESQL_USER}" -d "${POSTGRESQL_DATABASE}" -c "${SQL_EXISTS}" 2>&1 | grep -q -v "${STDERR}"; then
if PGPASSWORD="${KAI__INCIDENT_STORE__ARGS__PASSWORD}" psql -h "${KAI__INCIDENT_STORE__ARGS__HOST}" -U "${KAI__INCIDENT_STORE__ARGS__USER}" -d "${KAI__INCIDENT_STORE__ARGS__DATABASE}" -c "${SQL_EXISTS}" 2>&1 | grep -q -v "${STDERR}"; then
echo "################################################"
echo "load-data has run already run, starting server.#"
echo "################################################"
Expand All @@ -37,8 +34,8 @@ if [[ ${MODE} != "importer" ]]; then
sleep 5
fi
fi
PYTHONPATH="/kai/kai" exec gunicorn --timeout 3600 -w "${NUM_WORKERS}" --bind 0.0.0.0:8080 --worker-class aiohttp.GunicornWebWorker 'kai.server:app()'
PYTHONPATH="/kai/kai" python /kai/kai/server.py
else
cd /kai || exit
python ./kai/hub_importer.py --loglevel "${LOGLEVEL}" --config_filepath ./kai/config.toml "${HUB_URL}" "${IMPORTER_ARGS}"
python ./kai/hub_importer.py --loglevel "${KAI__LOG_LEVEL}" --config_filepath ./kai/config.toml "${KAI__HUB_URL}" "${KAI__IMPORTER_ARGS}"
fi
146 changes: 146 additions & 0 deletions build/example_config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
log_level = "info"
file_log_level = "debug"
log_dir = "$pwd/logs"
demo_mode = false
trace_enabled = true

# **Solution consumers** This controls the strategies the LLM uses to consume
# solutions.
# - "diff_only": consumes only the diff between the the initial and solved
# states
# - "llm_summary": If the incident store's `solution_producers` field is
# configured to use "llm_lazy", the solution used will include an
# llm-generated summary of the changes required.

solution_consumers = ["diff_only", "llm_summary"]

# **Postgresql incident store**
# ```
# [incident_store.args]
# provider = "postgresql"
# host = "127.0.0.1"
# database = "kai"
# user = "kai"
# password = "dog8code"
# ```

# **In-memory sqlite incident store**
# ```
# [incident_store.args]
# provider = "sqlite"
# connection_string = "sqlite:///:memory:"
# ```

[incident_store]

# **incident_store.solution_detectors** This controls the strategies the
# incident store uses to detect when an incident was solved.
# - "naive": Incidents are considered the same if every field in the incident is
# the exact same.
# - "line_match": Same as "naive", except we take into account if the line has
# moved about in the file.

solution_detectors = "naive"

# **incident_store.solution_producers** This controls the strategies the
# incident store uses to produce incidents.
# - "text_only": Only the textual information (diff, code before, code after) of
# the incident is stored.
# - "llm_lazy": Same as "text_only", but will earmark the solution for LLM
# summary generation upon retrieval.

solution_producers = "text_only"

# Only set this if you want to use a different incident store than the default.
# If you are running it using podman compose, you should probably leave this
# alone.

[incident_store.args]
provider = "postgresql"

host = "127.1.0.1"
database = "kai"
user = "kai"
password = "dog8code"

# **IBM served granite**
# ```
# [models]
# provider = "ChatIBMGenAI"

# [models.args]
# model_id = "ibm/granite-13b-chat-v2"
# ```

# **IBM served mistral**
# ```
# [models]
# provider = "ChatIBMGenAI"

# [models.args]
# model_id = "mistralai/mixtral-8x7b-instruct-v01"
# ```

# **IBM served codellama**
# ```
# [models]
# provider = "ChatIBMGenAI"

# [models.args]
# model_id = "meta-llama/llama-2-13b-chat"
# ```

# **IBM served llama3**
# ```
# # Note: llama3 complains if we use more than 2048 tokens
# # See: https://github.com/konveyor-ecosystem/kai/issues/172
# [models]
# provider = "ChatIBMGenAI"

# [models.args]
# model_id = "meta-llama/llama-3-70b-instruct"
# parameters.max_new_tokens = 2048
# ```

# **Ollama**
# ```
# [models]
# provider = "ChatOllama"

# [models.args]
# model = "mistral"
# ```

# **OpenAI GPT 4**
# ```
# [models]
# provider = "ChatOpenAI"

# [models.args]
# model = "gpt-4"
# ```

# **OpenAI GPT 3.5**
# ```
# [models]
# provider = "ChatOpenAI"

# [models.args]
# model = "gpt-3.5-turbo"
# ```

# **Amazon Bedrock served Anthropic Claude 3.5 Sonnet **
# ```
# [models]
# provider = "ChatBedrock"

# [models.args]
# model_id = "anthropic.claude-3-5-sonnet-20240620-v1:0"
# ```


[models]
provider = "ChatIBMGenAI"

[models.args]
model_id = "mistralai/mixtral-8x7b-instruct-v01"
44 changes: 27 additions & 17 deletions compose.yaml
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
version: "3"

# TODO: Unify hub importer variables with kai variables. They are currently not
# stored on KaiConfig.

x-kai-variables: &kai-variables
DEMO_MODE: "True"
HUB_URL: ${HUB_URL:-https://tackle-konveyor-tackle.apps.example.com/hub}
IMPORTER_ARGS:
LOG_LEVEL: info
LOG_DIR: "/podman_compose/logs"
NUM_WORKERS: 8
KAI__LOG_LEVEL: info
KAI__LOG_DIR: "/podman_compose/logs"
KAI__GUNICORN_WORKERS: 1
KAI__GUNICORN_BIND: "0.0.0.0:8080"
KAI__HUB_URL: ${HUB_URL:-https://tackle-konveyor-tackle.apps.example.com/hub}
KAI__IMPORTER_ARGS:
USE_HUB_IMPORTER: ${USE_HUB_IMPORTER:-False}
# KAI__DEMO_MODE: "True"

KAI__INCIDENT_STORE__ARGS__PROVIDER: postgresql
KAI__INCIDENT_STORE__ARGS__DATABASE: kai
KAI__INCIDENT_STORE__ARGS__PASSWORD: dog8code
KAI__INCIDENT_STORE__ARGS__USER: kai
KAI__INCIDENT_STORE__ARGS__HOST: kai_db

x-db-variables: &db-variables
POSTGRESQL_DATABASE: kai
POSTGRESQL_PASSWORD: dog8code
POSTGRESQL_USER: kai
POSTGRESQL_HOST: kai_db
POSTGRESQL_DATABASE: "${KAI__INCIDENT_STORE__ARGS__DATABASE:-kai}"
POSTGRESQL_PASSWORD: "${KAI__INCIDENT_STORE__ARGS__PASSWORD:-dog8code}"
POSTGRESQL_USER: "${KAI__INCIDENT_STORE__ARGS__USER:-kai}"
POSTGRESQL_HOST: "${KAI__INCIDENT_STORE__ARGS__HOST:-kai_db}"

services:
kai:
environment:
<<: [*db-variables, *kai-variables]
<<: [*kai-variables, *db-variables]
# Do not edit the variables below otherwise you risk committing keys to a
# public repo These lines will pass in the environment variables from your
# host system.
Expand All @@ -27,20 +37,20 @@ services:
OPENAI_API_KEY:
image: ${IMAGE:-quay.io/konveyor/kai}:${TAG:-stable}
volumes:
- ${PWD}:/podman_compose:rw,z
- ${PWD}/logs:/podman_compose/logs:rw,z,U
- ${PWD}:/podman_compose:rw,Z
# - ${PWD}/logs:/podman_compose/logs:rw,Z,U
ports:
- "8080:8080"
depends_on:
- kai_db
kai_hub_importer:
environment:
<<: [*db-variables, *kai-variables]
<<: [*kai-variables, *db-variables]
MODE: importer
image: ${IMAGE:-quay.io/konveyor/kai}:${TAG:-stable}
volumes:
- ${PWD}:/podman_compose:rw,z
- ${PWD}/logs:/podman_compose/logs:rw,z,U
- ${PWD}:/podman_compose:rw,Z
- ${PWD}/logs:/podman_compose/logs:rw,Z,U
depends_on:
- kai_db
profiles:
Expand All @@ -50,6 +60,6 @@ services:
environment:
<<: *db-variables
volumes:
- kai_db_data:/var/lib/postgresql/data:z
- kai_db_data:/var/lib/postgresql/data:Z
volumes:
kai_db_data:
4 changes: 2 additions & 2 deletions docs/Getting_Started.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ Running Kai consists of:

- _The easiest way to run is to leverage prebuilt container images we publish to [quay.io/konveyor/kai](https://quay.io/repository/konveyor/kai?tab=tags), you can learn more about early builds at [docs/Evaluation_Builds.md](/docs/Evaluation_Builds.md)_
- _This is the simplest configuration which will limit configuration choices and will use cached LLM results so that you may evaluate Kai without having your own API Keys_
- The cached data uses a `DEMO_MODE=TRUE` mode for running the backend. See [docs/contrib/Demo_Mode.md](/docs/contrib/Demo_Mode.md) for more information.
- The cached data uses a `KAI__DEMO_MODE=TRUE` mode for running the backend. See [docs/contrib/Demo_Mode.md](/docs/contrib/Demo_Mode.md) for more information.
- Configured via:
- [kai/config.toml](/kai/config.toml): `demo_mode = true`
- [compose.yaml](/compose.yaml): `DEMO_MODE: "TRUE"`
- [compose.yaml](/compose.yaml): `KAI__DEMO_MODE: "TRUE"`
- Follow the guided scenario at [docs/scenarios/demo.md](/docs/scenarios/demo.md) to evaluate Kai

### Launch Kai with sample data and cached LLM responses
Expand Down
18 changes: 9 additions & 9 deletions docs/contrib/Demo_Mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,35 @@ The kai server is able to cache results from a LLM and later replay these to aid

This mode uses a project called [vcr](https://vcrpy.readthedocs.io/en/latest/) to record the interaction with a given LLM.

## What to expect from `DEMO_MODE`
## What to expect from `KAI__DEMO_MODE`

_if_ the `kai/data/vcr/<application_name>/<model>` directory contains a request which has been cached AND if `DEMO_MODE` is enabled then a request that has the same exact parameters as what was seen during recording will return the cached data and will instead of talking to the LLM.
_if_ the `kai/data/vcr/<application_name>/<model>` directory contains a request which has been cached AND if `KAI__DEMO_MODE` is enabled then a request that has the same exact parameters as what was seen during recording will return the cached data and will instead of talking to the LLM.

This mode is most useful for situations where you want to demo functionality but are concerned about conference wifi. The data replayed is actual data that specific LLM generated in past, it's just cached for convenience.

## Notes on `DEMO_MODE` and cached responses
## Notes on `KAI__DEMO_MODE` and cached responses

The kai server will always cache responses in the `kai/data/vcr/<application_name>/<model>` directory. In non-demo mode, these responses will be overwritten whenever a new request is made.
When the server is run with `DEMO_MODE=true`, these responses will be played back. The request will be matched on everything except for authorization headers, cookies, content-length and request body.
When the server is run with `KAI__DEMO_MODE=true`, these responses will be played back. The request will be matched on everything except for authorization headers, cookies, content-length and request body.

### `DEMO_MODE` Cached Responses
### `KAI__DEMO_MODE` Cached Responses

- We do not actively maintain cached responses for all models/requests.
- You may look at: [kai/data/vcr/coolstore](kai/data/vcr/coolstore/) to see a list of what models have cached responses.
- In general when we cache responses we are running: [example/run_demo.py](example/run_demo.py) and saving those responses.
- This corresponds to a 'KAI Fix All' being run per file in Analysis.
- When running from IDE and attempting to use cached response, we likely only have cached responses for 'Fix All', and we do not have cached responses for individual issues in a file.

### `DEMO_MODE` Updating Cached Responses
### `KAI__DEMO_MODE` Updating Cached Responses

There are two ways to record new responses:

1. Run the requests while the server is not in `DEMO_MODE`
1. Run the requests while the server is not in `KAI__DEMO_MODE`
1. Delete the specific existing cached response (under `kai/data/vcr/<application_name>/<model>/<source-file-path-with-slashes-replaced-with-dashes.java.yaml>`), then rerun. When a cached response does not exist, a new one will be recorded and played back on subsequent runs.

### Seeing a `401` while running with `DEMO_MODE=TRUE`?
### Seeing a `401` while running with `KAI__DEMO_MODE=TRUE`?

If you are running with DEMO_MODE=TRUE and you see a `401` being returned from the LLM Provider consider that this is likely 'correct' behavior, if you do not have a valid API key defined. Note that DEMO_MODE will attempt to play back a cached response, yet if there is no cached data for the request Kai will attempt to talk to the LLM and will make a 'real' request, which if you don't have a valid API key will result in a `401`. To 'fix' this you will want to look at the request you are sending to Kai and ensure it is cached for the model you have configured, if you don't have valid cached data then you will need to get a valid api key and re-run so the data may be cached.
If you are running with KAI**DEMO_MODE=TRUE and you see a `401` being returned from the LLM Provider consider that this is likely 'correct' behavior, if you do not have a valid API key defined. Note that KAI**DEMO_MODE will attempt to play back a cached response, yet if there is no cached data for the request Kai will attempt to talk to the LLM and will make a 'real' request, which if you don't have a valid API key will result in a `401`. To 'fix' this you will want to look at the request you are sending to Kai and ensure it is cached for the model you have configured, if you don't have valid cached data then you will need to get a valid api key and re-run so the data may be cached.

WARNING - 2024-07-11 14:11:44,063 - [ llm_io_handler.py:243 - get_incident_solutions_for_file()] - Request to model failed for batch 1/1 for src/main/java/com/redhat/coolstore/model/InventoryEntity.java with exception, retrying in 10s
Failed to handle request to https://bam-api.res.ibm.com/v2/text/chat_stream?version=2024-01-10.
Expand Down
Loading

0 comments on commit f765975

Please sign in to comment.