rename cli to plano (#647)

This commit is contained in:
Adil Hafeez 2025-12-23 18:37:58 -08:00 committed by GitHub
parent e224cba3e3
commit e7ce00b5a7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
70 changed files with 226 additions and 212 deletions

View file

@ -1,7 +1,7 @@
name: Publish docker image (latest)
env:
DOCKER_IMAGE: katanemo/archgw
DOCKER_IMAGE: katanemo/plano
on:
push:

View file

@ -1,7 +1,7 @@
name: Publish docker image (release)
env:
DOCKER_IMAGE: katanemo/archgw
DOCKER_IMAGE: katanemo/plano
on:
release:

View file

@ -1,4 +1,4 @@
name: e2e archgw tests
name: e2e plano tests
on:
push:
@ -7,7 +7,7 @@ on:
pull_request:
jobs:
e2e_archgw_tests:
e2e_plano_tests:
runs-on: ubuntu-latest-m
strategy:
fail-fast: false
@ -30,9 +30,9 @@ jobs:
- name: build arch docker image
run: |
cd ../../ && docker build -f arch/Dockerfile . -t katanemo/archgw -t katanemo/archgw:0.3.22 -t katanemo/archgw:latest
cd ../../ && docker build -f arch/Dockerfile . -t katanemo/plano -t katanemo/plano:0.4.0 -t katanemo/plano:latest
- name: start archgw
- name: start plano
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
@ -42,9 +42,9 @@ jobs:
AWS_BEARER_TOKEN_BEDROCK: ${{ secrets.AWS_BEARER_TOKEN_BEDROCK }}
run: |
docker compose up | tee &> archgw.logs &
docker compose up | tee &> plano.logs &
- name: wait for archgw to be healthy
- name: wait for plano to be healthy
run: |
source common.sh && wait_for_healthz http://localhost:10000/healthz
@ -58,11 +58,11 @@ jobs:
run: |
poetry install
- name: run archgw tests
- name: run plano tests
run: |
poetry run pytest || tail -100 archgw.logs
poetry run pytest || tail -100 plano.logs
- name: stop archgw docker container
- name: stop plano docker container
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}

View file

@ -22,9 +22,9 @@ jobs:
with:
python-version: "3.12"
- name: build arch docker image
- name: build plano docker image
run: |
docker build -f arch/Dockerfile . -t katanemo/archgw -t katanemo/archgw:0.3.22
docker build -f arch/Dockerfile . -t katanemo/plano -t katanemo/plano:0.4.0
- name: install poetry
run: |
@ -43,7 +43,7 @@ jobs:
- name: install arch gateway and test dependencies
run: |
source venv/bin/activate
cd arch/tools && echo "installing archgw cli" && poetry install
cd arch/tools && echo "installing plano cli" && poetry install
cd ../../demos/shared/test_runner && echo "installing test dependencies" && poetry install
- name: run demo tests

View file

@ -24,7 +24,7 @@ jobs:
- name: build arch docker image
run: |
docker build -f arch/Dockerfile . -t katanemo/archgw -t katanemo/archgw:0.3.22
docker build -f arch/Dockerfile . -t katanemo/plano -t katanemo/plano:0.4.0
- name: install poetry
run: |
@ -43,7 +43,7 @@ jobs:
- name: install arch gateway and test dependencies
run: |
source venv/bin/activate
cd arch/tools && echo "installing archgw cli" && poetry install
cd arch/tools && echo "installing plano cli" && poetry install
cd ../../demos/shared/test_runner && echo "installing test dependencies" && poetry install
- name: run demo tests

View file

@ -1,7 +1,7 @@
name: Publish docker image to ghcr (latest)
env:
IMAGE_NAME: ghcr.io/${{ github.repository_owner }}/archgw
IMAGE_NAME: ghcr.io/${{ github.repository_owner }}/plano
on:
push:
@ -33,7 +33,7 @@ jobs:
file: ./arch/Dockerfile
platforms: linux/arm64
push: true
# produce ghcr.io/<owner>/archgw:latest-arm64
# produce ghcr.io/<owner>/plano:latest-arm64
tags: ${{ steps.meta.outputs.tags }}-arm64
build-amd64:

View file

@ -1,7 +1,7 @@
name: release - publish docker image to ghcr (latest)
env:
IMAGE_NAME: ghcr.io/${{ github.repository_owner }}/archgw
IMAGE_NAME: ghcr.io/${{ github.repository_owner }}/plano
on:
release:

View file

@ -1,4 +1,4 @@
name: arch tools tests
name: plano tools tests
permissions:
contents: read
@ -10,7 +10,7 @@ on:
pull_request:
jobs:
arch_tools_tests:
plano_tools_tests:
runs-on: ubuntu-latest-m
defaults:
run:
@ -31,7 +31,7 @@ jobs:
curl -sSL https://install.python-poetry.org | python3 -
export PATH="$HOME/.local/bin:$PATH"
- name: install arch tools
- name: install plano tools
run: |
poetry install

View file

@ -24,8 +24,8 @@ jobs:
- name: build arch docker image
run: |
docker build -f arch/Dockerfile . -t katanemo/archgw -t katanemo/archgw:0.3.22
docker build -f arch/Dockerfile . -t katanemo/plano -t katanemo/plano:0.4.0
- name: validate arch config
run: |
bash arch/validate_arch_config.sh
bash arch/validate_plano_config.sh

View file

@ -1,6 +1,6 @@
services:
archgw:
image: katanemo/archgw:latest
plano:
image: katanemo/plano:latest
ports:
- "10000:10000"
- "10001:10001"

