2025-09-29 19:23:08 -07:00
|
|
|
import json
|
2024-10-03 18:21:27 -07:00
|
|
|
import subprocess
|
|
|
|
|
import os
|
2024-10-18 12:09:45 -07:00
|
|
|
import sys
|
2026-02-10 13:17:43 -08:00
|
|
|
import time
|
2025-02-14 19:28:10 -08:00
|
|
|
|
|
|
|
|
import yaml
|
2025-12-25 14:55:29 -08:00
|
|
|
from planoai.utils import convert_legacy_listeners, getLogger
|
|
|
|
|
from planoai.consts import (
|
2025-12-23 18:37:58 -08:00
|
|
|
PLANO_DOCKER_IMAGE,
|
|
|
|
|
PLANO_DOCKER_NAME,
|
2024-10-18 12:09:45 -07:00
|
|
|
)
|
2025-02-14 17:46:58 -08:00
|
|
|
import subprocess
|
2025-12-25 14:55:29 -08:00
|
|
|
from planoai.docker_cli import (
|
2025-02-14 17:46:58 -08:00
|
|
|
docker_container_status,
|
|
|
|
|
docker_remove_container,
|
2025-12-23 18:37:58 -08:00
|
|
|
docker_start_plano_detached,
|
2025-02-14 17:46:58 -08:00
|
|
|
docker_stop_container,
|
|
|
|
|
health_check_endpoint,
|
|
|
|
|
stream_gateway_logs,
|
|
|
|
|
)
|
2024-11-26 13:13:02 -08:00
|
|
|
|
2024-10-10 17:44:41 -07:00
|
|
|
|
|
|
|
|
log = getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
Rename all arch references to plano (#745)
* Rename all arch references to plano across the codebase
Complete rebrand from "Arch"/"archgw" to "Plano" including:
- Config files: arch_config_schema.yaml, workflow, demo configs
- Environment variables: ARCH_CONFIG_* → PLANO_CONFIG_*
- Python CLI: variables, functions, file paths, docker mounts
- Rust crates: config paths, log messages, metadata keys
- Docker/build: Dockerfile, supervisord, .dockerignore, .gitignore
- Docker Compose: volume mounts and env vars across all demos/tests
- GitHub workflows: job/step names
- Shell scripts: log messages
- Demos: Python code, READMEs, VS Code configs, Grafana dashboard
- Docs: RST includes, code comments, config references
- Package metadata: package.json, pyproject.toml, uv.lock
External URLs (docs.archgw.com, github.com/katanemo/archgw) left as-is.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update remaining arch references in docs
- Rename RST cross-reference labels: arch_access_logging, arch_overview_tracing, arch_overview_threading → plano_*
- Update label references in request_lifecycle.rst
- Rename arch_config_state_storage_example.yaml → plano_config_state_storage_example.yaml
- Update config YAML comments: "Arch creates/uses" → "Plano creates/uses"
- Update "the Arch gateway" → "the Plano gateway" in configuration_reference.rst
- Update arch_config_schema.yaml reference in provider_models.py
- Rename arch_agent_router → plano_agent_router in config example
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix remaining arch references found in second pass
- config/docker-compose.dev.yaml: ARCH_CONFIG_FILE → PLANO_CONFIG_FILE,
arch_config.yaml → plano_config.yaml, archgw_logs → plano_logs
- config/test_passthrough.yaml: container mount path
- tests/e2e/docker-compose.yaml: source file path (was still arch_config.yaml)
- cli/planoai/core.py: comment and log message
- crates/brightstaff/src/tracing/constants.rs: doc comment
- tests/{e2e,archgw}/common.py: get_arch_messages → get_plano_messages,
arch_state/arch_messages variables renamed
- tests/{e2e,archgw}/test_prompt_gateway.py: updated imports and usages
- demos/shared/test_runner/{common,test_demos}.py: same renames
- tests/e2e/test_model_alias_routing.py: docstring
- .dockerignore: archgw_modelserver → plano_modelserver
- demos/use_cases/claude_code_router/pretty_model_resolution.sh: container name
Note: x-arch-* HTTP header values and Rust constant names intentionally
preserved for backwards compatibility with existing deployments.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 15:16:56 -08:00
|
|
|
def _get_gateway_ports(plano_config_file: str) -> list[int]:
|
2025-02-14 19:28:10 -08:00
|
|
|
PROMPT_GATEWAY_DEFAULT_PORT = 10000
|
|
|
|
|
LLM_GATEWAY_DEFAULT_PORT = 12000
|
|
|
|
|
|
Rename all arch references to plano (#745)
* Rename all arch references to plano across the codebase
Complete rebrand from "Arch"/"archgw" to "Plano" including:
- Config files: arch_config_schema.yaml, workflow, demo configs
- Environment variables: ARCH_CONFIG_* → PLANO_CONFIG_*
- Python CLI: variables, functions, file paths, docker mounts
- Rust crates: config paths, log messages, metadata keys
- Docker/build: Dockerfile, supervisord, .dockerignore, .gitignore
- Docker Compose: volume mounts and env vars across all demos/tests
- GitHub workflows: job/step names
- Shell scripts: log messages
- Demos: Python code, READMEs, VS Code configs, Grafana dashboard
- Docs: RST includes, code comments, config references
- Package metadata: package.json, pyproject.toml, uv.lock
External URLs (docs.archgw.com, github.com/katanemo/archgw) left as-is.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update remaining arch references in docs
- Rename RST cross-reference labels: arch_access_logging, arch_overview_tracing, arch_overview_threading → plano_*
- Update label references in request_lifecycle.rst
- Rename arch_config_state_storage_example.yaml → plano_config_state_storage_example.yaml
- Update config YAML comments: "Arch creates/uses" → "Plano creates/uses"
- Update "the Arch gateway" → "the Plano gateway" in configuration_reference.rst
- Update arch_config_schema.yaml reference in provider_models.py
- Rename arch_agent_router → plano_agent_router in config example
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix remaining arch references found in second pass
- config/docker-compose.dev.yaml: ARCH_CONFIG_FILE → PLANO_CONFIG_FILE,
arch_config.yaml → plano_config.yaml, archgw_logs → plano_logs
- config/test_passthrough.yaml: container mount path
- tests/e2e/docker-compose.yaml: source file path (was still arch_config.yaml)
- cli/planoai/core.py: comment and log message
- crates/brightstaff/src/tracing/constants.rs: doc comment
- tests/{e2e,archgw}/common.py: get_arch_messages → get_plano_messages,
arch_state/arch_messages variables renamed
- tests/{e2e,archgw}/test_prompt_gateway.py: updated imports and usages
- demos/shared/test_runner/{common,test_demos}.py: same renames
- tests/e2e/test_model_alias_routing.py: docstring
- .dockerignore: archgw_modelserver → plano_modelserver
- demos/use_cases/claude_code_router/pretty_model_resolution.sh: container name
Note: x-arch-* HTTP header values and Rust constant names intentionally
preserved for backwards compatibility with existing deployments.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 15:16:56 -08:00
|
|
|
# parse plano_config_file yaml file and get prompt_gateway_port
|
|
|
|
|
plano_config_dict = {}
|
|
|
|
|
with open(plano_config_file) as f:
|
|
|
|
|
plano_config_dict = yaml.safe_load(f)
|
2025-02-14 19:28:10 -08:00
|
|
|
|
2025-10-14 14:01:11 -07:00
|
|
|
listeners, _, _ = convert_legacy_listeners(
|
Rename all arch references to plano (#745)
* Rename all arch references to plano across the codebase
Complete rebrand from "Arch"/"archgw" to "Plano" including:
- Config files: arch_config_schema.yaml, workflow, demo configs
- Environment variables: ARCH_CONFIG_* → PLANO_CONFIG_*
- Python CLI: variables, functions, file paths, docker mounts
- Rust crates: config paths, log messages, metadata keys
- Docker/build: Dockerfile, supervisord, .dockerignore, .gitignore
- Docker Compose: volume mounts and env vars across all demos/tests
- GitHub workflows: job/step names
- Shell scripts: log messages
- Demos: Python code, READMEs, VS Code configs, Grafana dashboard
- Docs: RST includes, code comments, config references
- Package metadata: package.json, pyproject.toml, uv.lock
External URLs (docs.archgw.com, github.com/katanemo/archgw) left as-is.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update remaining arch references in docs
- Rename RST cross-reference labels: arch_access_logging, arch_overview_tracing, arch_overview_threading → plano_*
- Update label references in request_lifecycle.rst
- Rename arch_config_state_storage_example.yaml → plano_config_state_storage_example.yaml
- Update config YAML comments: "Arch creates/uses" → "Plano creates/uses"
- Update "the Arch gateway" → "the Plano gateway" in configuration_reference.rst
- Update arch_config_schema.yaml reference in provider_models.py
- Rename arch_agent_router → plano_agent_router in config example
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix remaining arch references found in second pass
- config/docker-compose.dev.yaml: ARCH_CONFIG_FILE → PLANO_CONFIG_FILE,
arch_config.yaml → plano_config.yaml, archgw_logs → plano_logs
- config/test_passthrough.yaml: container mount path
- tests/e2e/docker-compose.yaml: source file path (was still arch_config.yaml)
- cli/planoai/core.py: comment and log message
- crates/brightstaff/src/tracing/constants.rs: doc comment
- tests/{e2e,archgw}/common.py: get_arch_messages → get_plano_messages,
arch_state/arch_messages variables renamed
- tests/{e2e,archgw}/test_prompt_gateway.py: updated imports and usages
- demos/shared/test_runner/{common,test_demos}.py: same renames
- tests/e2e/test_model_alias_routing.py: docstring
- .dockerignore: archgw_modelserver → plano_modelserver
- demos/use_cases/claude_code_router/pretty_model_resolution.sh: container name
Note: x-arch-* HTTP header values and Rust constant names intentionally
preserved for backwards compatibility with existing deployments.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 15:16:56 -08:00
|
|
|
plano_config_dict.get("listeners"), plano_config_dict.get("llm_providers")
|
2025-02-14 19:28:10 -08:00
|
|
|
)
|
|
|
|
|
|
2025-10-14 14:01:11 -07:00
|
|
|
all_ports = [listener.get("port") for listener in listeners]
|
|
|
|
|
|
2025-12-23 18:37:58 -08:00
|
|
|
# unique ports
|
|
|
|
|
all_ports = list(set(all_ports))
|
|
|
|
|
|
2025-10-14 14:01:11 -07:00
|
|
|
return all_ports
|
2025-02-14 19:28:10 -08:00
|
|
|
|
|
|
|
|
|
Rename all arch references to plano (#745)
* Rename all arch references to plano across the codebase
Complete rebrand from "Arch"/"archgw" to "Plano" including:
- Config files: arch_config_schema.yaml, workflow, demo configs
- Environment variables: ARCH_CONFIG_* → PLANO_CONFIG_*
- Python CLI: variables, functions, file paths, docker mounts
- Rust crates: config paths, log messages, metadata keys
- Docker/build: Dockerfile, supervisord, .dockerignore, .gitignore
- Docker Compose: volume mounts and env vars across all demos/tests
- GitHub workflows: job/step names
- Shell scripts: log messages
- Demos: Python code, READMEs, VS Code configs, Grafana dashboard
- Docs: RST includes, code comments, config references
- Package metadata: package.json, pyproject.toml, uv.lock
External URLs (docs.archgw.com, github.com/katanemo/archgw) left as-is.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update remaining arch references in docs
- Rename RST cross-reference labels: arch_access_logging, arch_overview_tracing, arch_overview_threading → plano_*
- Update label references in request_lifecycle.rst
- Rename arch_config_state_storage_example.yaml → plano_config_state_storage_example.yaml
- Update config YAML comments: "Arch creates/uses" → "Plano creates/uses"
- Update "the Arch gateway" → "the Plano gateway" in configuration_reference.rst
- Update arch_config_schema.yaml reference in provider_models.py
- Rename arch_agent_router → plano_agent_router in config example
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix remaining arch references found in second pass
- config/docker-compose.dev.yaml: ARCH_CONFIG_FILE → PLANO_CONFIG_FILE,
arch_config.yaml → plano_config.yaml, archgw_logs → plano_logs
- config/test_passthrough.yaml: container mount path
- tests/e2e/docker-compose.yaml: source file path (was still arch_config.yaml)
- cli/planoai/core.py: comment and log message
- crates/brightstaff/src/tracing/constants.rs: doc comment
- tests/{e2e,archgw}/common.py: get_arch_messages → get_plano_messages,
arch_state/arch_messages variables renamed
- tests/{e2e,archgw}/test_prompt_gateway.py: updated imports and usages
- demos/shared/test_runner/{common,test_demos}.py: same renames
- tests/e2e/test_model_alias_routing.py: docstring
- .dockerignore: archgw_modelserver → plano_modelserver
- demos/use_cases/claude_code_router/pretty_model_resolution.sh: container name
Note: x-arch-* HTTP header values and Rust constant names intentionally
preserved for backwards compatibility with existing deployments.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 15:16:56 -08:00
|
|
|
def start_plano(plano_config_file, env, log_timeout=120, foreground=False):
|
2024-10-03 18:21:27 -07:00
|
|
|
"""
|
|
|
|
|
Start Docker Compose in detached mode and stream logs until services are healthy.
|
|
|
|
|
|
|
|
|
|
Args:
|
2024-11-26 13:13:02 -08:00
|
|
|
path (str): The path where the prompt_config.yml file is located.
|
2024-10-03 18:21:27 -07:00
|
|
|
log_timeout (int): Time in seconds to show logs before checking for healthy state.
|
|
|
|
|
"""
|
2025-05-19 09:59:22 -07:00
|
|
|
log.info(
|
Rename all arch references to plano (#745)
* Rename all arch references to plano across the codebase
Complete rebrand from "Arch"/"archgw" to "Plano" including:
- Config files: arch_config_schema.yaml, workflow, demo configs
- Environment variables: ARCH_CONFIG_* → PLANO_CONFIG_*
- Python CLI: variables, functions, file paths, docker mounts
- Rust crates: config paths, log messages, metadata keys
- Docker/build: Dockerfile, supervisord, .dockerignore, .gitignore
- Docker Compose: volume mounts and env vars across all demos/tests
- GitHub workflows: job/step names
- Shell scripts: log messages
- Demos: Python code, READMEs, VS Code configs, Grafana dashboard
- Docs: RST includes, code comments, config references
- Package metadata: package.json, pyproject.toml, uv.lock
External URLs (docs.archgw.com, github.com/katanemo/archgw) left as-is.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update remaining arch references in docs
- Rename RST cross-reference labels: arch_access_logging, arch_overview_tracing, arch_overview_threading → plano_*
- Update label references in request_lifecycle.rst
- Rename arch_config_state_storage_example.yaml → plano_config_state_storage_example.yaml
- Update config YAML comments: "Arch creates/uses" → "Plano creates/uses"
- Update "the Arch gateway" → "the Plano gateway" in configuration_reference.rst
- Update arch_config_schema.yaml reference in provider_models.py
- Rename arch_agent_router → plano_agent_router in config example
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix remaining arch references found in second pass
- config/docker-compose.dev.yaml: ARCH_CONFIG_FILE → PLANO_CONFIG_FILE,
arch_config.yaml → plano_config.yaml, archgw_logs → plano_logs
- config/test_passthrough.yaml: container mount path
- tests/e2e/docker-compose.yaml: source file path (was still arch_config.yaml)
- cli/planoai/core.py: comment and log message
- crates/brightstaff/src/tracing/constants.rs: doc comment
- tests/{e2e,archgw}/common.py: get_arch_messages → get_plano_messages,
arch_state/arch_messages variables renamed
- tests/{e2e,archgw}/test_prompt_gateway.py: updated imports and usages
- demos/shared/test_runner/{common,test_demos}.py: same renames
- tests/e2e/test_model_alias_routing.py: docstring
- .dockerignore: archgw_modelserver → plano_modelserver
- demos/use_cases/claude_code_router/pretty_model_resolution.sh: container name
Note: x-arch-* HTTP header values and Rust constant names intentionally
preserved for backwards compatibility with existing deployments.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 15:16:56 -08:00
|
|
|
f"Starting plano gateway, image name: {PLANO_DOCKER_NAME}, tag: {PLANO_DOCKER_IMAGE}"
|
2025-05-19 09:59:22 -07:00
|
|
|
)
|
2024-10-03 18:21:27 -07:00
|
|
|
|
|
|
|
|
try:
|
2025-12-23 18:37:58 -08:00
|
|
|
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)
|
2025-02-14 17:46:58 -08:00
|
|
|
|
Rename all arch references to plano (#745)
* Rename all arch references to plano across the codebase
Complete rebrand from "Arch"/"archgw" to "Plano" including:
- Config files: arch_config_schema.yaml, workflow, demo configs
- Environment variables: ARCH_CONFIG_* → PLANO_CONFIG_*
- Python CLI: variables, functions, file paths, docker mounts
- Rust crates: config paths, log messages, metadata keys
- Docker/build: Dockerfile, supervisord, .dockerignore, .gitignore
- Docker Compose: volume mounts and env vars across all demos/tests
- GitHub workflows: job/step names
- Shell scripts: log messages
- Demos: Python code, READMEs, VS Code configs, Grafana dashboard
- Docs: RST includes, code comments, config references
- Package metadata: package.json, pyproject.toml, uv.lock
External URLs (docs.archgw.com, github.com/katanemo/archgw) left as-is.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update remaining arch references in docs
- Rename RST cross-reference labels: arch_access_logging, arch_overview_tracing, arch_overview_threading → plano_*
- Update label references in request_lifecycle.rst
- Rename arch_config_state_storage_example.yaml → plano_config_state_storage_example.yaml
- Update config YAML comments: "Arch creates/uses" → "Plano creates/uses"
- Update "the Arch gateway" → "the Plano gateway" in configuration_reference.rst
- Update arch_config_schema.yaml reference in provider_models.py
- Rename arch_agent_router → plano_agent_router in config example
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix remaining arch references found in second pass
- config/docker-compose.dev.yaml: ARCH_CONFIG_FILE → PLANO_CONFIG_FILE,
arch_config.yaml → plano_config.yaml, archgw_logs → plano_logs
- config/test_passthrough.yaml: container mount path
- tests/e2e/docker-compose.yaml: source file path (was still arch_config.yaml)
- cli/planoai/core.py: comment and log message
- crates/brightstaff/src/tracing/constants.rs: doc comment
- tests/{e2e,archgw}/common.py: get_arch_messages → get_plano_messages,
arch_state/arch_messages variables renamed
- tests/{e2e,archgw}/test_prompt_gateway.py: updated imports and usages
- demos/shared/test_runner/{common,test_demos}.py: same renames
- tests/e2e/test_model_alias_routing.py: docstring
- .dockerignore: archgw_modelserver → plano_modelserver
- demos/use_cases/claude_code_router/pretty_model_resolution.sh: container name
Note: x-arch-* HTTP header values and Rust constant names intentionally
preserved for backwards compatibility with existing deployments.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 15:16:56 -08:00
|
|
|
gateway_ports = _get_gateway_ports(plano_config_file)
|
2025-02-14 19:28:10 -08:00
|
|
|
|
2025-12-23 18:37:58 -08:00
|
|
|
return_code, _, plano_stderr = docker_start_plano_detached(
|
Rename all arch references to plano (#745)
* Rename all arch references to plano across the codebase
Complete rebrand from "Arch"/"archgw" to "Plano" including:
- Config files: arch_config_schema.yaml, workflow, demo configs
- Environment variables: ARCH_CONFIG_* → PLANO_CONFIG_*
- Python CLI: variables, functions, file paths, docker mounts
- Rust crates: config paths, log messages, metadata keys
- Docker/build: Dockerfile, supervisord, .dockerignore, .gitignore
- Docker Compose: volume mounts and env vars across all demos/tests
- GitHub workflows: job/step names
- Shell scripts: log messages
- Demos: Python code, READMEs, VS Code configs, Grafana dashboard
- Docs: RST includes, code comments, config references
- Package metadata: package.json, pyproject.toml, uv.lock
External URLs (docs.archgw.com, github.com/katanemo/archgw) left as-is.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update remaining arch references in docs
- Rename RST cross-reference labels: arch_access_logging, arch_overview_tracing, arch_overview_threading → plano_*
- Update label references in request_lifecycle.rst
- Rename arch_config_state_storage_example.yaml → plano_config_state_storage_example.yaml
- Update config YAML comments: "Arch creates/uses" → "Plano creates/uses"
- Update "the Arch gateway" → "the Plano gateway" in configuration_reference.rst
- Update arch_config_schema.yaml reference in provider_models.py
- Rename arch_agent_router → plano_agent_router in config example
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix remaining arch references found in second pass
- config/docker-compose.dev.yaml: ARCH_CONFIG_FILE → PLANO_CONFIG_FILE,
arch_config.yaml → plano_config.yaml, archgw_logs → plano_logs
- config/test_passthrough.yaml: container mount path
- tests/e2e/docker-compose.yaml: source file path (was still arch_config.yaml)
- cli/planoai/core.py: comment and log message
- crates/brightstaff/src/tracing/constants.rs: doc comment
- tests/{e2e,archgw}/common.py: get_arch_messages → get_plano_messages,
arch_state/arch_messages variables renamed
- tests/{e2e,archgw}/test_prompt_gateway.py: updated imports and usages
- demos/shared/test_runner/{common,test_demos}.py: same renames
- tests/e2e/test_model_alias_routing.py: docstring
- .dockerignore: archgw_modelserver → plano_modelserver
- demos/use_cases/claude_code_router/pretty_model_resolution.sh: container name
Note: x-arch-* HTTP header values and Rust constant names intentionally
preserved for backwards compatibility with existing deployments.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 15:16:56 -08:00
|
|
|
plano_config_file,
|
2025-02-14 19:28:10 -08:00
|
|
|
env,
|
2025-10-14 14:01:11 -07:00
|
|
|
gateway_ports,
|
2025-02-14 17:46:58 -08:00
|
|
|
)
|
|
|
|
|
if return_code != 0:
|
2025-12-23 18:37:58 -08:00
|
|
|
log.info("Failed to start plano gateway: " + str(return_code))
|
|
|
|
|
log.info("stderr: " + plano_stderr)
|
2025-02-14 17:46:58 -08:00
|
|
|
sys.exit(1)
|
2024-10-03 18:21:27 -07:00
|
|
|
|
|
|
|
|
start_time = time.time()
|
|
|
|
|
while True:
|
2025-10-14 14:01:11 -07:00
|
|
|
all_listeners_healthy = True
|
|
|
|
|
for port in gateway_ports:
|
|
|
|
|
health_check_status = health_check_endpoint(
|
|
|
|
|
f"http://localhost:{port}/healthz"
|
|
|
|
|
)
|
2025-10-22 14:13:16 -07:00
|
|
|
if not health_check_status:
|
2025-10-14 14:01:11 -07:00
|
|
|
all_listeners_healthy = False
|
2025-03-03 13:11:57 -08:00
|
|
|
|
2025-12-23 18:37:58 -08:00
|
|
|
plano_status = docker_container_status(PLANO_DOCKER_NAME)
|
2024-10-03 18:21:27 -07:00
|
|
|
current_time = time.time()
|
|
|
|
|
elapsed_time = current_time - start_time
|
|
|
|
|
|
2025-12-23 18:37:58 -08:00
|
|
|
if plano_status == "exited":
|
|
|
|
|
log.info("plano container exited unexpectedly.")
|
2025-05-19 09:59:22 -07:00
|
|
|
stream_gateway_logs(follow=False)
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
2024-10-03 18:21:27 -07:00
|
|
|
# Check if timeout is reached
|
|
|
|
|
if elapsed_time > log_timeout:
|
2025-02-14 17:46:58 -08:00
|
|
|
log.info(f"stopping log monitoring after {log_timeout} seconds.")
|
2025-05-22 22:55:46 -07:00
|
|
|
stream_gateway_logs(follow=False)
|
2025-05-19 09:59:22 -07:00
|
|
|
sys.exit(1)
|
2024-10-03 18:21:27 -07:00
|
|
|
|
2025-10-14 14:01:11 -07:00
|
|
|
if all_listeners_healthy:
|
2025-12-23 18:37:58 -08:00
|
|
|
log.info("plano is running and is healthy!")
|
2024-10-03 18:21:27 -07:00
|
|
|
break
|
2024-11-26 13:13:02 -08:00
|
|
|
else:
|
2025-10-22 14:13:16 -07:00
|
|
|
health_check_status_str = (
|
|
|
|
|
"healthy" if health_check_status else "not healthy"
|
|
|
|
|
)
|
|
|
|
|
log.info(
|
2025-12-23 18:37:58 -08:00
|
|
|
f"plano status: {plano_status}, health status: {health_check_status_str}"
|
2025-10-22 14:13:16 -07:00
|
|
|
)
|
2024-11-26 13:13:02 -08:00
|
|
|
time.sleep(1)
|
2024-10-03 18:21:27 -07:00
|
|
|
|
2024-12-20 13:25:01 -08:00
|
|
|
if foreground:
|
2025-02-14 17:46:58 -08:00
|
|
|
stream_gateway_logs(follow=True)
|
2024-12-20 13:25:01 -08:00
|
|
|
|
|
|
|
|
except KeyboardInterrupt:
|
Rename all arch references to plano (#745)
* Rename all arch references to plano across the codebase
Complete rebrand from "Arch"/"archgw" to "Plano" including:
- Config files: arch_config_schema.yaml, workflow, demo configs
- Environment variables: ARCH_CONFIG_* → PLANO_CONFIG_*
- Python CLI: variables, functions, file paths, docker mounts
- Rust crates: config paths, log messages, metadata keys
- Docker/build: Dockerfile, supervisord, .dockerignore, .gitignore
- Docker Compose: volume mounts and env vars across all demos/tests
- GitHub workflows: job/step names
- Shell scripts: log messages
- Demos: Python code, READMEs, VS Code configs, Grafana dashboard
- Docs: RST includes, code comments, config references
- Package metadata: package.json, pyproject.toml, uv.lock
External URLs (docs.archgw.com, github.com/katanemo/archgw) left as-is.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update remaining arch references in docs
- Rename RST cross-reference labels: arch_access_logging, arch_overview_tracing, arch_overview_threading → plano_*
- Update label references in request_lifecycle.rst
- Rename arch_config_state_storage_example.yaml → plano_config_state_storage_example.yaml
- Update config YAML comments: "Arch creates/uses" → "Plano creates/uses"
- Update "the Arch gateway" → "the Plano gateway" in configuration_reference.rst
- Update arch_config_schema.yaml reference in provider_models.py
- Rename arch_agent_router → plano_agent_router in config example
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix remaining arch references found in second pass
- config/docker-compose.dev.yaml: ARCH_CONFIG_FILE → PLANO_CONFIG_FILE,
arch_config.yaml → plano_config.yaml, archgw_logs → plano_logs
- config/test_passthrough.yaml: container mount path
- tests/e2e/docker-compose.yaml: source file path (was still arch_config.yaml)
- cli/planoai/core.py: comment and log message
- crates/brightstaff/src/tracing/constants.rs: doc comment
- tests/{e2e,archgw}/common.py: get_arch_messages → get_plano_messages,
arch_state/arch_messages variables renamed
- tests/{e2e,archgw}/test_prompt_gateway.py: updated imports and usages
- demos/shared/test_runner/{common,test_demos}.py: same renames
- tests/e2e/test_model_alias_routing.py: docstring
- .dockerignore: archgw_modelserver → plano_modelserver
- demos/use_cases/claude_code_router/pretty_model_resolution.sh: container name
Note: x-arch-* HTTP header values and Rust constant names intentionally
preserved for backwards compatibility with existing deployments.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 15:16:56 -08:00
|
|
|
log.info("Keyboard interrupt received, stopping plano gateway service.")
|
2025-05-19 09:59:22 -07:00
|
|
|
stop_docker_container()
|
2024-10-03 18:21:27 -07:00
|
|
|
|
|
|
|
|
|
2025-12-23 18:37:58 -08:00
|
|
|
def stop_docker_container(service=PLANO_DOCKER_NAME):
|
2024-10-03 18:21:27 -07:00
|
|
|
"""
|
|
|
|
|
Shutdown all Docker Compose services by running `docker-compose down`.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
path (str): The path where the docker-compose.yml file is located.
|
|
|
|
|
"""
|
2025-05-19 09:59:22 -07:00
|
|
|
log.info(f"Shutting down {service} service.")
|
2024-10-10 17:44:41 -07:00
|
|
|
|
2024-10-03 18:21:27 -07:00
|
|
|
try:
|
|
|
|
|
subprocess.run(
|
2025-05-19 09:59:22 -07:00
|
|
|
["docker", "stop", service],
|
2024-10-03 18:21:27 -07:00
|
|
|
)
|
2024-11-26 13:13:02 -08:00
|
|
|
subprocess.run(
|
2025-05-19 09:59:22 -07:00
|
|
|
["docker", "rm", service],
|
2024-11-26 13:13:02 -08:00
|
|
|
)
|
|
|
|
|
|
2025-05-19 09:59:22 -07:00
|
|
|
log.info(f"Successfully shut down {service} service.")
|
2024-10-03 18:21:27 -07:00
|
|
|
|
|
|
|
|
except subprocess.CalledProcessError as e:
|
2024-10-10 17:44:41 -07:00
|
|
|
log.info(f"Failed to shut down services: {str(e)}")
|
2024-10-06 18:21:43 -07:00
|
|
|
|
2024-10-09 11:25:07 -07:00
|
|
|
|
2026-02-25 10:16:32 -08:00
|
|
|
def start_cli_agent(plano_config_file=None, settings_json="{}", agent_type="claude"):
|
2026-01-28 17:47:33 -08:00
|
|
|
"""Start a CLI client connected to Plano."""
|
2025-09-29 19:23:08 -07:00
|
|
|
|
Rename all arch references to plano (#745)
* Rename all arch references to plano across the codebase
Complete rebrand from "Arch"/"archgw" to "Plano" including:
- Config files: arch_config_schema.yaml, workflow, demo configs
- Environment variables: ARCH_CONFIG_* → PLANO_CONFIG_*
- Python CLI: variables, functions, file paths, docker mounts
- Rust crates: config paths, log messages, metadata keys
- Docker/build: Dockerfile, supervisord, .dockerignore, .gitignore
- Docker Compose: volume mounts and env vars across all demos/tests
- GitHub workflows: job/step names
- Shell scripts: log messages
- Demos: Python code, READMEs, VS Code configs, Grafana dashboard
- Docs: RST includes, code comments, config references
- Package metadata: package.json, pyproject.toml, uv.lock
External URLs (docs.archgw.com, github.com/katanemo/archgw) left as-is.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update remaining arch references in docs
- Rename RST cross-reference labels: arch_access_logging, arch_overview_tracing, arch_overview_threading → plano_*
- Update label references in request_lifecycle.rst
- Rename arch_config_state_storage_example.yaml → plano_config_state_storage_example.yaml
- Update config YAML comments: "Arch creates/uses" → "Plano creates/uses"
- Update "the Arch gateway" → "the Plano gateway" in configuration_reference.rst
- Update arch_config_schema.yaml reference in provider_models.py
- Rename arch_agent_router → plano_agent_router in config example
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix remaining arch references found in second pass
- config/docker-compose.dev.yaml: ARCH_CONFIG_FILE → PLANO_CONFIG_FILE,
arch_config.yaml → plano_config.yaml, archgw_logs → plano_logs
- config/test_passthrough.yaml: container mount path
- tests/e2e/docker-compose.yaml: source file path (was still arch_config.yaml)
- cli/planoai/core.py: comment and log message
- crates/brightstaff/src/tracing/constants.rs: doc comment
- tests/{e2e,archgw}/common.py: get_arch_messages → get_plano_messages,
arch_state/arch_messages variables renamed
- tests/{e2e,archgw}/test_prompt_gateway.py: updated imports and usages
- demos/shared/test_runner/{common,test_demos}.py: same renames
- tests/e2e/test_model_alias_routing.py: docstring
- .dockerignore: archgw_modelserver → plano_modelserver
- demos/use_cases/claude_code_router/pretty_model_resolution.sh: container name
Note: x-arch-* HTTP header values and Rust constant names intentionally
preserved for backwards compatibility with existing deployments.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 15:16:56 -08:00
|
|
|
with open(plano_config_file, "r") as file:
|
|
|
|
|
plano_config = file.read()
|
|
|
|
|
plano_config_yaml = yaml.safe_load(plano_config)
|
2025-09-29 19:23:08 -07:00
|
|
|
|
2026-02-25 10:16:32 -08:00
|
|
|
# Get egress listener configuration (supports both legacy dict and list formats)
|
|
|
|
|
host = "127.0.0.1"
|
|
|
|
|
port = 12000
|
|
|
|
|
listeners = plano_config_yaml.get("listeners")
|
|
|
|
|
if isinstance(listeners, dict):
|
|
|
|
|
egress_config = listeners.get("egress_traffic", {})
|
|
|
|
|
host = egress_config.get("host", host)
|
|
|
|
|
port = egress_config.get("port", port)
|
|
|
|
|
elif isinstance(listeners, list):
|
|
|
|
|
model_listener = next(
|
|
|
|
|
(
|
|
|
|
|
listener
|
|
|
|
|
for listener in listeners
|
|
|
|
|
if listener.get("type") in ("model", "model_listener")
|
|
|
|
|
),
|
|
|
|
|
{},
|
|
|
|
|
)
|
|
|
|
|
host = model_listener.get("host", host)
|
|
|
|
|
port = model_listener.get("port", port)
|
2025-09-29 19:23:08 -07:00
|
|
|
|
|
|
|
|
# Parse additional settings from command line
|
|
|
|
|
try:
|
|
|
|
|
additional_settings = json.loads(settings_json) if settings_json else {}
|
|
|
|
|
except json.JSONDecodeError:
|
|
|
|
|
log.error("Settings must be valid JSON")
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
# Set up environment variables
|
|
|
|
|
env = os.environ.copy()
|
|
|
|
|
env.update(
|
|
|
|
|
{
|
|
|
|
|
"NO_PROXY": host,
|
|
|
|
|
"DISABLE_TELEMETRY": "true",
|
|
|
|
|
"API_TIMEOUT_MS": "600000",
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
2026-02-25 10:16:32 -08:00
|
|
|
model_aliases = plano_config_yaml.get("model_aliases", {})
|
|
|
|
|
command_path = None
|
|
|
|
|
command_args = []
|
|
|
|
|
handled_settings = {"NON_INTERACTIVE_MODE"}
|
|
|
|
|
|
|
|
|
|
if agent_type == "claude":
|
|
|
|
|
env.update(
|
|
|
|
|
{
|
|
|
|
|
"ANTHROPIC_AUTH_TOKEN": "test", # Use test token for plano
|
|
|
|
|
"ANTHROPIC_API_KEY": "",
|
|
|
|
|
"ANTHROPIC_BASE_URL": f"http://{host}:{port}",
|
|
|
|
|
"DISABLE_COST_WARNINGS": "true",
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
command_path = "claude"
|
|
|
|
|
|
|
|
|
|
# Set ANTHROPIC_SMALL_FAST_MODEL from additional_settings or model alias
|
|
|
|
|
if "ANTHROPIC_SMALL_FAST_MODEL" in additional_settings:
|
|
|
|
|
env["ANTHROPIC_SMALL_FAST_MODEL"] = additional_settings[
|
|
|
|
|
"ANTHROPIC_SMALL_FAST_MODEL"
|
|
|
|
|
]
|
|
|
|
|
elif "arch.claude.code.small.fast" in model_aliases:
|
2025-09-29 19:23:08 -07:00
|
|
|
env["ANTHROPIC_SMALL_FAST_MODEL"] = "arch.claude.code.small.fast"
|
|
|
|
|
else:
|
|
|
|
|
log.info(
|
|
|
|
|
"Tip: Set an alias 'arch.claude.code.small.fast' in your model_aliases config to set a small fast model Claude Code"
|
|
|
|
|
)
|
|
|
|
|
log.info("Or provide ANTHROPIC_SMALL_FAST_MODEL in --settings JSON")
|
|
|
|
|
|
2026-02-25 10:16:32 -08:00
|
|
|
handled_settings.add("ANTHROPIC_SMALL_FAST_MODEL")
|
|
|
|
|
|
|
|
|
|
elif agent_type == "codex":
|
|
|
|
|
env.update(
|
|
|
|
|
{
|
|
|
|
|
# Codex uses OpenAI-compatible auth/base URL when routing through Plano.
|
|
|
|
|
"OPENAI_API_KEY": env.get("OPENAI_API_KEY", "test"),
|
|
|
|
|
"OPENAI_BASE_URL": f"http://{host}:{port}/v1",
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
command_path = "codex"
|
|
|
|
|
|
|
|
|
|
codex_model = additional_settings.get("CODEX_MODEL")
|
|
|
|
|
if codex_model is None and "arch.codex.default" in model_aliases:
|
|
|
|
|
# Codex expects known model metadata. Resolve alias to concrete target by default
|
|
|
|
|
# to avoid metadata fallback warnings for custom alias names.
|
|
|
|
|
codex_model = model_aliases["arch.codex.default"].get(
|
|
|
|
|
"target", "arch.codex.default"
|
|
|
|
|
)
|
|
|
|
|
if codex_model:
|
|
|
|
|
command_args.extend(["-m", codex_model])
|
|
|
|
|
|
|
|
|
|
handled_settings.add("CODEX_MODEL")
|
|
|
|
|
elif agent_type == "opencode":
|
|
|
|
|
env.update(
|
|
|
|
|
{
|
|
|
|
|
# OpenCode uses OpenAI-compatible auth/base URL when routing through Plano.
|
|
|
|
|
"OPENAI_API_KEY": env.get("OPENAI_API_KEY", "test"),
|
|
|
|
|
"OPENAI_BASE_URL": f"http://{host}:{port}/v1",
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
command_path = "opencode"
|
|
|
|
|
|
|
|
|
|
opencode_model = additional_settings.get("OPENCODE_MODEL")
|
|
|
|
|
if opencode_model is None and "arch.opencode.default" in model_aliases:
|
|
|
|
|
opencode_model = model_aliases["arch.opencode.default"].get(
|
|
|
|
|
"target", "arch.opencode.default"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if opencode_model:
|
|
|
|
|
# Set both generic and client-specific model env vars for compatibility.
|
|
|
|
|
env["OPENAI_MODEL"] = opencode_model
|
|
|
|
|
env["OPENCODE_MODEL"] = opencode_model
|
|
|
|
|
|
|
|
|
|
handled_settings.add("OPENCODE_MODEL")
|
|
|
|
|
else:
|
|
|
|
|
raise ValueError(
|
|
|
|
|
f"Unsupported cli-agent type '{agent_type}'. Supported values: claude, codex, opencode"
|
|
|
|
|
)
|
|
|
|
|
|
2025-09-29 19:23:08 -07:00
|
|
|
# Non-interactive mode configuration from additional_settings only
|
|
|
|
|
if additional_settings.get("NON_INTERACTIVE_MODE", False):
|
|
|
|
|
env.update(
|
|
|
|
|
{
|
|
|
|
|
"CI": "true",
|
|
|
|
|
"FORCE_COLOR": "0",
|
|
|
|
|
"NODE_NO_READLINE": "1",
|
|
|
|
|
"TERM": "dumb",
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
2026-02-25 10:16:32 -08:00
|
|
|
# Add passthrough settings for supported agents.
|
2025-09-29 19:23:08 -07:00
|
|
|
if additional_settings:
|
2026-02-25 10:16:32 -08:00
|
|
|
passthrough_settings = {
|
|
|
|
|
k: v for k, v in additional_settings.items() if k not in handled_settings
|
2025-09-29 19:23:08 -07:00
|
|
|
}
|
2026-02-25 10:16:32 -08:00
|
|
|
if agent_type == "claude" and passthrough_settings:
|
|
|
|
|
command_args.append(f"--settings={json.dumps(passthrough_settings)}")
|
2025-09-29 19:23:08 -07:00
|
|
|
|
2026-02-25 10:16:32 -08:00
|
|
|
log.info(f"Connecting {agent_type} CLI agent to Plano at {host}:{port}")
|
2025-09-29 19:23:08 -07:00
|
|
|
|
|
|
|
|
try:
|
2026-02-25 10:16:32 -08:00
|
|
|
subprocess.run([command_path] + command_args, env=env, check=True)
|
2025-09-29 19:23:08 -07:00
|
|
|
except subprocess.CalledProcessError as e:
|
2026-02-25 10:16:32 -08:00
|
|
|
log.error(f"Error starting {agent_type}: {e}")
|
2025-09-29 19:23:08 -07:00
|
|
|
sys.exit(1)
|
|
|
|
|
except FileNotFoundError:
|
2026-02-25 10:16:32 -08:00
|
|
|
if agent_type == "claude":
|
|
|
|
|
log.error(
|
|
|
|
|
"claude not found. Make sure Claude Code is installed: npm install -g @anthropic-ai/claude-code"
|
|
|
|
|
)
|
|
|
|
|
elif agent_type == "codex":
|
|
|
|
|
log.error(
|
|
|
|
|
"codex not found. Make sure Codex CLI is installed: npm install -g @openai/codex"
|
|
|
|
|
)
|
|
|
|
|
else:
|
|
|
|
|
log.error(
|
|
|
|
|
"opencode not found. Make sure OpenCode CLI is installed and available in PATH"
|
|
|
|
|
)
|
2025-09-29 19:23:08 -07:00
|
|
|
sys.exit(1)
|