restructure cli (#656)

This commit is contained in:
Adil Hafeez 2025-12-25 14:55:29 -08:00 committed by GitHub
parent a56bb9d190
commit 88d14a205b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
45 changed files with 153 additions and 115 deletions

36
config/README.md Normal file
View file

@ -0,0 +1,36 @@
# Envoy filter code for gateway
## Add toolchain
```sh
$ rustup target add wasm32-wasip1
```
## Building
```sh
$ cargo build --target wasm32-wasip1 --release
```
## Testing
```sh
$ cargo test
```
## Local development
- Build docker image for arch gateway. Note this needs to be built once.
```
$ sh build_filter_image.sh
```
- Build filter binary,
```
$ cargo build --target wasm32-wasip1 --release
```
- Start envoy with arch_config.yaml and test,
```
$ docker compose -f docker-compose.dev.yaml up archgw
```
- dev version of docker-compose file uses following files that are mounted inside the container. That means no docker rebuild is needed if any of these files change. Just restart the container and chagne will be picked up,
- envoy.template.yaml
- intelligent_prompt_gateway.wasm

View file

@ -0,0 +1,422 @@
$schema: "http://json-schema.org/draft-07/schema#"
type: object
properties:
version:
type: string
enum:
- v0.1
- v0.1.0
- 0.1-beta
- 0.2.0
- v0.3.0
agents:
type: array
items:
type: object
properties:
id:
type: string
url:
type: string
additionalProperties: false
required:
- id
- url
filters:
type: array
items:
type: object
properties:
id:
type: string
url:
type: string
type:
type: string
enum:
- mcp
- http
transport:
type: string
enum:
- streamable-http
tool:
type: string
additionalProperties: false
required:
- id
- url
listeners:
oneOf:
- type: array
additionalProperties: false
items:
type: object
properties:
name:
type: string
port:
type: integer
address:
type: string
timeout:
type: string
router:
type: string
enum:
- plano_orchestrator_v1
type:
type: string
enum:
- model
- prompt
- agent
required:
- type
- name
- type: object # deprecated legacy format, use list format instead
additionalProperties: false
properties:
ingress_traffic:
type: object
properties:
address:
type: string
port:
type: integer
message_format:
type: string
enum:
- openai
timeout:
type: string
additionalProperties: false
egress_traffic:
type: object
properties:
address:
type: string
port:
type: integer
message_format:
type: string
enum:
- openai
timeout:
type: string
additionalProperties: false
endpoints:
type: object
patternProperties:
"^[a-zA-Z][a-zA-Z0-9_]*$":
type: object
properties:
endpoint:
type: string
pattern: "^.*$"
connect_timeout:
type: string
protocol:
type: string
enum:
- http
- https
http_host:
type: string
additionalProperties: false
required:
- endpoint
model_providers:
type: array
items:
type: object
properties:
name:
type: string
access_key:
type: string
model:
type: string
default:
type: boolean
base_url:
type: string
http_host:
type: string
provider_interface:
type: string
enum:
- arch
- claude
- deepseek
- groq
- mistral
- openai
- gemini
routing_preferences:
type: array
items:
type: object
properties:
name:
type: string
description:
type: string
additionalProperties: false
required:
- name
- description
additionalProperties: false
required:
- model
llm_providers: # deprecated for legacy support, use model_providers instead
type: array
items:
type: object
properties:
name:
type: string
access_key:
type: string
model:
type: string
default:
type: boolean
base_url:
type: string
http_host:
type: string
provider_interface:
type: string
enum:
- arch
- claude
- deepseek
- groq
- mistral
- openai
- gemini
routing_preferences:
type: array
items:
type: object
properties:
name:
type: string
description:
type: string
additionalProperties: false
required:
- name
- description
additionalProperties: false
required:
- model
model_aliases:
type: object
patternProperties:
"^.*$":
type: object
properties:
target:
type: string
additionalProperties: false
required:
- target
overrides:
type: object
properties:
prompt_target_intent_matching_threshold:
type: number
optimize_context_window:
type: boolean
use_agent_orchestrator:
type: boolean
system_prompt:
type: string
prompt_targets:
type: array
items:
type: object
properties:
name:
type: string
default:
type: boolean
description:
type: string
auto_llm_dispatch_on_response:
type: boolean
parameters:
type: array
items:
type: object
properties:
name:
type: string
additionalProperties: false
required:
type: boolean
default:
anyOf:
- type: string
- type: integer
- type: boolean
description:
type: string
type:
type: string
enum:
type: array
items:
anyOf:
- type: string
- type: integer
- type: boolean
in_path:
type: boolean
format:
type: string
additionalProperties: false
required:
- name
- description
- type
endpoint:
type: object
properties:
name:
type: string
path:
type: string
http_method:
type: string
enum:
- GET
- POST
http_headers:
type: object
additionalProperties:
type: string
additionalProperties: false
required:
- name
- path
system_prompt:
type: string
additionalProperties: false
required:
- name
- description
ratelimits:
type: array
items:
type: object
properties:
model:
type: string
selector:
type: object
properties:
key:
type: string
value:
type: string
additionalProperties: false
required:
- key
- value
limit:
type: object
properties:
tokens:
type: integer
unit:
type: string
additionalProperties: false
required:
- tokens
- unit
additionalProperties: false
required:
- model
- selector
- limit
tracing:
type: object
properties:
random_sampling:
type: integer
trace_arch_internal:
type: boolean
additionalProperties: false
mode:
type: string
enum:
- llm
- prompt
routing:
type: object
properties:
llm_provider:
type: string
model:
type: string
additionalProperties: false
state_storage:
type: object
properties:
type:
type: string
enum:
- memory
- postgres
connection_string:
type: string
description: Required when type is postgres. Supports environment variable substitution using $VAR or ${VAR} syntax.
additionalProperties: false
required:
- type
# Note: connection_string is conditionally required based on type
# If type is 'postgres', connection_string must be provided
# If type is 'memory', connection_string is not needed
allOf:
- if:
properties:
type:
const: postgres
then:
required:
- connection_string
prompt_guards:
type: object
properties:
input_guards:
type: object
properties:
jailbreak:
type: object
properties:
on_exception:
type: object
properties:
message:
type: string
additionalProperties: false
required:
- message
additionalProperties: false
required:
- on_exception
additionalProperties: false
required:
- jailbreak
additionalProperties: false
required:
- version
- listeners

View file

@ -0,0 +1,24 @@
services:
plano:
image: katanemo/plano:latest
ports:
- "10000:10000"
- "10001:10001"
- "11000:11000"
- "12000:12000"
- "19901:9901"
volumes:
- ${ARCH_CONFIG_FILE:-../demos/samples_python/weather_forecast/arch_config.yaml}:/app/arch_config.yaml
- /etc/ssl/cert.pem:/etc/ssl/cert.pem
- ./envoy.template.yaml:/app/envoy.template.yaml
- ./arch_config_schema.yaml:/app/arch_config_schema.yaml
- ../cli/planoai/config_generator.py:/app/planoai/config_generator.py
- ../crates/target/wasm32-wasip1/release/llm_gateway.wasm:/etc/envoy/proxy-wasm-plugins/llm_gateway.wasm
- ../crates/target/wasm32-wasip1/release/prompt_gateway.wasm:/etc/envoy/proxy-wasm-plugins/prompt_gateway.wasm
- ~/archgw_logs:/var/log/
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
- OPENAI_API_KEY=${OPENAI_API_KEY:?error}
- MISTRAL_API_KEY=${MISTRAL_API_KEY:?error}
- OTEL_TRACING_HTTP_ENDPOINT=http://host.docker.internal:4318/v1/traces

0
config/env.list Normal file
View file

1094
config/envoy.template.yaml Normal file

File diff suppressed because it is too large Load diff

3
config/requirements.txt Normal file
View file

@ -0,0 +1,3 @@
jinja2
pyyaml
jsonschema

23
config/supervisord.conf Normal file
View file

@ -0,0 +1,23 @@
[supervisord]
nodaemon=true
[program:brightstaff]
command=sh -c "envsubst < /app/arch_config_rendered.yaml > /app/arch_config_rendered.env_sub.yaml && RUST_LOG=info ARCH_CONFIG_PATH_RENDERED=/app/arch_config_rendered.env_sub.yaml /app/brightstaff 2>&1 | tee /var/log/brightstaff.log | while IFS= read -r line; do echo '[brightstaff]' \"$line\"; done"
stdout_logfile=/dev/stdout
redirect_stderr=true
stdout_logfile_maxbytes=0
stderr_logfile_maxbytes=0
[program:envoy]
command=/bin/sh -c "python -m planoai.config_generator && envsubst < /etc/envoy/envoy.yaml > /etc/envoy.env_sub.yaml && envoy -c /etc/envoy.env_sub.yaml --component-log-level wasm:info --log-format '[%%Y-%%m-%%d %%T.%%e][%%l] %%v' 2>&1 | tee /var/log/envoy.log | while IFS= read -r line; do echo '[archgw_logs]' \"$line\"; done"
stdout_logfile=/dev/stdout
redirect_stderr=true
stdout_logfile_maxbytes=0
stderr_logfile_maxbytes=0
[program:tail_access_logs]
command=/bin/sh -c "tail -F /var/log/access_*.log | while IFS= read -r line; do echo '[access_logs]' \"$line\"; done"
stdout_logfile=/dev/stdout
redirect_stderr=true
stdout_logfile_maxbytes=0
stderr_logfile_maxbytes=0

View file

@ -0,0 +1,31 @@
#!/bin/bash
failed_files=()
for file in $(find . -name 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/plano:0.4.0 -c "python -m planoai.config_generator" 2>&1 > /dev/null ; then
echo "Validation failed for $file"
failed_files+=("$file")
fi
RENDERED_CHECKED_IN_FILE=$(echo $file | sed 's/\.yaml$/_rendered.yaml/')
if [ -f "$RENDERED_CHECKED_IN_FILE" ]; then
echo "Checking rendered file against checked-in version..."
if ! diff -q "${file}_rendered" "$RENDERED_CHECKED_IN_FILE" > /dev/null; then
echo "Rendered file ${file}_rendered does not match checked-in version ${RENDERED_CHECKED_IN_FILE}"
failed_files+=("${file}_rendered")
else
echo "Rendered file matches checked-in version."
fi
fi
done
# Print summary of failed files
if [ ${#failed_files[@]} -ne 0 ]; then
echo -e "\nValidation failed for the following files:"
printf '%s\n' "${failed_files[@]}"
exit 1
else
echo -e "\nAll files validated successfully!"
fi