View file

@ -1,6 +1,6 @@
## Setup Instructions(User): archgw CLI
## Setup Instructions(User): plano CLI
This guide will walk you through the steps to set up the archgw cli on your local machine
This guide will walk you through the steps to set up the plano cli on your local machine
### Step 1: Create a Python virtual environment
@ -19,17 +19,17 @@ source venv/bin/activate
### Step 3: Run the build script
```bash
pip install archgw==0.3.22
pip install plano==0.4.0
```
## Uninstall Instructions: archgw CLI
## Uninstall Instructions: plano CLI
```bash
pip uninstall archgw
pip uninstall plano
```
## Setup Instructions (Dev): archgw CLI
## Setup Instructions (Dev): plano CLI
This guide will walk you through the steps to set up the archgw cli on your local machine when you want to develop the Archgw CLI
This guide will walk you through the steps to set up the plano cli on your local machine when you want to develop the plano CLI
### Step 1: Create a Python virtual environment
@ -53,16 +53,16 @@ poetry install
### Step 4: build Arch
```bash
archgw build
plano build
```
### Logs
`archgw` command can also view logs from the gateway. Use following command to view logs,
`plano` command can also view logs from the gateway. Use following command to view logs,
```bash
archgw logs --follow
plano logs --follow
```
## Uninstall Instructions: archgw CLI
## Uninstall Instructions: plano CLI
```bash
pip uninstall archgw
pip uninstall plano

View file

@ -1,5 +1,5 @@
import os
SERVICE_NAME_ARCHGW = "archgw"
ARCHGW_DOCKER_NAME = "archgw"
ARCHGW_DOCKER_IMAGE = os.getenv("ARCHGW_DOCKER_IMAGE", "katanemo/archgw:0.3.22")
SERVICE_NAME_ARCHGW = "plano"
PLANO_DOCKER_NAME = "plano"
PLANO_DOCKER_IMAGE = os.getenv("PLANO_DOCKER_IMAGE", "katanemo/plano:0.4.0")

View file

@ -7,14 +7,14 @@ import sys
import yaml
from cli.utils import convert_legacy_listeners, getLogger
from cli.consts import (
ARCHGW_DOCKER_IMAGE,
ARCHGW_DOCKER_NAME,
PLANO_DOCKER_IMAGE,
PLANO_DOCKER_NAME,
)
import subprocess
from cli.docker_cli import (
docker_container_status,
docker_remove_container,
docker_start_archgw_detached,
docker_start_plano_detached,
docker_stop_container,
health_check_endpoint,
stream_gateway_logs,
@ -39,6 +39,9 @@ def _get_gateway_ports(arch_config_file: str) -> list[int]:
all_ports = [listener.get("port") for listener in listeners]
# unique ports
all_ports = list(set(all_ports))
return all_ports
@ -51,27 +54,26 @@ def start_arch(arch_config_file, env, log_timeout=120, foreground=False):
log_timeout (int): Time in seconds to show logs before checking for healthy state.
"""
log.info(
f"Starting arch gateway, image name: {ARCHGW_DOCKER_NAME}, tag: {ARCHGW_DOCKER_IMAGE}"
f"Starting arch gateway, image name: {PLANO_DOCKER_NAME}, tag: {PLANO_DOCKER_IMAGE}"
)
try:
archgw_container_status = docker_container_status(ARCHGW_DOCKER_NAME)
if archgw_container_status != "not found":
log.info("archgw found in docker, stopping and removing it")
docker_stop_container(ARCHGW_DOCKER_NAME)
docker_remove_container(ARCHGW_DOCKER_NAME)
plano_container_status = docker_container_status(PLANO_DOCKER_NAME)
if plano_container_status != "not found":
log.info("plano found in docker, stopping and removing it")
docker_stop_container(PLANO_DOCKER_NAME)
docker_remove_container(PLANO_DOCKER_NAME)
gateway_ports = _get_gateway_ports(arch_config_file)
return_code, _, archgw_stderr = docker_start_archgw_detached(
return_code, _, plano_stderr = docker_start_plano_detached(
arch_config_file,
os.path.expanduser("~/archgw_logs"),
env,
gateway_ports,
)
if return_code != 0:
log.info("Failed to start arch gateway: " + str(return_code))
log.info("stderr: " + archgw_stderr)
log.info("Failed to start plano gateway: " + str(return_code))
log.info("stderr: " + plano_stderr)
sys.exit(1)
start_time = time.time()
@ -84,12 +86,12 @@ def start_arch(arch_config_file, env, log_timeout=120, foreground=False):
if not health_check_status:
all_listeners_healthy = False
archgw_status = docker_container_status(ARCHGW_DOCKER_NAME)
plano_status = docker_container_status(PLANO_DOCKER_NAME)
current_time = time.time()
elapsed_time = current_time - start_time
if archgw_status == "exited":
log.info("archgw container exited unexpectedly.")
if plano_status == "exited":
log.info("plano container exited unexpectedly.")
stream_gateway_logs(follow=False)
sys.exit(1)
@ -100,14 +102,14 @@ def start_arch(arch_config_file, env, log_timeout=120, foreground=False):
sys.exit(1)
if all_listeners_healthy:
log.info("archgw is running and is healthy!")
log.info("plano is running and is healthy!")
break
else:
health_check_status_str = (
"healthy" if health_check_status else "not healthy"
)
log.info(
f"archgw status: {archgw_status}, health status: {health_check_status_str}"
f"plano status: {plano_status}, health status: {health_check_status_str}"
)
time.sleep(1)
@ -119,7 +121,7 @@ def start_arch(arch_config_file, env, log_timeout=120, foreground=False):
stop_docker_container()
def stop_docker_container(service=ARCHGW_DOCKER_NAME):
def stop_docker_container(service=PLANO_DOCKER_NAME):
"""
Shutdown all Docker Compose services by running `docker-compose down`.

View file

@ -4,8 +4,8 @@ import sys
import requests
from cli.consts import (
ARCHGW_DOCKER_IMAGE,
ARCHGW_DOCKER_NAME,
PLANO_DOCKER_IMAGE,
PLANO_DOCKER_NAME,
)
from cli.utils import getLogger
@ -40,9 +40,8 @@ def docker_remove_container(container: str) -> str:
return result.returncode
def docker_start_archgw_detached(
def docker_start_plano_detached(
arch_config_file: str,
logs_path_abs: str,
env: dict,
gateway_ports: list[int],
) -> str:
@ -70,13 +69,13 @@ def docker_start_archgw_detached(
"run",
"-d",
"--name",
ARCHGW_DOCKER_NAME,
PLANO_DOCKER_NAME,
*port_mappings_args,
*volume_mappings_args,
*env_args,
"--add-host",
"host.docker.internal:host-gateway",
ARCHGW_DOCKER_IMAGE,
PLANO_DOCKER_IMAGE,
]
result = subprocess.run(options, capture_output=True, text=True, check=False)
@ -93,11 +92,11 @@ def health_check_endpoint(endpoint: str) -> bool:
return False
def stream_gateway_logs(follow, service="archgw"):
def stream_gateway_logs(follow, service="plano"):
"""
Stream logs from the arch gateway service.
Stream logs from the plano gateway service.
"""
log.info("Logs from arch gateway service.")
log.info("Logs from plano gateway service.")
options = ["docker", "logs"]
if follow:
@ -116,7 +115,7 @@ def stream_gateway_logs(follow, service="archgw"):
log.info(f"Failed to stream logs: {str(e)}")
def docker_validate_archgw_schema(arch_config_file):
def docker_validate_plano_schema(arch_config_file):
result = subprocess.run(
[
"docker",
@ -126,7 +125,7 @@ def docker_validate_archgw_schema(arch_config_file):
f"{arch_config_file}:/app/arch_config.yaml:ro",
"--entrypoint",
"python",
ARCHGW_DOCKER_IMAGE,
PLANO_DOCKER_IMAGE,
"-m",
"cli.config_generator",
],

View file

@ -7,7 +7,7 @@ import importlib.metadata
import json
from cli import targets
from cli.docker_cli import (
docker_validate_archgw_schema,
docker_validate_plano_schema,
stream_gateway_logs,
docker_container_status,
)
@ -25,43 +25,45 @@ from cli.core import (
start_cli_agent,
)
from cli.consts import (
ARCHGW_DOCKER_IMAGE,
ARCHGW_DOCKER_NAME,
PLANO_DOCKER_IMAGE,
PLANO_DOCKER_NAME,
SERVICE_NAME_ARCHGW,
)
log = getLogger(__name__)
# ref https://patorjk.com/software/taag/#p=display&f=Doom&t=Plano&x=none&v=4&h=4&w=80&we=false
logo = r"""
_ _
/ \ _ __ ___ | |__
/ _ \ | '__|/ __|| '_ \
/ ___ \ | | | (__ | | | |
/_/ \_\|_| \___||_| |_|
______ _
| ___ \ |
| |_/ / | __ _ _ __ ___
| __/| |/ _` | '_ \ / _ \
| | | | (_| | | | | (_) |
\_| |_|\__,_|_| |_|\___/
"""
# Command to build archgw Docker images
# Command to build plano Docker images
ARCHGW_DOCKERFILE = "./arch/Dockerfile"
def get_version():
try:
version = importlib.metadata.version("archgw")
version = importlib.metadata.version("plano")
return version
except importlib.metadata.PackageNotFoundError:
return "version not found"
@click.group(invoke_without_command=True)
@click.option("--version", is_flag=True, help="Show the archgw cli version and exit.")
@click.option("--version", is_flag=True, help="Show the plano cli version and exit.")
@click.pass_context
def main(ctx, version):
if version:
click.echo(f"archgw cli version: {get_version()}")
click.echo(f"plano cli version: {get_version()}")
ctx.exit()
log.info(f"Starting archgw cli version: {get_version()}")
log.info(f"Starting plano cli version: {get_version()}")
if ctx.invoked_subcommand is None:
click.echo("""Arch (The Intelligent Prompt Gateway) CLI""")
@ -76,7 +78,7 @@ def build():
# Check if /arch/Dockerfile exists
if os.path.exists(ARCHGW_DOCKERFILE):
if os.path.exists(ARCHGW_DOCKERFILE):
click.echo("Building archgw image...")
click.echo("Building plano image...")
try:
subprocess.run(
[
@ -85,7 +87,7 @@ def build():
"-f",
ARCHGW_DOCKERFILE,
"-t",
f"{ARCHGW_DOCKER_IMAGE}",
f"{PLANO_DOCKER_IMAGE}",
".",
"--add-host=host.docker.internal:host-gateway",
],
@ -93,7 +95,7 @@ def build():
)
click.echo("archgw image built successfully.")
except subprocess.CalledProcessError as e:
click.echo(f"Error building archgw image: {e}")
click.echo(f"Error building plano image: {e}")
sys.exit(1)
else:
click.echo("Error: Dockerfile not found in /arch")
@ -128,7 +130,7 @@ def up(file, path, foreground):
validation_return_code,
validation_stdout,
validation_stderr,
) = docker_validate_archgw_schema(arch_config_file)
) = docker_validate_plano_schema(arch_config_file)
if validation_return_code != 0:
log.info(f"Error: Validation failed. Exiting")
log.info(f"Validation stdout: {validation_stdout}")
@ -211,7 +213,7 @@ def generate_prompt_targets(file):
@click.command()
@click.option(
"--debug",
help="For detailed debug logs to trace calls from archgw <> api_server, etc",
help="For detailed debug logs to trace calls from plano <> api_server, etc",
is_flag=True,
)
@click.option("--follow", help="Follow the logs", is_flag=True)
@ -259,11 +261,11 @@ def cli_agent(type, file, path, settings):
CLI_AGENT: The type of CLI agent to start (currently only 'claude' is supported)
"""
# Check if archgw docker container is running
archgw_status = docker_container_status(ARCHGW_DOCKER_NAME)
# Check if plano docker container is running
archgw_status = docker_container_status(PLANO_DOCKER_NAME)
if archgw_status != "running":
log.error(f"archgw docker container is not running (status: {archgw_status})")
log.error("Please start archgw using the 'archgw up' command.")
log.error("Please start plano using the 'archgw up' command.")
sys.exit(1)
# Determine arch_config.yaml path

View file

@ -1,7 +1,7 @@
[tool.poetry]
name = "archgw"
version = "0.3.22"
description = "Python-based CLI tool to manage Arch Gateway."
name = "plano"
version = "0.4.0"
description = "Python-based CLI tool to manage Plano."
authors = ["Katanemo Labs, Inc."]
readme = "README.md"
packages = [{ include = "cli" }]
@ -18,7 +18,7 @@ requests = ">=2.31.0,<3.0.0"
pytest = ">=8.4.1,<9.0.0"
[tool.poetry.scripts]
archgw = "cli.main:main"
plano = "cli.main:main"
[build-system]
requires = ["poetry-core>=2.0.0"]

View file

@ -5,7 +5,7 @@ failed_files=()
for file in $(find . -name arch_config.yaml -o -name arch_config_full_reference.yaml); do
echo "Validating ${file}..."
touch $(pwd)/${file}_rendered
if ! docker run --rm -v "$(pwd)/${file}:/app/arch_config.yaml:ro" -v "$(pwd)/${file}_rendered:/app/arch_config_rendered.yaml:rw" --entrypoint /bin/sh katanemo/archgw:0.3.22 -c "python -m cli.config_generator" 2>&1 > /dev/null ; then
if ! docker run --rm -v "$(pwd)/${file}:/app/arch_config.yaml:ro" -v "$(pwd)/${file}_rendered:/app/arch_config_rendered.yaml:rw" --entrypoint /bin/sh katanemo/plano:0.4.0 -c "python -m cli.config_generator" 2>&1 > /dev/null ; then
echo "Validation failed for $file"
failed_files+=("$file")
fi

View file

@ -1 +1 @@
docker build -f arch/Dockerfile . -t katanemo/archgw -t katanemo/archgw:0.3.22
docker build -f arch/Dockerfile . -t katanemo/plano -t katanemo/plano:0.4.0

View file

@ -18,7 +18,7 @@ services:
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- ./arch_config.yaml:/app/arch_config.yaml
- ./config.yaml:/app/arch_config.yaml
jaeger:
build:

View file

@ -19,8 +19,8 @@ start_demo() {
fi
# Step 3: Start Arch
echo "Starting Arch with arch_config.yaml..."
archgw up arch_config.yaml
echo "Starting Arch with config.yaml..."
plano up config.yaml
# Step 4: Start developer services
echo "Starting Network Agent using Docker Compose..."
@ -35,7 +35,7 @@ stop_demo() {
# Step 2: Stop Arch
echo "Stopping Arch..."
archgw down
plano down
}
# Main script logic

View file

@ -10,7 +10,7 @@ services:
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- ./arch_config.yaml:/app/arch_config.yaml
- ./config.yaml:/app/arch_config.yaml
jaeger:
build:

View file

@ -19,8 +19,8 @@ start_demo() {
fi
# Step 3: Start Arch
echo "Starting Arch with arch_config.yaml..."
archgw up arch_config.yaml
echo "Starting Arch with config.yaml..."
plano up config.yaml
# Step 4: Start developer services
echo "Starting Network Agent using Docker Compose..."
@ -35,7 +35,7 @@ stop_demo() {
# Step 2: Stop Arch
echo "Stopping Arch..."
archgw down
plano down
}
# Main script logic

View file

@ -21,4 +21,4 @@ services:
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- ./arch_config.yaml:/app/arch_config.yaml
- ./config.yaml:/app/arch_config.yaml

View file

@ -19,8 +19,8 @@ start_demo() {
fi
# Step 3: Start Arch
echo "Starting Arch with arch_config.yaml..."
archgw up arch_config.yaml
echo "Starting Arch with config.yaml..."
plano up config.yaml
# Step 4: Start Network Agent
echo "Starting HR Agent using Docker Compose..."
@ -35,7 +35,7 @@ stop_demo() {
# Step 2: Stop Arch
echo "Stopping Arch..."
archgw down
plano down
}
# Main script logic

View file

@ -10,7 +10,7 @@ services:
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- ./arch_config.yaml:/app/arch_config.yaml
- ./config.yaml:/app/arch_config.yaml
jaeger:
build:

View file

@ -19,8 +19,8 @@ start_demo() {
fi
# Step 3: Start Arch
echo "Starting Arch with arch_config.yaml..."
archgw up arch_config.yaml
echo "Starting Arch with config.yaml..."
plano up config.yaml
# Step 4: Start developer services
echo "Starting Network Agent using Docker Compose..."
@ -35,7 +35,7 @@ stop_demo() {
# Step 2: Stop Arch
echo "Stopping Arch..."
archgw down
plano down
}
# Main script logic

View file

@ -20,7 +20,7 @@ services:
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- ./arch_config.yaml:/app/arch_config.yaml
- ./config.yaml:/app/arch_config.yaml
otel-collector:
build:

View file

@ -20,7 +20,7 @@ services:
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- ./arch_config.yaml:/app/arch_config.yaml
- ./config.yaml:/app/arch_config.yaml
jaeger:
build:

View file

@ -20,7 +20,7 @@ services:
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- ./arch_config.yaml:/app/arch_config.yaml
- ./config.yaml:/app/arch_config.yaml
otel-collector:
build:

View file

@ -23,7 +23,7 @@ services:
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- ./arch_config.yaml:/app/arch_config.yaml
- ./config.yaml:/app/arch_config.yaml
prometheus:
build:

View file

@ -20,4 +20,4 @@ services:
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- ./arch_config.yaml:/app/arch_config.yaml
- ./config.yaml:/app/arch_config.yaml

View file

@ -73,8 +73,8 @@ start_demo() {
fi
# Step 4: Start Arch
echo "Starting Arch with arch_config.yaml..."
archgw up arch_config.yaml
echo "Starting Arch with config.yaml..."
plano up config.yaml
# Step 5: Start Network Agent with the chosen Docker Compose file
echo "Starting Network Agent with $COMPOSE_FILE..."
@ -93,7 +93,7 @@ stop_demo() {
# Stop Arch
echo "Stopping Arch..."
archgw down
plano down
}
# Main script logic

View file

@ -159,7 +159,7 @@ def convert_prompt_target_to_openai_format(target):
def get_prompt_targets():
try:
with open(os.getenv("ARCH_CONFIG", "arch_config.yaml"), "r") as file:
with open(os.getenv("ARCH_CONFIG", "config.yaml"), "r") as file:
config = yaml.safe_load(file)
available_tools = []
@ -181,7 +181,7 @@ def get_prompt_targets():
def get_llm_models():
try:
with open(os.getenv("ARCH_CONFIG", "arch_config.yaml"), "r") as file:
with open(os.getenv("ARCH_CONFIG", "config.yaml"), "r") as file:
config = yaml.safe_load(file)
available_models = [""]

View file

@ -20,8 +20,8 @@ do
echo "Running tests for $demo ..."
echo "****************************************"
cd ../../$demo
echo "starting archgw"
archgw up arch_config.yaml
echo "starting plano"
plano up config.yaml
echo "starting docker containers"
# only execute docker compose if demo is use_cases/preference_based_routing
if [ "$demo" == "use_cases/preference_based_routing" ]; then
@ -33,12 +33,12 @@ do
echo "starting hurl tests"
if ! hurl hurl_tests/*.hurl; then
echo "Hurl tests failed for $demo"
echo "docker logs for archgw:"
docker logs archgw | tail -n 100
echo "docker logs for plano:"
docker logs plano | tail -n 100
exit 1
fi
echo "stopping docker containers and archgw"
archgw down
echo "stopping docker containers and plano"
plano down
docker compose down -v
cd ../../shared/test_runner
done

View file

@ -1,6 +1,6 @@
### Use Arch for (Model-based) LLM Routing Step 1. Create arch config file
Create `arch_config.yaml` file with following content:
Create `config.yaml` file with following content:
```yaml
version: v0.1.0
@ -28,8 +28,8 @@ Once the config file is created ensure that you have env vars setup for `MISTRAL
Start arch gateway,
```
$ archgw up arch_config.yaml
2024-12-05 11:24:51,288 - cli.main - INFO - Starting archgw cli version: 0.1.5
$ plano up config.yaml
2024-12-05 11:24:51,288 - cli.main - INFO - Starting plano cli version: 0.4.0
2024-12-05 11:24:51,825 - cli.utils - INFO - Schema validation successful!
2024-12-05 11:24:51,825 - cli.main - INFO - Starting arch model server and arch gateway
...

View file

@ -2,7 +2,7 @@ services:
open-web-ui:
image: ghcr.io/open-webui/open-webui:main
image: dyrnq/open-webui:main
restart: always
ports:
- "8080:8080"

View file

@ -19,8 +19,8 @@ start_demo() {
fi
# Step 3: Start Arch
echo "Starting Arch with arch_config.yaml..."
archgw up arch_config.yaml
echo "Starting Arch with config.yaml..."
plano up config.yaml
# Step 4: Start LLM Routing
echo "Starting LLM Routing using Docker Compose..."
@ -35,7 +35,7 @@ stop_demo() {
# Step 2: Stop Arch
echo "Stopping Arch..."
archgw down
plano down
}
# Main script logic

View file

@ -1,6 +1,6 @@
# RAG Agent Demo
A multi-agent RAG system demonstrating archgw's agent filter chain with MCP protocol.
A multi-agent RAG system demonstrating plano's agent filter chain with MCP protocol.
## Architecture
@ -46,9 +46,9 @@ This starts:
- Context Builder MCP server on port 10502
- RAG Agent REST server on port 10505
### 2. Start archgw
### 2. Start plano
```bash
archgw up --foreground
plano up --foreground
```
### 3. Test the system
@ -63,7 +63,7 @@ curl -X POST http://localhost:8001/v1/chat/completions \
## Configuration
The `arch_config.yaml` defines how agents are connected:
The `config.yaml` defines how agents are connected:
```yaml
filters:
@ -82,7 +82,7 @@ filters:
## How It Works
1. User sends request to archgw listener on port 8001
1. User sends request to plano listener on port 8001
2. Request passes through MCP filter chain:
- **Input Guards** validates the query is within TechCorp's domain
- **Query Rewriter** rewrites the query for better retrieval
@ -92,7 +92,7 @@ filters:
## Additional Configuration
See `arch_config.yaml` for the complete filter chain setup. The MCP filters use default settings:
See `config.yaml` for the complete filter chain setup. The MCP filters use default settings:
- `type: mcp` (default)
- `transport: streamable-http` (default)
- Tool name defaults to filter ID
@ -113,10 +113,10 @@ curl -X POST http://localhost:8001/v1/chat/completions \
]
}'
```
- `LLM_GATEWAY_ENDPOINT` - archgw endpoint (default: `http://localhost:12000/v1`)
- `LLM_GATEWAY_ENDPOINT` - lpano endpoint (default: `http://localhost:12000/v1`)
- `OPENAI_API_KEY` - OpenAI API key for model providers
## Additional Resources
- See `sample_queries.md` for more example queries
- See `arch_config.yaml` for complete configuration details
- See `config.yaml` for complete configuration details

View file

@ -11,7 +11,7 @@ services:
environment:
- LLM_GATEWAY_ENDPOINT=${LLM_GATEWAY_ENDPOINT:-http://host.docker.internal:12000/v1}
- OPENAI_API_KEY=${OPENAI_API_KEY:?OPENAI_API_KEY environment variable is required but not set}
archgw:
plano:
build:
context: ../../../
dockerfile: arch/Dockerfile
@ -19,10 +19,10 @@ services:
- "12000:12000"
- "8001:8001"
environment:
- ARCH_CONFIG_PATH=/config/arch_config.yaml
- ARCH_CONFIG_PATH=/config/config.yaml
- OPENAI_API_KEY=${OPENAI_API_KEY:?OPENAI_API_KEY environment variable is required but not set}
volumes:
- ./arch_config.yaml:/app/arch_config.yaml
- ./config.yaml:/app/arch_config.yaml
- /etc/ssl/cert.pem:/etc/ssl/cert.pem
jaeger:
build:

View file

@ -1,6 +1,6 @@
# Model Choice Newsletter Demo
This folder demonstrates a practical workflow for rapid model adoption and safe model switching using Arch Gateway (`archgw`). It includes both a minimal test harness and a sample proxy configuration.
This folder demonstrates a practical workflow for rapid model adoption and safe model switching using Arch Gateway (`plano`). It includes both a minimal test harness and a sample proxy configuration.
---
@ -34,13 +34,13 @@ fixtures:
#### 2. Candidate Models
List the model aliases (e.g., `arch.summarize.v1`, `arch.reason.v1`) you want to test. The harness will route requests through `archgw`, so you dont need provider API keys in your code.
List the model aliases (e.g., `arch.summarize.v1`, `arch.reason.v1`) you want to test. The harness will route requests through `plano`, so you dont need provider API keys in your code.
#### 3. Minimal Python Harness
See `bench.py` for a complete example. It:
- Loads fixtures.
- Sends requests to each candidate model via `archgw`.
- Sends requests to each candidate model via `plano`.
- Validates output against schema and anchor words.
- Reports success rate and latency.
@ -60,7 +60,7 @@ python bench.py
### Part 2 — Network Infrastructure
**Goal:** Use a proxy server (`archgw`) to decouple your app from vendor-specific model names and centralize control.
**Goal:** Use a proxy server (`plano`) to decouple your app from vendor-specific model names and centralize control.
#### Why Use a Proxy?
@ -73,7 +73,7 @@ python bench.py
#### Example Proxy Config
See `arch_config.yaml` for a sample configuration mapping aliases to provider models.
See `config.yaml` for a sample configuration mapping aliases to provider models.
---
@ -108,12 +108,12 @@ See `arch_config.yaml` for a sample configuration mapping aliases to provider mo
- `bench.py` — Minimal Python test harness
- `evals_summarize.yaml` — Example test fixtures
- `pyproject.toml` — Poetry environment file
- `arch_config.yaml` — Sample archgw config (if present)
- `config.yaml` — Sample plano config (if present)
---
## Troubleshooting
- If you see `Success: 0/2 (0%)`, check your anchor words and prompt clarity.
- Make sure archgw is running and accessible at `http://localhost:12000/`.
- Make sure plano is running and accessible at `http://localhost:12000/`.
- For schema validation errors, ensure your prompt instructs the model to output the correct JSON structure.

View file

@ -12,7 +12,7 @@ python = ">=3.10,<3.13.3"
pydantic = "^2.0"
openai = "^1.0"
pyyaml = "^6.0"
archgw ="^0.3.22"
plano = "^0.4.0"
[tool.poetry.group.dev.dependencies]
pytest = "^8.3"

View file

@ -10,7 +10,7 @@ services:
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- ./arch_config.yaml:/app/arch_config.yaml
- ./config.yaml:/app/arch_config.yaml
jaeger:
build:

View file

@ -10,7 +10,7 @@ services:
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- ./arch_config.yaml:/app/arch_config.yaml
- ./config.yaml:/app/arch_config.yaml
otel-collector:
build:

View file

@ -19,8 +19,8 @@ start_demo() {
fi
# Step 3: Start Arch
echo "Starting Arch with arch_config.yaml..."
archgw up arch_config.yaml
echo "Starting Arch with config.yaml..."
plano up config.yaml
# Step 4: Start developer services
echo "Starting Network Agent using Docker Compose..."
@ -35,7 +35,7 @@ stop_demo() {
# Step 2: Stop Arch
echo "Stopping Arch..."
archgw down
plano down
}
# Main script logic

View file

@ -1,9 +1,9 @@
# Usage based LLM Routing
This demo shows how you can use user preferences to route user prompts to appropriate llm. See [arch_config.yaml](arch_config.yaml) for details on how you can define user preferences.
This demo shows how you can use user preferences to route user prompts to appropriate llm. See [config.yaml](config.yaml) for details on how you can define user preferences.
## How to start the demo
Make sure your machine is up to date with [latest version of archgw]([url](https://github.com/katanemo/archgw/tree/main?tab=readme-ov-file#prerequisites)). And you have activated the virtual environment.
Make sure your machine is up to date with [latest version of plano]([url](https://github.com/katanemo/plano/tree/main?tab=readme-ov-file#prerequisites)). And you have activated the virtual environment.
1. start the openwebui
@ -11,15 +11,15 @@ Make sure your machine is up to date with [latest version of archgw]([url](https
(venv) $ cd demos/use_cases/preference_based_routing
(venv) $ docker compose up -d
```
2. start archgw in the foreground
2. start plano in the foreground
```bash
(venv) $ archgw up --service archgw --foreground
2025-05-30 18:00:09,953 - cli.main - INFO - Starting archgw cli version: 0.3.22
2025-05-30 18:00:09,953 - cli.main - INFO - Validating /Users/adilhafeez/src/intelligent-prompt-gateway/demos/use_cases/preference_based_routing/arch_config.yaml
2025-05-30 18:00:10,422 - cli.core - INFO - Starting arch gateway, image name: archgw, tag: katanemo/archgw:0.3.22
2025-05-30 18:00:10,662 - cli.core - INFO - archgw status: running, health status: starting
2025-05-30 18:00:11,712 - cli.core - INFO - archgw status: running, health status: starting
2025-05-30 18:00:12,761 - cli.core - INFO - archgw is running and is healthy!
(venv) $ plano up --service plano --foreground
2025-05-30 18:00:09,953 - cli.main - INFO - Starting plano cli version: 0.4.0
2025-05-30 18:00:09,953 - cli.main - INFO - Validating /Users/adilhafeez/src/intelligent-prompt-gateway/demos/use_cases/preference_based_routing/config.yaml
2025-05-30 18:00:10,422 - cli.core - INFO - Starting arch gateway, image name: plano, tag: katanemo/plano:0.4.0
2025-05-30 18:00:10,662 - cli.core - INFO - plano status: running, health status: starting
2025-05-30 18:00:11,712 - cli.core - INFO - plano status: running, health status: starting
2025-05-30 18:00:12,761 - cli.core - INFO - plano is running and is healthy!
...
```

View file

@ -1,7 +1,7 @@
services:
open-web-ui:
image: ghcr.io/open-webui/open-webui:main
image: dyrnq/open-webui:main
restart: always
ports:
- "8080:8080"

View file

@ -10,7 +10,7 @@ services:
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- ./arch_config.yaml:/app/arch_config.yaml
- ./config.yaml:/app/arch_config.yaml
jaeger:
build:

View file

@ -19,8 +19,8 @@ start_demo() {
fi
# Step 3: Start Arch
echo "Starting Arch with arch_config.yaml..."
archgw up arch_config.yaml
echo "Starting Arch with config.yaml..."
plano up config.yaml
# Step 4: Start developer services
echo "Starting Network Agent using Docker Compose..."
@ -35,7 +35,7 @@ stop_demo() {
# Step 2: Stop Arch
echo "Stopping Arch..."
archgw down
plano down
}
# Main script logic

View file

@ -2,8 +2,9 @@ FROM python:3.11-slim
WORKDIR /app
# Install uv for faster dependency management
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
# Install bash and uv
RUN apt-get update && apt-get install -y bash && rm -rf /var/lib/apt/lists/*
RUN pip install --no-cache-dir uv
# Copy dependency files
COPY pyproject.toml README.md ./

View file

@ -60,7 +60,7 @@ In a new terminal:
```bash
cd /path/to/travel_agents
plano up arch_config.yaml
plano up config.yaml
```
The gateway will start on port 8001 and route requests to the appropriate agents.
@ -159,7 +159,7 @@ Both agents run as Docker containers and communicate with Plano via `host.docker
```
travel_agents/
├── arch_config.yaml # Plano configuration
├── config.yaml # Plano configuration
├── docker-compose.yaml # Docker services orchestration
├── Dockerfile # Multi-agent container image
├── start_agents.sh # Quick start script
@ -173,7 +173,7 @@ travel_agents/
## Configuration Files
### arch_config.yaml
### config.yaml
Defines the two agents, their descriptions, and routing configuration. The agent router uses these descriptions to intelligently route requests.
@ -195,7 +195,7 @@ Orchestrates the deployment of:
**Plano won't start**
- Verify Plano is installed: `plano --version`
- Ensure you're in the travel_agents directory
- Check arch_config.yaml is valid
- Check config.yaml is valid
**No response from agents**
- Verify all containers are running: `docker compose ps`

View file

@ -1,15 +1,18 @@
services:
jaeger:
plano:
build:
context: ../../shared/jaeger
container_name: jaeger
restart: always
context: ../../../
dockerfile: arch/Dockerfile
ports:
- "16686:16686" # Jaeger UI
- "4317:4317" # OTLP gRPC receiver
- "4318:4318" # OTLP HTTP receiver
- "12000:12000"
- "8001:8001"
environment:
- ARCH_CONFIG_PATH=/config/config.yaml
- OPENAI_API_KEY=${OPENAI_API_KEY:?OPENAI_API_KEY environment variable is required but not set}
volumes:
- ./config.yaml:/app/arch_config.yaml
- /etc/ssl/cert.pem:/etc/ssl/cert.pem
weather-agent:
build:
context: .
@ -23,7 +26,6 @@ services:
command: ["uv", "run", "python", "src/travel_agents/weather_agent.py"]
extra_hosts:
- "host.docker.internal:host-gateway"
flight-agent:
build:
context: .
@ -34,11 +36,10 @@ services:
- "10520:10520"
environment:
- LLM_GATEWAY_ENDPOINT=http://host.docker.internal:12000/v1
- AEROAPI_KEY=${AEROAPI_KEY:-ESVFX7TJLxB7OTuayUv0zTQBryA3tOPr}
- AEROAPI_KEY=${AEROAPI_KEY:? AEROAPI_KEY environment variable is required but not set}
command: ["uv", "run", "python", "src/travel_agents/flight_agent.py"]
extra_hosts:
- "host.docker.internal:host-gateway"
open-web-ui:
image: dyrnq/open-webui:main
restart: always
@ -51,3 +52,12 @@ services:
depends_on:
- weather-agent
- flight-agent
jaeger:
build:
context: ../../shared/jaeger
container_name: jaeger
restart: always
ports:
- "16686:16686" # Jaeger UI
- "4317:4317" # OTLP gRPC receiver
- "4318:4318" # OTLP HTTP receiver

View file

@ -28,7 +28,7 @@ EXTRACTION_MODEL = "openai/gpt-4o-mini"
# FlightAware AeroAPI configuration
AEROAPI_BASE_URL = "https://aeroapi.flightaware.com/aeroapi"
AEROAPI_KEY = os.getenv("AEROAPI_KEY", "ESVFX7TJLxB7OTuayUv0zTQBryA3tOPr")
AEROAPI_KEY = os.getenv("AEROAPI_KEY")
# HTTP client for API calls
http_client = httpx.AsyncClient(timeout=30.0)

View file

@ -17,7 +17,7 @@ from sphinxawesome_theme.postprocess import Icons
project = "Plano Docs"
copyright = "2025, Katanemo Labs, Inc"
author = "Katanemo Labs, Inc"
release = " v0.4"
release = " v0.4.0"
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

View file

@ -1,11 +1,11 @@
services:
archgw:
image: katanemo/archgw:latest
plano:
image: katanemo/plano:latest
ports:
- "10000:10000"
- "12000:12000"
volumes:
- ./arch_config.yaml:/app/arch_config.yaml
- ./config.yaml:/app/arch_config.yaml
- /etc/ssl/cert.pem:/etc/ssl/cert.pem
extra_hosts:
- "host.docker.internal:host-gateway"

View file

@ -1,6 +1,6 @@
services:
archgw:
image: katanemo/archgw:latest
plano:
image: katanemo/plano:latest
ports:
- "10000:10000"
- "10001:10001"

View file

@ -6,15 +6,15 @@ set -e
print_disk_usage
mkdir -p ~/archgw_logs
touch ~/archgw_logs/modelserver.log
mkdir -p ~/plano_logs
touch ~/plano_logs/modelserver.log
print_debug() {
log "Received signal to stop"
log "Printing debug logs for docker"
log "===================================="
tail -n 100 ../build.log
archgw logs --debug | tail -n 100
plano logs --debug | tail -n 100
}
trap 'print_debug' INT TERM ERR
@ -27,7 +27,7 @@ cd ../../demos/samples_python/weather_forecast/
docker compose up weather_forecast_service --build -d
cd -
log building and installing archgw cli
log building and installing plano cli
log ==================================
cd ../../arch/tools
poetry install
@ -36,16 +36,16 @@ cd -
log building docker image for arch gateway
log ======================================
cd ../../
archgw build
plano build
cd -
# Once we build archgw we have to install the dependencies again to a new virtual environment.
# Once we build plano we have to install the dependencies again to a new virtual environment.
poetry install
log startup arch gateway with function calling demo
cd ../../
archgw down
archgw up demos/samples_python/weather_forecast/arch_config.yaml
plano down
plano up demos/samples_python/weather_forecast/config.yaml
cd -
log running e2e tests for prompt gateway
@ -54,11 +54,11 @@ poetry run pytest test_prompt_gateway.py
log shutting down the arch gateway service for prompt_gateway demo
log ===============================================================
archgw down
plano down
log startup arch gateway with model alias routing demo
cd ../../
archgw up demos/use_cases/model_alias_routing/arch_config_with_aliases.yaml
plano up demos/use_cases/model_alias_routing/config_with_aliases.yaml
cd -
log running e2e tests for model alias routing
@ -70,8 +70,8 @@ log ========================================
poetry run pytest test_openai_responses_api_client.py
log startup arch gateway with state storage for openai responses api client demo
archgw down
archgw up arch_config_memory_state_v1_responses.yaml
plano down
plano up config_memory_state_v1_responses.yaml
log running e2e tests for openai responses api client
log ========================================