diff --git a/.github/workflows/e2e_archgw.yml b/.github/workflows/e2e_archgw.yml
index 46643de1..84ccff68 100644
--- a/.github/workflows/e2e_archgw.yml
+++ b/.github/workflows/e2e_archgw.yml
@@ -7,7 +7,7 @@ on:
pull_request:
jobs:
- test:
+ e2e_archgw_tests:
runs-on: ubuntu-latest-m
defaults:
run:
diff --git a/.github/workflows/e2e_model_server.yml b/.github/workflows/e2e_model_server.yml
index 6d749942..3985fc5a 100644
--- a/.github/workflows/e2e_model_server.yml
+++ b/.github/workflows/e2e_model_server.yml
@@ -7,7 +7,7 @@ on:
pull_request:
jobs:
- test:
+ e2e_model_server_tests:
runs-on: ubuntu-latest-m
defaults:
run:
diff --git a/.github/workflows/e2e_test_demos.yml b/.github/workflows/e2e_test_demos.yml
index dc4255c2..0dfe3dd7 100644
--- a/.github/workflows/e2e_test_demos.yml
+++ b/.github/workflows/e2e_test_demos.yml
@@ -7,7 +7,7 @@ on:
pull_request:
jobs:
- test:
+ e2e_demo_tests:
runs-on: ubuntu-latest-m
steps:
@@ -37,7 +37,7 @@ jobs:
source venv/bin/activate
cd model_server/ && echo "installing model server" && poetry install
cd ../arch/tools && echo "installing archgw cli" && poetry install
- cd ../../demos/test_runner && echo "installing test dependencies" && poetry install
+ cd ../../demos/shared/test_runner && echo "installing test dependencies" && poetry install
- name: run demo tests
env:
@@ -45,4 +45,4 @@ jobs:
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
run: |
source venv/bin/activate
- cd demos/test_runner && sh run_demo_tests.sh
+ cd demos/shared/test_runner && sh run_demo_tests.sh
diff --git a/.github/workflows/e2e_tests.yml b/.github/workflows/e2e_tests.yml
index 370988fe..f894b713 100644
--- a/.github/workflows/e2e_tests.yml
+++ b/.github/workflows/e2e_tests.yml
@@ -7,7 +7,7 @@ on:
pull_request:
jobs:
- test:
+ e2e_tests:
runs-on: ubuntu-latest
steps:
diff --git a/README.md b/README.md
index c5762f52..e3a6a8ba 100644
--- a/README.md
+++ b/README.md
@@ -1,30 +1,41 @@
-
+
-
-
-
-
+
+
-Arch is an **intelligent (edge and LLM) proxy designed for agentic applications** - to help you protect, observe, and build agentic tasks by simply connecting (existing) APIs.
+_Arch is an intelligent (edge and LLM) proxy designed for agentic applications - to help you protect, observe, and build agentic tasks by simply connecting (existing) APIs._
-Built by the contributors of [Envoy Proxy](https://www.envoyproxy.io/) with the belief that:
-
->Prompts are nuanced and opaque user requests, which require the same capabilities as traditional HTTP requests including secure handling, intelligent routing, robust observability, and integration with backend (API) systems for personalization – outside core business logic.*
+[Quickstart](#Quickstart) •
+[Demos](#Demos) •
+[Build agentic apps with Arch](#Build-AI-Agent-with-Arch-Gateway) •
+[Use Arch as an LLM router](#Use-Arch-Gateway-as-LLM-Router) •
+[Documentation](https://docs.archgw.com) •
+[Contact](#Contact)
[](https://github.com/katanemo/arch/actions/workflows/pre-commit.yml)
[](https://github.com/katanemo/arch/actions/workflows/rust_tests.yml)
[](https://github.com/katanemo/arch/actions/workflows/e2e_tests.yml)
[](https://github.com/katanemo/arch/actions/workflows/static.yml)
+
-Arch is engineered with purpose-built LLMs to handle critical but undifferentiated tasks related to the handling and processing of prompts. This includes detecting and rejecting [jailbreak](https://github.com/verazuo/jailbreak_llms) attempts, intelligent task routing for improved accuracy, mapping user request into "backend" functions, and managing the observability of prompts and LLM API calls in a centralized way.
+# Overview
+
+Arch Gateway was built by the contributors of [Envoy Proxy](https://www.envoyproxy.io/) with the belief that:
+
+>Prompts are nuanced and opaque user requests, which require the same capabilities as traditional HTTP requests including secure handling, intelligent routing, robust observability, and integration with backend (API) systems for personalization – outside core business logic.*
+
+
+Arch is engineered with purpose-built LLMs to handle critical but pesky tasks related to the handling and processing of prompts. This includes detecting and rejecting [jailbreak](https://github.com/verazuo/jailbreak_llms) attempts, intent-based routing for improved task accuracy, mapping user request into "backend" functions, and managing the observability of prompts and LLM API calls in a centralized way.
+
**Core Features**:
- - Built on [Envoy](https://envoyproxy.io): Arch runs alongside application servers as a separate containerized process, and builds on top of Envoy's proven HTTP management and scalability features to handle ingress and egress traffic related to prompts and LLMs.
- - Task Routing & Fast Function Calling. Engineered with purpose-built [LLMs](https://huggingface.co/collections/katanemo/arch-function-66f209a693ea8df14317ad68) to handle fast, cost-effective, and accurate prompt-based tasks like function/API calling, and parameter extraction from prompts to build more task-accurate agentic applications.
- - Prompt [Guard](https://huggingface.co/collections/katanemo/arch-guard-6702bdc08b889e4bce8f446d): Arch centralizes guardrails to prevent jailbreak attempts and ensure safe user interactions without writing a single line of code.
- - Routing & Traffic Management: Arch centralizes calls to LLMs used by your applications, offering smart retries, automatic cutover, and resilient upstream connections for continuous availability.
- - Observability: Arch uses the W3C Trace Context standard to enable complete request tracing across applications, ensuring compatibility with observability tools, and provides metrics to monitor latency, token usage, and error rates, helping optimize AI application performance.
+
+ - **Intent-based prompt routing & fast ⚡ function-calling via APIs**. Engineered with purpose-built [LLMs](https://huggingface.co/collections/katanemo/arch-function-66f209a693ea8df14317ad68) to handle fast, cost-effective, and accurate prompt-based tasks like function/API calling, and parameter extraction from prompts to build more task-accurate agentic applications.
+ - **Prompt [Guard](https://huggingface.co/collections/katanemo/arch-guard-6702bdc08b889e4bce8f446d)**: Arch centralizes guardrails to prevent jailbreak attempts and ensure safe user interactions without writing a single line of code.
+ - **LLM Routing & Traffic Management**: Arch centralizes calls to LLMs used by your applications, offering smart retries, automatic cutover, and resilient upstream connections for continuous availability.
+ - **Observability**: Arch uses the W3C Trace Context standard to enable complete request tracing across applications, ensuring compatibility with observability tools, and provides metrics to monitor latency, token usage, and error rates, helping optimize AI application performance.
+ - **Built on [Envoy](https://envoyproxy.io)**: Arch runs alongside application servers as a separate containerized process, and builds on top of Envoy's proven HTTP management and scalability features to handle ingress and egress traffic related to prompts and LLMs.
**High-Level Sequence Diagram**:

@@ -38,9 +49,9 @@ Arch is engineered with purpose-built LLMs to handle critical but undifferentiat
To get in touch with us, please join our [discord server](https://discord.gg/pGZf2gcwEc). We will be monitoring that actively and offering support there.
## Demos
-* [Weather Forecast](demos/weather_forecast/README.md) - Walk through of the core function calling capabilities of arch gateway using weather forecasting service
-* [Insurance Agent](demos/insurance_agent/README.md) - Build a full insurance agent with Arch
-* [Network Agent](demos/network_agent/README.md) - Build a networking co-pilot/agent agent with Arch
+* [Sample App: Weather Forecast Agent](demos/samples_python/weather_forecast/README.md) - A sample agentic weather forecasting app that highlights core function calling capabilities of Arch.
+* [Sample App: Network Operator Agent](demos/samples_python/network_switch_operator_agent/README.md) - A simple network device switch operator agent that can retrive device statistics and reboot them.
+* [User Case: Connecting to SaaS APIs](demos/use_cases/spotify_bearer_auth) - Connect 3rd party SaaS APIs to your agentic chat experience.
## Quickstart
@@ -62,7 +73,7 @@ Arch's CLI allows you to manage and interact with the Arch gateway efficiently.
```console
$ python -m venv venv
$ source venv/bin/activate # On Windows, use: venv\Scripts\activate
-$ pip install archgw==0.2.0
+$ pip install archgw==0.2.1
```
### Build AI Agent with Arch Gateway
diff --git a/arch/arch_config_schema.yaml b/arch/arch_config_schema.yaml
index f2b2c8a5..1b32b730 100644
--- a/arch/arch_config_schema.yaml
+++ b/arch/arch_config_schema.yaml
@@ -79,6 +79,8 @@ properties:
properties:
prompt_target_intent_matching_threshold:
type: number
+ optimize_context_window:
+ type: boolean
system_prompt:
type: string
prompt_targets:
diff --git a/arch/docker-compose.dev.yaml b/arch/docker-compose.dev.yaml
index 04edd8db..0b52d057 100644
--- a/arch/docker-compose.dev.yaml
+++ b/arch/docker-compose.dev.yaml
@@ -8,7 +8,7 @@ services:
- "12000:12000"
- "19901:9901"
volumes:
- - ${ARCH_CONFIG_FILE:-../demos/weather_forecast/arch_config.yaml}:/app/arch_config.yaml
+ - ${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
diff --git a/arch/tools/README.md b/arch/tools/README.md
index 9a2c6e14..a4722c4a 100644
--- a/arch/tools/README.md
+++ b/arch/tools/README.md
@@ -19,7 +19,7 @@ source venv/bin/activate
### Step 3: Run the build script
```bash
-pip install archgw==0.2.0
+pip install archgw==0.2.1
```
## Uninstall Instructions: archgw CLI
diff --git a/arch/tools/poetry.lock b/arch/tools/poetry.lock
index 21f2772c..d5a45050 100644
--- a/arch/tools/poetry.lock
+++ b/arch/tools/poetry.lock
@@ -2,7 +2,7 @@
[[package]]
name = "archgw_modelserver"
-version = "0.2.0"
+version = "0.2.1"
description = "A model server for serving models"
optional = false
python-versions = "*"
@@ -15,13 +15,13 @@ url = "../../model_server"
[[package]]
name = "attrs"
-version = "24.3.0"
+version = "25.1.0"
description = "Classes Without Boilerplate"
optional = false
python-versions = ">=3.8"
files = [
- {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"},
- {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"},
+ {file = "attrs-25.1.0-py3-none-any.whl", hash = "sha256:c75a69e28a550a7e93789579c22aa26b0f5b83b75dc4e08fe092980051e1090a"},
+ {file = "attrs-25.1.0.tar.gz", hash = "sha256:1c97078a80c814273a76b2a298a932eb681c87415c11dee0a6921de7f1b02c3e"},
]
[package.extras]
@@ -34,13 +34,13 @@ tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"]
[[package]]
name = "certifi"
-version = "2024.12.14"
+version = "2025.1.31"
description = "Python package for providing Mozilla's CA Bundle."
optional = false
python-versions = ">=3.6"
files = [
- {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"},
- {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"},
+ {file = "certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe"},
+ {file = "certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651"},
]
[[package]]
@@ -370,13 +370,13 @@ files = [
[[package]]
name = "referencing"
-version = "0.36.1"
+version = "0.36.2"
description = "JSON Referencing + Python"
optional = false
python-versions = ">=3.9"
files = [
- {file = "referencing-0.36.1-py3-none-any.whl", hash = "sha256:363d9c65f080d0d70bc41c721dce3c7f3e77fc09f269cd5c8813da18069a6794"},
- {file = "referencing-0.36.1.tar.gz", hash = "sha256:ca2e6492769e3602957e9b831b94211599d2aade9477f5d44110d2530cf9aade"},
+ {file = "referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0"},
+ {file = "referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa"},
]
[package.dependencies]
@@ -568,4 +568,4 @@ zstd = ["zstandard (>=0.18.0)"]
[metadata]
lock-version = "2.0"
python-versions = "^3.10"
-content-hash = "59543baf4d462d4830e7228ba9eda8ae865416fdabd8ede129492ac45f1926f2"
+content-hash = "6b29791896ec1680e2c841ac42e835c1bada672b056d8208ab24388f70f9badb"
diff --git a/arch/tools/pyproject.toml b/arch/tools/pyproject.toml
index 28b3b3ab..7ed79a36 100644
--- a/arch/tools/pyproject.toml
+++ b/arch/tools/pyproject.toml
@@ -1,6 +1,6 @@
[tool.poetry]
name = "archgw"
-version = "0.2.0"
+version = "0.2.1"
description = "Python-based CLI tool to manage Arch Gateway."
authors = ["Katanemo Labs, Inc."]
packages = [
@@ -10,7 +10,7 @@ readme = "README.md"
[tool.poetry.dependencies]
python = "^3.10"
-archgw_modelserver = "^0.2.0"
+archgw_modelserver = "^0.2.1"
click = "^8.1.7"
jinja2 = "^3.1.4"
jsonschema = "^4.23.0"
diff --git a/crates/common/src/configuration.rs b/crates/common/src/configuration.rs
index f1250499..069695ba 100644
--- a/crates/common/src/configuration.rs
+++ b/crates/common/src/configuration.rs
@@ -25,6 +25,7 @@ pub struct Configuration {
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct Overrides {
pub prompt_target_intent_matching_threshold: Option,
+ pub optimize_context_window: Option,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
diff --git a/crates/prompt_gateway/src/http_context.rs b/crates/prompt_gateway/src/http_context.rs
index e7d920f1..1ff7f91d 100644
--- a/crates/prompt_gateway/src/http_context.rs
+++ b/crates/prompt_gateway/src/http_context.rs
@@ -137,9 +137,20 @@ impl HttpContext for StreamContext {
.map(|(_, pt)| pt.into())
.collect();
+ let mut metadata = deserialized_body.metadata.clone();
+
+ if let Some(overrides) = self.overrides.as_ref() {
+ if overrides.optimize_context_window.unwrap_or_default() {
+ if metadata.is_none() {
+ metadata = Some(HashMap::new());
+ }
+ metadata.as_mut().unwrap().insert("optimize_context_window".to_string(), "true".to_string());
+ }
+ }
+
let arch_fc_chat_completion_request = ChatCompletionsRequest {
messages: deserialized_body.messages.clone(),
- metadata: deserialized_body.metadata.clone(),
+ metadata,
stream: deserialized_body.stream,
model: "--".to_string(),
stream_options: deserialized_body.stream_options.clone(),
diff --git a/crates/prompt_gateway/src/stream_context.rs b/crates/prompt_gateway/src/stream_context.rs
index 2704e8d8..e6db7f59 100644
--- a/crates/prompt_gateway/src/stream_context.rs
+++ b/crates/prompt_gateway/src/stream_context.rs
@@ -46,7 +46,7 @@ pub struct StreamCallContext {
pub struct StreamContext {
system_prompt: Rc>,
pub prompt_targets: Rc>,
- _overrides: Rc>,
+ pub overrides: Rc >,
pub metrics: Rc,
pub callouts: RefCell>,
pub context_id: u32,
@@ -89,7 +89,7 @@ impl StreamContext {
streaming_response: false,
user_prompt: None,
is_chat_completions_request: false,
- _overrides: overrides,
+ overrides: overrides,
request_id: None,
traceparent: None,
_tracing: tracing,
diff --git a/demos/insurance_agent/Dockerfile b/demos/insurance_agent/Dockerfile
deleted file mode 100644
index 95855991..00000000
--- a/demos/insurance_agent/Dockerfile
+++ /dev/null
@@ -1,19 +0,0 @@
-FROM python:3 AS base
-
-FROM base AS builder
-
-WORKDIR /src
-
-COPY requirements.txt /src/
-RUN pip install --prefix=/runtime --force-reinstall -r requirements.txt
-
-COPY . /src
-
-FROM python:3-slim AS output
-
-COPY --from=builder /runtime /usr/local
-
-COPY . /app
-WORKDIR /app
-
-CMD ["uvicorn", "insurance_agent_main:app", "--host", "0.0.0.0", "--port", "80", "--log-level", "info"]
diff --git a/demos/insurance_agent/README.md b/demos/insurance_agent/README.md
deleted file mode 100644
index 46067173..00000000
--- a/demos/insurance_agent/README.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# Insurance Agent Demo
-
-This demo showcases how the **Arch** can be used to manage insurance-related tasks such as policy inquiries, initiating policies, and updating claims or deductibles. In this demo, the assistant provides factual information related to insurance policies (e.g., car, boat, house, motorcycle).
-
-The system can perform a variety of tasks, such as answering insurance-related questions, retrieving policy coverage details, initiating policies, and updating claims or deductibles.
-
-## Available Functions:
-
-- **Policy Q/A**: Handles general Q&A related to insurance policies.
- - **Endpoint**: `/policy/qa`
- - This function answers general inquiries related to insurance, such as coverage details or policy types. It is the default target for insurance-related queries.
-
-- **Get Policy Coverage**: Retrieves the coverage details for a given policy type (car, boat, house, motorcycle).
- - **Endpoint**: `/policy/coverage`
- - Parameters:
- - `policy_type` (required): The type of policy. Available options: `car`, `boat`, `house`, `motorcycle`. Defaults to `car`.
-
-- **Initiate Policy**: Starts a policy coverage for car, boat, motorcycle, or house.
- - **Endpoint**: `/policy/initiate`
- - Parameters:
- - `policy_type` (required): The type of policy. Available options: `car`, `boat`, `house`, `motorcycle`. Defaults to `car`.
- - `deductible` (required): The deductible amount set for the policy.
-
-- **Update Claim**: Updates the notes on a specific insurance claim.
- - **Endpoint**: `/policy/claim`
- - Parameters:
- - `claim_id` (required): The claim number.
- - `notes` (optional): Notes about the claim number for the adjustor to see.
-
-- **Update Deductible**: Updates the deductible amount for a specific policy coverage.
- - **Endpoint**: `/policy/deductible`
- - Parameters:
- - `policy_id` (required): The ID of the policy.
- - `deductible` (required): The deductible amount to be set for the policy.
-
-**Arch** is designed to intelligently routes prompts to the appropriate functions based on the target, allowing for seamless interaction with various insurance-related services.
-
-# Starting the demo
-1. Please make sure the [pre-requisites](https://github.com/katanemo/arch/?tab=readme-ov-file#prerequisites) are installed correctly
-2. Start Arch
- ```sh
- sh run_demo.sh
- ```
-3. Navigate to http://localhost:18080/
-4. Tell me what can you do for me?"
-
-# Observability
-Arch gateway publishes stats endpoint at http://localhost:19901/stats. In this demo we are using prometheus to pull stats from arch and we are using grafana to visalize the stats in dashboard. To see grafana dashboard follow instructions below,
-
-1. Start grafana and prometheus using following command
- ```yaml
- docker compose --profile monitoring up
- ```
-1. Navigate to http://localhost:3000/ to open grafana UI (use admin/grafana as credentials)
-1. From grafana left nav click on dashboards and select "Intelligent Gateway Overview" to view arch gateway stats
-
-Here is sample interaction,
-
diff --git a/demos/insurance_agent/arch_config.yaml b/demos/insurance_agent/arch_config.yaml
deleted file mode 100644
index 9e5c6ed3..00000000
--- a/demos/insurance_agent/arch_config.yaml
+++ /dev/null
@@ -1,105 +0,0 @@
-version: v0.1
-listener:
- address: 127.0.0.1
- port: 8080 #If you configure port 443, you'll need to update the listener with tls_certificates
- message_format: huggingface
-
-system_prompt: |
- You are an insurance assistant that just offers guidance related to car, boat, rental and home insurnace only. Please be pricese and summarize based on the context provided.
-
-llm_providers:
- - name: OpenAI
- provider_interface: openai
- access_key: $OPENAI_API_KEY
- model: gpt-4o
- default: true
-
-# Arch creates a round-robin load balancing between different endpoints, managed via the cluster subsystem.
-endpoints:
- app_server:
- # value could be ip address or a hostname with port
- # this could also be a list of endpoints for load balancing
- # for example endpoint: [ ip1:port, ip2:port ]
- endpoint: host.docker.internal:18083
- # max time to wait for a connection to be established
- connect_timeout: 0.05s
-
-prompt_targets:
- - name: policy_qa
- endpoint:
- name: app_server
- path: /policy/qa
- http_method: POST
- description: Handle general Q/A related to insurance.
- default: true
-
- - name: get_policy_coverage
- description: Retrieve the coverage details for an insurance policy.
- endpoint:
- name: app_server
- path: /policy/coverage
- http_method: POST
- parameters:
- - name: policy_type
- type: str
- description: The type of policy
- default: car
- required: true
-
- - name: initiate_policy
- endpoint:
- name: app_server
- path: /policy/initiate
- http_method: POST
- description: Start a policy coverage for an insurance policy
- parameters:
- - name: policy_type
- type: str
- description: The type of policy
- default: car
- required: true
- - name: deductible
- type: float
- description: the deductible amount set of the policy
- required: true
-
- - name: update_claim
- endpoint:
- name: app_server
- path: /policy/claim
- http_method: POST
- description: Update the notes on the claim
- parameters:
- - name: claim_id
- type: str
- description: the claim number
- required: true
- - name: notes
- type: str
- description: notes about the cliam number for your adjustor to see
- required: false
-
- - name: update_deductible
- endpoint:
- name: app_server
- path: /policy/deductible
- http_method: POST
- description: Update the deductible amount for a specific insurance policy coverage.
- parameters:
- - name: policy_id
- type: str
- description: The id of the insurance policy
- required: true
- - name: deductible
- type: float
- description: the deductible amount set of the policy
- required: true
-
-ratelimits:
- - model: gpt-4
- selector:
- key: selector-key
- value: selector-value
- limit:
- tokens: 1
- unit: minute
diff --git a/demos/insurance_agent/insurance_agent_main.py b/demos/insurance_agent/insurance_agent_main.py
deleted file mode 100644
index 3143342f..00000000
--- a/demos/insurance_agent/insurance_agent_main.py
+++ /dev/null
@@ -1,140 +0,0 @@
-from fastapi import FastAPI, HTTPException
-from pydantic import BaseModel, Field
-
-app = FastAPI()
-
-
-class Conversation(BaseModel):
- arch_messages: list
-
-
-class PolicyCoverageRequest(BaseModel):
- policy_type: str = Field(
- ...,
- description="The type of a policy held by the customer For, e.g. car, boat, house, motorcycle)",
- )
-
-
-class PolicyInitiateRequest(PolicyCoverageRequest):
- deductible: float = Field(
- ..., description="The deductible amount set of the policy"
- )
-
-
-class ClaimUpdate(BaseModel):
- claim_id: str
- notes: str # Status or details of the claim
-
-
-class DeductibleUpdate(BaseModel):
- policy_id: str
- deductible: float
-
-
-class CoverageResponse(BaseModel):
- policy_type: str
- coverage: str # Description of coverage
- premium: float # The premium cost
-
-
-# Get information about policy coverage
-@app.post("/policy/coverage", response_model=CoverageResponse)
-async def get_policy_coverage(req: PolicyCoverageRequest):
- """
- Retrieve the coverage details for a given policy type (car, boat, house, motorcycle).
- """
- policy_coverage = {
- "car": {
- "coverage": "Full car coverage with collision, liability",
- "premium": 500.0,
- },
- "boat": {
- "coverage": "Full boat coverage including theft and storm damage",
- "premium": 700.0,
- },
- "house": {
- "coverage": "Full house coverage including fire, theft, flood",
- "premium": 1000.0,
- },
- "motorcycle": {
- "coverage": "Full motorcycle coverage with liability",
- "premium": 400.0,
- },
- }
-
- if req.policy_type not in policy_coverage:
- raise HTTPException(status_code=404, detail="Policy type not found")
-
- return CoverageResponse(
- policy_type=req.policy_type,
- coverage=policy_coverage[req.policy_type]["coverage"],
- premium=policy_coverage[req.policy_type]["premium"],
- )
-
-
-# Initiate policy coverage
-@app.post("/policy/initiate")
-async def initiate_policy(policy_request: PolicyInitiateRequest):
- """
- Initiate policy coverage for a car, boat, house, or motorcycle.
- """
- if policy_request.policy_type not in ["car", "boat", "house", "motorcycle"]:
- raise HTTPException(status_code=400, detail="Invalid policy type")
-
- return {
- "message": f"Policy initiated for {policy_request.policy_type}",
- "deductible": policy_request.deductible,
- }
-
-
-# Update claim details
-@app.post("/policy/claim")
-async def update_claim(req: ClaimUpdate):
- """
- Update the status or details of a claim.
- """
- # For simplicity, this is a mock update response
- return {
- "message": f"Claim {claim_update.claim_id} for policy {claim_update.claim_id} has been updated",
- "update": claim_update.notes,
- }
-
-
-# Update deductible amount
-@app.post("/policy/deductible")
-async def update_deductible(deductible_update: DeductibleUpdate):
- """
- Update the deductible amount for a specific policy.
- """
- # For simplicity, this is a mock update response
- return {
- "message": f"Deductible for policy {deductible_update.policy_id} has been updated",
- "new_deductible": deductible_update.deductible,
- }
-
-
-# Post method for policy Q/A
-@app.post("/policy/qa")
-async def policy_qa(conversation: Conversation):
- """
- This method handles Q/A related to general issues in insurance.
- It forwards the conversation to the OpenAI client via a local proxy and returns the response.
- """
- return {
- "choices": [
- {
- "message": {
- "role": "assistant",
- "content": "I am a helpful insurance agent, and can only help with insurance things",
- },
- "finish_reason": "completed",
- "index": 0,
- }
- ],
- "model": "insurance_agent",
- "usage": {"completion_tokens": 0},
- }
-
-
-# Run the app using:
-# uvicorn main:app --reload
diff --git a/demos/insurance_agent/requirements.txt b/demos/insurance_agent/requirements.txt
deleted file mode 100644
index 6703613f..00000000
--- a/demos/insurance_agent/requirements.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-fastapi
-uvicorn
-pydantic
-openai
diff --git a/demos/network_agent/grafana/dashboard.yaml b/demos/network_agent/grafana/dashboard.yaml
deleted file mode 100644
index fd66a479..00000000
--- a/demos/network_agent/grafana/dashboard.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
-apiVersion: 1
-
-providers:
- - name: "Dashboard provider"
- orgId: 1
- type: file
- disableDeletion: false
- updateIntervalSeconds: 10
- allowUiUpdates: false
- options:
- path: /var/lib/grafana/dashboards
- foldersFromFilesStructure: true
diff --git a/demos/network_agent/grafana/dashboards/envoy_overview.json b/demos/network_agent/grafana/dashboards/envoy_overview.json
deleted file mode 100644
index 51bff777..00000000
--- a/demos/network_agent/grafana/dashboards/envoy_overview.json
+++ /dev/null
@@ -1,355 +0,0 @@
-{
- "annotations": {
- "list": [
- {
- "builtIn": 1,
- "datasource": {
- "type": "grafana",
- "uid": "-- Grafana --"
- },
- "enable": true,
- "hide": true,
- "iconColor": "rgba(0, 211, 255, 1)",
- "name": "Annotations & Alerts",
- "type": "dashboard"
- }
- ]
- },
- "editable": true,
- "fiscalYearStartMonth": 0,
- "graphTooltip": 1,
- "links": [],
- "panels": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "line",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- }
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 0,
- "y": 0
- },
- "id": 2,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "list",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "disableTextWrap": false,
- "editorMode": "code",
- "expr": "avg(rate(envoy_cluster_internal_upstream_rq_time_sum[1m]) / rate(envoy_cluster_internal_upstream_rq_time_count[1m])) by (envoy_cluster_name)",
- "fullMetaSearch": false,
- "hide": false,
- "includeNullMetadata": true,
- "instant": false,
- "legendFormat": "__auto",
- "range": true,
- "refId": "A",
- "useBackend": false
- }
- ],
- "title": "request latency - internal (ms)",
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "line",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- }
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 12,
- "y": 0
- },
- "id": 1,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "list",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "disableTextWrap": false,
- "editorMode": "code",
- "expr": "avg(rate(envoy_cluster_external_upstream_rq_time_sum[1m]) / rate(envoy_cluster_external_upstream_rq_time_count[1m])) by (envoy_cluster_name)",
- "fullMetaSearch": false,
- "hide": false,
- "includeNullMetadata": true,
- "instant": false,
- "legendFormat": "__auto",
- "range": true,
- "refId": "A",
- "useBackend": false
- }
- ],
- "title": "request latency - external (ms)",
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "line",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- }
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 0,
- "y": 8
- },
- "id": 3,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "list",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "disableTextWrap": false,
- "editorMode": "code",
- "expr": "avg(rate(envoy_cluster_internal_upstream_rq_completed[1m])) by (envoy_cluster_name)",
- "fullMetaSearch": false,
- "includeNullMetadata": true,
- "instant": false,
- "legendFormat": "__auto",
- "range": true,
- "refId": "A",
- "useBackend": false
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "disableTextWrap": false,
- "editorMode": "code",
- "expr": "avg(rate(envoy_cluster_external_upstream_rq_completed[1m])) by (envoy_cluster_name)",
- "fullMetaSearch": false,
- "hide": false,
- "includeNullMetadata": true,
- "instant": false,
- "legendFormat": "__auto",
- "range": true,
- "refId": "B",
- "useBackend": false
- }
- ],
- "title": "Upstream request count",
- "type": "timeseries"
- }
- ],
- "schemaVersion": 39,
- "tags": [],
- "templating": {
- "list": []
- },
- "time": {
- "from": "now-15m",
- "to": "now"
- },
- "timepicker": {},
- "timezone": "browser",
- "title": "Intelligent Gateway Overview",
- "uid": "adt6uhx5lk8aob",
- "version": 3,
- "weekStart": ""
-}
diff --git a/demos/network_agent/grafana/datasource.yaml b/demos/network_agent/grafana/datasource.yaml
deleted file mode 100644
index 4870174e..00000000
--- a/demos/network_agent/grafana/datasource.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-apiVersion: 1
-
-datasources:
-- name: Prometheus
- type: prometheus
- url: http://prometheus:9090
- isDefault: true
- access: proxy
- editable: true
diff --git a/demos/network_agent/utils.py b/demos/network_agent/utils.py
deleted file mode 100644
index ed1be070..00000000
--- a/demos/network_agent/utils.py
+++ /dev/null
@@ -1,253 +0,0 @@
-import logging
-import random
-import re
-import sqlite3
-from datetime import datetime, timedelta, timezone
-
-import pandas as pd
-from dateparser import parse
-
-logging.basicConfig(
- level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
-)
-logger = logging.getLogger(__name__)
-
-
-def loadsql():
- # Example Usage
- conn = sqlite3.connect(":memory:")
-
- # create and load the devices table
- device_data = generate_device_data(conn)
-
- # create and load the interface_stats table
- generate_interface_stats_data(conn, device_data)
-
- # create and load the flow table
- generate_flow_data(conn, device_data)
-
- return conn
-
-
-# Function to convert natural language time expressions to "X {time} ago" format
-def convert_to_ago_format(expression):
- # Define patterns for different time units
- time_units = {
- r"seconds": "seconds",
- r"minutes": "minutes",
- r"mins": "mins",
- r"hrs": "hrs",
- r"hours": "hours",
- r"hour": "hour",
- r"hr": "hour",
- r"days": "days",
- r"day": "day",
- r"weeks": "weeks",
- r"week": "week",
- r"months": "months",
- r"month": "month",
- r"years": "years",
- r"yrs": "years",
- r"year": "year",
- r"yr": "year",
- }
-
- # Iterate over each time unit and create regex for each phrase format
- for pattern, unit in time_units.items():
- # Handle "for the past X {unit}"
- match = re.search(rf"(\d+) {pattern}", expression)
- if match:
- quantity = match.group(1)
- return f"{quantity} {unit} ago"
-
- # If the format is not recognized, return None or raise an error
- return None
-
-
-# Function to generate random MAC addresses
-def random_mac():
- return "AA:BB:CC:DD:EE:" + ":".join(
- [f"{random.randint(0, 255):02X}" for _ in range(2)]
- )
-
-
-# Function to generate random IP addresses
-def random_ip():
- return f"""{random.randint(1, 255)}
- .{random.randint(1, 255)}
- .{random.randint(1, 255)}
- .{random.randint(1, 255)}"""
-
-
-# Generate synthetic data for the device table
-def generate_device_data(
- conn,
- n=1000,
-):
- device_data = {
- "switchip": [random_ip() for _ in range(n)],
- "hwsku": [f"HW{i+1}" for i in range(n)],
- "hostname": [f"switch{i+1}" for i in range(n)],
- "osversion": [f"v{i+1}" for i in range(n)],
- "layer": ["L2" if i % 2 == 0 else "L3" for i in range(n)],
- "region": [random.choice(["US", "EU", "ASIA"]) for _ in range(n)],
- "uptime": [
- f"""{random.randint(0, 10)} days {random.randint(0, 23)}
- :{random.randint(0, 59)}:{random.randint(0, 59)}"""
- for _ in range(n)
- ],
- "device_mac_address": [random_mac() for _ in range(n)],
- }
- df = pd.DataFrame(device_data)
- df.to_sql("device", conn, index=False)
- return df
-
-
-# Generate synthetic data for the interfacestats table
-def generate_interface_stats_data(conn, device_df, n=1000):
- interface_stats_data = []
- for _ in range(n):
- device_mac = random.choice(device_df["device_mac_address"])
- ifname = random.choice(["eth0", "eth1", "eth2", "eth3"])
- time = datetime.now(timezone.utc) - timedelta(
- minutes=random.randint(0, 1440 * 5)
- ) # random timestamps in the past 5 day
- in_discards = random.randint(0, 1000)
- in_errors = random.randint(0, 500)
- out_discards = random.randint(0, 800)
- out_errors = random.randint(0, 400)
- in_octets = random.randint(1000, 100000)
- out_octets = random.randint(1000, 100000)
-
- interface_stats_data.append(
- {
- "device_mac_address": device_mac,
- "ifname": ifname,
- "time": time,
- "in_discards": in_discards,
- "in_errors": in_errors,
- "out_discards": out_discards,
- "out_errors": out_errors,
- "in_octets": in_octets,
- "out_octets": out_octets,
- }
- )
- df = pd.DataFrame(interface_stats_data)
- df.to_sql("interfacestats", conn, index=False)
-
-
-# Generate synthetic data for the ts_flow table
-def generate_flow_data(conn, device_df, n=1000):
- flow_data = []
- for _ in range(n):
- sampler_address = random.choice(device_df["switchip"])
- proto = random.choice(["TCP", "UDP"])
- src_addr = random_ip()
- dst_addr = random_ip()
- src_port = random.randint(1024, 65535)
- dst_port = random.randint(1024, 65535)
- in_if = random.randint(1, 10)
- out_if = random.randint(1, 10)
- flow_start = int(
- (datetime.now() - timedelta(days=random.randint(1, 30))).timestamp()
- )
- flow_end = int(
- (datetime.now() - timedelta(days=random.randint(1, 30))).timestamp()
- )
- bytes_transferred = random.randint(1000, 100000)
- packets = random.randint(1, 1000)
- flow_time = datetime.now(timezone.utc) - timedelta(
- minutes=random.randint(0, 1440 * 5)
- ) # random flow time
-
- flow_data.append(
- {
- "sampler_address": sampler_address,
- "proto": proto,
- "src_addr": src_addr,
- "dst_addr": dst_addr,
- "src_port": src_port,
- "dst_port": dst_port,
- "in_if": in_if,
- "out_if": out_if,
- "flow_start": flow_start,
- "flow_end": flow_end,
- "bytes": bytes_transferred,
- "packets": packets,
- "time": flow_time,
- }
- )
- df = pd.DataFrame(flow_data)
- df.to_sql("ts_flow", conn, index=False)
-
-
-def load_params(req):
- # Step 1: Convert the from_time natural language string to a timestamp if provided
- if req.from_time:
- # Use `dateparser` to parse natural language timeframes
- logger.info("%s\n\nCaptured from time: %s\n\n", "* " * 50, req.from_time)
- parsed_time = parse(req.from_time, settings={"RELATIVE_BASE": datetime.now()})
- if not parsed_time:
- conv_time = convert_to_ago_format(req.from_time)
- if conv_time:
- parsed_time = parse(
- conv_time, settings={"RELATIVE_BASE": datetime.now()}
- )
- else:
- return {
- "error": """Invalid from_time format. Please provide a valid time description
- such as 'past 7 days' or 'since last month'."""
- }
- logger.info("\n\nConverted from time: %s\n\n%s\n\n", parsed_time, "* " * 50)
- from_time = parsed_time
- logger.info("Using parsed from_time: %f", from_time)
- else:
- # If no from_time is provided, use a default value (e.g., the past 7 days)
- from_time = datetime.now() - timedelta(days=7)
- logger.info("Using default from_time: %f", from_time)
-
- # Step 2: Build the dynamic SQL query based on the optional filters
- filters = []
- params = {"from_time": from_time}
-
- if req.ifname:
- filters.append("i.ifname = :ifname")
- params["ifname"] = req.ifname
-
- if req.region:
- filters.append("d.region = :region")
- params["region"] = req.region
-
- if req.min_in_errors is not None:
- filters.append("i.in_errors >= :min_in_errors")
- params["min_in_errors"] = req.min_in_errors
-
- if req.max_in_errors is not None:
- filters.append("i.in_errors <= :max_in_errors")
- params["max_in_errors"] = req.max_in_errors
-
- if req.min_out_errors is not None:
- filters.append("i.out_errors >= :min_out_errors")
- params["min_out_errors"] = req.min_out_errors
-
- if req.max_out_errors is not None:
- filters.append("i.out_errors <= :max_out_errors")
- params["max_out_errors"] = req.max_out_errors
-
- if req.min_in_discards is not None:
- filters.append("i.in_discards >= :min_in_discards")
- params["min_in_discards"] = req.min_in_discards
-
- if req.max_in_discards is not None:
- filters.append("i.in_discards <= :max_in_discards")
- params["max_in_discards"] = req.max_in_discards
-
- if req.min_out_discards is not None:
- filters.append("i.out_discards >= :min_out_discards")
- params["min_out_discards"] = req.min_out_discards
-
- if req.max_out_discards is not None:
- filters.append("i.out_discards <= :max_out_discards")
- params["max_out_discards"] = req.max_out_discards
-
- return params, filters
diff --git a/demos/samples_java/weather_forcecast_service/Dockerfile b/demos/samples_java/weather_forcecast_service/Dockerfile
new file mode 100644
index 00000000..1f536c5a
--- /dev/null
+++ b/demos/samples_java/weather_forcecast_service/Dockerfile
@@ -0,0 +1,18 @@
+# Stage 1: Build the application using Maven
+FROM maven:3.8.7-openjdk-18-slim AS build
+WORKDIR /app
+# Copy pom.xml and download dependencies first (caching)
+COPY pom.xml .
+RUN mvn dependency:go-offline
+# Copy the source code and build the application
+COPY src ./src
+RUN mvn clean package -DskipTests
+
+# Stage 2: Run the application using a slim JDK image
+FROM openjdk:17-jdk-slim
+WORKDIR /app
+# Copy the built jar from the previous stage
+COPY --from=build /app/target/weather-forecast-service-0.0.1-SNAPSHOT.jar app.jar
+# Expose the port on which the app runs (default Spring Boot is 8080)
+EXPOSE 8081
+ENTRYPOINT ["java", "-jar", "app.jar"]
diff --git a/demos/samples_java/weather_forcecast_service/arch_config.yaml b/demos/samples_java/weather_forcecast_service/arch_config.yaml
new file mode 100644
index 00000000..10c22819
--- /dev/null
+++ b/demos/samples_java/weather_forcecast_service/arch_config.yaml
@@ -0,0 +1,45 @@
+version: v0.1
+listener:
+ address: 127.0.0.1
+ port: 10000 #If you configure port 443, you'll need to update the listener with tls_certificates
+ message_format: huggingface
+
+# Centralized way to manage LLMs, manage keys, retry logic, failover and limits in a central way
+llm_providers:
+ - name: OpenAI
+ provider_interface: openai
+ access_key: $OPENAI_API_KEY
+ model: gpt-4o-mini
+ default: true
+
+# Arch creates a round-robin load balancing between different endpoints, managed via the cluster subsystem.
+endpoints:
+ weather_forecast_service:
+ # value could be ip address or a hostname with port
+ # this could also be a list of endpoints for load balancing
+ # for example endpoint: [ ip1:port, ip2:port ]
+ endpoint: host.docker.internal:18081
+ # max time to wait for a connection to be established
+ connect_timeout: 0.005s
+
+# default system prompt used by all prompt targets
+system_prompt: |
+ You are a helpful weather assistant.
+
+prompt_targets:
+ - name: weather_forecast
+ description: get the weather forecast
+ parameters:
+ - name: location
+ description: the location for which to get the weather forecast
+ required: true
+ type: string
+ format: City, State
+ - name: days
+ description: the number of days for the forecast
+ required: true
+ type: int
+ endpoint:
+ name: weather_forecast_service
+ path: /weather
+ http_method: POST
diff --git a/demos/insurance_agent/docker-compose.yaml b/demos/samples_java/weather_forcecast_service/docker-compose.yaml
similarity index 66%
rename from demos/insurance_agent/docker-compose.yaml
rename to demos/samples_java/weather_forcecast_service/docker-compose.yaml
index a4bd27bd..998800b7 100644
--- a/demos/insurance_agent/docker-compose.yaml
+++ b/demos/samples_java/weather_forcecast_service/docker-compose.yaml
@@ -1,18 +1,14 @@
services:
- api_server:
+ weather_forecast_service:
build:
context: .
dockerfile: Dockerfile
ports:
- - "18083:80"
- healthcheck:
- test: ["CMD", "curl" ,"http://localhost:80/healthz"]
- interval: 5s
- retries: 20
+ - "18081:8081"
chatbot_ui:
build:
- context: ../shared/chatbot_ui
+ context: ../../shared/chatbot_ui
dockerfile: Dockerfile
ports:
- "18080:8080"
diff --git a/demos/samples_java/weather_forcecast_service/pom.xml b/demos/samples_java/weather_forcecast_service/pom.xml
new file mode 100644
index 00000000..c2fed928
--- /dev/null
+++ b/demos/samples_java/weather_forcecast_service/pom.xml
@@ -0,0 +1,40 @@
+
+ 4.0.0
+
+ weather
+ weather-forecast-service
+ 0.0.1-SNAPSHOT
+ jar
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.7.10
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/demos/currency_exchange/run_demo.sh b/demos/samples_java/weather_forcecast_service/run_demo.sh
similarity index 100%
rename from demos/currency_exchange/run_demo.sh
rename to demos/samples_java/weather_forcecast_service/run_demo.sh
diff --git a/demos/samples_java/weather_forcecast_service/src/main/java/weather/WeatherForecastApplication.java b/demos/samples_java/weather_forcecast_service/src/main/java/weather/WeatherForecastApplication.java
new file mode 100644
index 00000000..b31a3444
--- /dev/null
+++ b/demos/samples_java/weather_forcecast_service/src/main/java/weather/WeatherForecastApplication.java
@@ -0,0 +1,12 @@
+// File: src/main/java/com/example/weather/WeatherForecastApplication.java
+package weather;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class WeatherForecastApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(WeatherForecastApplication.class, args);
+ }
+}
diff --git a/demos/samples_java/weather_forcecast_service/src/main/java/weather/controller/WeatherController.java b/demos/samples_java/weather_forcecast_service/src/main/java/weather/controller/WeatherController.java
new file mode 100644
index 00000000..bb41227a
--- /dev/null
+++ b/demos/samples_java/weather_forcecast_service/src/main/java/weather/controller/WeatherController.java
@@ -0,0 +1,54 @@
+package weather.controller;
+
+import weather.model.DayForecast;
+import weather.model.WeatherForecastResponse;
+import weather.model.WeatherRequest;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.Instant;
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+@RestController
+public class WeatherController {
+
+ private Random random = new Random();
+
+ @PostMapping("/weather")
+ public WeatherForecastResponse getRandomWeatherForecast(@RequestBody WeatherRequest req) {
+ WeatherForecastResponse response = new WeatherForecastResponse();
+ response.setLocation(req.getLocation());
+ response.setUnits(req.getUnits());
+
+ List forecasts = new ArrayList<>();
+ for (int i = 0; i < req.getDays(); i++) {
+ // Generate a random min temperature between 50 and 89 (inclusive)
+ int minTemp = random.nextInt(90 - 50) + 50;
+ // Generate a max temperature between (minTemp + 5) and (minTemp + 19)
+ int maxTemp = random.nextInt(15) + (minTemp + 5);
+
+ double finalMinTemp = minTemp;
+ double finalMaxTemp = maxTemp;
+
+ // Convert to Celsius if necessary
+ if (req.getUnits().equalsIgnoreCase("celsius") || req.getUnits().equalsIgnoreCase("c")) {
+ finalMinTemp = (minTemp - 32) * 5.0 / 9.0;
+ finalMaxTemp = (maxTemp - 32) * 5.0 / 9.0;
+ }
+
+ DayForecast dayForecast = new DayForecast();
+ dayForecast.setDate(LocalDate.now().plusDays(i).toString());
+ dayForecast.setMin(finalMinTemp);
+ dayForecast.setMax(finalMaxTemp);
+ dayForecast.setUnits(req.getUnits());
+
+ forecasts.add(dayForecast);
+ }
+ response.setDailyForecast(forecasts);
+ return response;
+ }
+}
diff --git a/demos/samples_java/weather_forcecast_service/src/main/java/weather/model/DayForecast.java b/demos/samples_java/weather_forcecast_service/src/main/java/weather/model/DayForecast.java
new file mode 100644
index 00000000..0077a3a7
--- /dev/null
+++ b/demos/samples_java/weather_forcecast_service/src/main/java/weather/model/DayForecast.java
@@ -0,0 +1,40 @@
+package weather.model;
+
+public class DayForecast {
+ private String date;
+ private String units;
+ private double min;
+ private double max;
+
+ public DayForecast() {}
+
+ // Getters and setters
+ public String getDate() {
+ return date;
+ }
+
+ public void setDate(String date) {
+ this.date = date;
+ }
+
+ public String getUnits() {
+ return units;
+ }
+
+ public void setUnits(String units) {
+ this.units = units;
+ }
+
+ public double getMin() {
+ return min;
+ }
+ public void setMin(double min) {
+ this.min = min;
+ }
+ public double getMax() {
+ return max;
+ }
+ public void setMax(double max) {
+ this.max = max;
+ }
+}
diff --git a/demos/samples_java/weather_forcecast_service/src/main/java/weather/model/WeatherForecastResponse.java b/demos/samples_java/weather_forcecast_service/src/main/java/weather/model/WeatherForecastResponse.java
new file mode 100644
index 00000000..3fc4d116
--- /dev/null
+++ b/demos/samples_java/weather_forcecast_service/src/main/java/weather/model/WeatherForecastResponse.java
@@ -0,0 +1,37 @@
+package weather.model;
+
+import java.util.List;
+
+public class WeatherForecastResponse {
+ private String location;
+ private String units;
+ private List forecast;
+
+ // Default Constructor
+ public WeatherForecastResponse() {}
+
+ // Getters and Setters
+ public String getLocation() {
+ return location;
+ }
+
+ public void setLocation(String location) {
+ this.location = location;
+ }
+
+ public String getUnits() {
+ return units;
+ }
+
+ public void setUnits(String units) {
+ this.units = units;
+ }
+
+ public List getDailyForecast() {
+ return forecast;
+ }
+
+ public void setDailyForecast(List forecast) {
+ this.forecast = forecast;
+ }
+}
diff --git a/demos/samples_java/weather_forcecast_service/src/main/java/weather/model/WeatherRequest.java b/demos/samples_java/weather_forcecast_service/src/main/java/weather/model/WeatherRequest.java
new file mode 100644
index 00000000..8b5e1340
--- /dev/null
+++ b/demos/samples_java/weather_forcecast_service/src/main/java/weather/model/WeatherRequest.java
@@ -0,0 +1,29 @@
+package weather.model;
+
+public class WeatherRequest {
+ private String location;
+ private int days = 7;
+ private String units = "Farenheit";
+
+ public WeatherRequest() {}
+
+ // Getters and setters
+ public String getLocation() {
+ return location;
+ }
+ public void setLocation(String location) {
+ this.location = location;
+ }
+ public int getDays() {
+ return days;
+ }
+ public void setDays(int days) {
+ this.days = days;
+ }
+ public String getUnits() {
+ return units;
+ }
+ public void setUnits(String units) {
+ this.units = units;
+ }
+}
diff --git a/demos/samples_java/weather_forcecast_service/src/main/resources/application.properties b/demos/samples_java/weather_forcecast_service/src/main/resources/application.properties
new file mode 100644
index 00000000..4d360de1
--- /dev/null
+++ b/demos/samples_java/weather_forcecast_service/src/main/resources/application.properties
@@ -0,0 +1 @@
+server.port=8081
diff --git a/demos/currency_exchange/README.md b/demos/samples_python/currency_exchange/README.md
similarity index 100%
rename from demos/currency_exchange/README.md
rename to demos/samples_python/currency_exchange/README.md
diff --git a/demos/currency_exchange/arch_config.yaml b/demos/samples_python/currency_exchange/arch_config.yaml
similarity index 100%
rename from demos/currency_exchange/arch_config.yaml
rename to demos/samples_python/currency_exchange/arch_config.yaml
diff --git a/demos/currency_exchange/docker-compose.yaml b/demos/samples_python/currency_exchange/docker-compose.yaml
similarity index 86%
rename from demos/currency_exchange/docker-compose.yaml
rename to demos/samples_python/currency_exchange/docker-compose.yaml
index 32e52c40..ee5465a5 100644
--- a/demos/currency_exchange/docker-compose.yaml
+++ b/demos/samples_python/currency_exchange/docker-compose.yaml
@@ -1,7 +1,7 @@
services:
chatbot_ui:
build:
- context: ../shared/chatbot_ui
+ context: ../../shared/chatbot_ui
ports:
- "18080:8080"
environment:
@@ -14,7 +14,7 @@ services:
jaeger:
build:
- context: ../shared/jaeger
+ context: ../../shared/jaeger
ports:
- "16686:16686"
- "4317:4317"
diff --git a/demos/currency_exchange_ollama/run_demo.sh b/demos/samples_python/currency_exchange/run_demo.sh
similarity index 100%
rename from demos/currency_exchange_ollama/run_demo.sh
rename to demos/samples_python/currency_exchange/run_demo.sh
diff --git a/demos/currency_exchange/test_data.yaml b/demos/samples_python/currency_exchange/test_data.yaml
similarity index 100%
rename from demos/currency_exchange/test_data.yaml
rename to demos/samples_python/currency_exchange/test_data.yaml
diff --git a/demos/hr_agent/Dockerfile b/demos/samples_python/human_resources_agent/Dockerfile
similarity index 100%
rename from demos/hr_agent/Dockerfile
rename to demos/samples_python/human_resources_agent/Dockerfile
diff --git a/demos/hr_agent/README.md b/demos/samples_python/human_resources_agent/README.md
similarity index 100%
rename from demos/hr_agent/README.md
rename to demos/samples_python/human_resources_agent/README.md
diff --git a/demos/hr_agent/arch_config.yaml b/demos/samples_python/human_resources_agent/arch_config.yaml
similarity index 100%
rename from demos/hr_agent/arch_config.yaml
rename to demos/samples_python/human_resources_agent/arch_config.yaml
diff --git a/demos/hr_agent/docker-compose.yaml b/demos/samples_python/human_resources_agent/docker-compose.yaml
similarity index 89%
rename from demos/hr_agent/docker-compose.yaml
rename to demos/samples_python/human_resources_agent/docker-compose.yaml
index 61c710a2..f1afe6f4 100644
--- a/demos/hr_agent/docker-compose.yaml
+++ b/demos/samples_python/human_resources_agent/docker-compose.yaml
@@ -8,7 +8,6 @@ services:
- CHAT_COMPLETION_ENDPOINT=http://host.docker.internal:10000/v1
volumes:
- ./arch_config.yaml:/app/arch_config.yaml
- - ../shared/chatbot_ui/common.py:/app/common.py
ports:
- "18080:80"
healthcheck:
@@ -18,7 +17,7 @@ services:
chatbot_ui:
build:
- context: ../shared/chatbot_ui
+ context: ../../shared/chatbot_ui
dockerfile: Dockerfile
ports:
- "18080:8080"
diff --git a/demos/hr_agent/image.png b/demos/samples_python/human_resources_agent/image.png
similarity index 100%
rename from demos/hr_agent/image.png
rename to demos/samples_python/human_resources_agent/image.png
diff --git a/demos/hr_agent/main.py b/demos/samples_python/human_resources_agent/main.py
similarity index 100%
rename from demos/hr_agent/main.py
rename to demos/samples_python/human_resources_agent/main.py
diff --git a/demos/hr_agent/requirements.txt b/demos/samples_python/human_resources_agent/requirements.txt
similarity index 100%
rename from demos/hr_agent/requirements.txt
rename to demos/samples_python/human_resources_agent/requirements.txt
diff --git a/demos/hr_agent/run_demo.sh b/demos/samples_python/human_resources_agent/run_demo.sh
similarity index 100%
rename from demos/hr_agent/run_demo.sh
rename to demos/samples_python/human_resources_agent/run_demo.sh
diff --git a/demos/hr_agent/test_data.yaml b/demos/samples_python/human_resources_agent/test_data.yaml
similarity index 100%
rename from demos/hr_agent/test_data.yaml
rename to demos/samples_python/human_resources_agent/test_data.yaml
diff --git a/demos/hr_agent/workforce_data.json b/demos/samples_python/human_resources_agent/workforce_data.json
similarity index 100%
rename from demos/hr_agent/workforce_data.json
rename to demos/samples_python/human_resources_agent/workforce_data.json
diff --git a/demos/multi_turn_rag_agent/Dockerfile b/demos/samples_python/multi_turn_rag_agent/Dockerfile
similarity index 100%
rename from demos/multi_turn_rag_agent/Dockerfile
rename to demos/samples_python/multi_turn_rag_agent/Dockerfile
diff --git a/demos/multi_turn_rag_agent/README.md b/demos/samples_python/multi_turn_rag_agent/README.md
similarity index 100%
rename from demos/multi_turn_rag_agent/README.md
rename to demos/samples_python/multi_turn_rag_agent/README.md
diff --git a/demos/multi_turn_rag_agent/arch_config.yaml b/demos/samples_python/multi_turn_rag_agent/arch_config.yaml
similarity index 100%
rename from demos/multi_turn_rag_agent/arch_config.yaml
rename to demos/samples_python/multi_turn_rag_agent/arch_config.yaml
diff --git a/demos/multi_turn_rag_agent/docker-compose.yaml b/demos/samples_python/multi_turn_rag_agent/docker-compose.yaml
similarity index 93%
rename from demos/multi_turn_rag_agent/docker-compose.yaml
rename to demos/samples_python/multi_turn_rag_agent/docker-compose.yaml
index 3bc8fc40..0bcbdbfd 100644
--- a/demos/multi_turn_rag_agent/docker-compose.yaml
+++ b/demos/samples_python/multi_turn_rag_agent/docker-compose.yaml
@@ -12,7 +12,7 @@ services:
chatbot_ui:
build:
- context: ../shared/chatbot_ui
+ context: ../../shared/chatbot_ui
dockerfile: Dockerfile
ports:
- "18080:8080"
diff --git a/demos/multi_turn_rag_agent/main.py b/demos/samples_python/multi_turn_rag_agent/main.py
similarity index 100%
rename from demos/multi_turn_rag_agent/main.py
rename to demos/samples_python/multi_turn_rag_agent/main.py
diff --git a/demos/multi_turn_rag_agent/mutli-turn-example.png b/demos/samples_python/multi_turn_rag_agent/mutli-turn-example.png
similarity index 100%
rename from demos/multi_turn_rag_agent/mutli-turn-example.png
rename to demos/samples_python/multi_turn_rag_agent/mutli-turn-example.png
diff --git a/demos/multi_turn_rag_agent/requirements.txt b/demos/samples_python/multi_turn_rag_agent/requirements.txt
similarity index 100%
rename from demos/multi_turn_rag_agent/requirements.txt
rename to demos/samples_python/multi_turn_rag_agent/requirements.txt
diff --git a/demos/multi_turn_rag_agent/run_demo.sh b/demos/samples_python/multi_turn_rag_agent/run_demo.sh
similarity index 100%
rename from demos/multi_turn_rag_agent/run_demo.sh
rename to demos/samples_python/multi_turn_rag_agent/run_demo.sh
diff --git a/demos/network_agent/Dockerfile b/demos/samples_python/network_switch_operator_agent/Dockerfile
similarity index 91%
rename from demos/network_agent/Dockerfile
rename to demos/samples_python/network_switch_operator_agent/Dockerfile
index d54fa746..96600b38 100644
--- a/demos/network_agent/Dockerfile
+++ b/demos/samples_python/network_switch_operator_agent/Dockerfile
@@ -7,13 +7,13 @@ WORKDIR /src
COPY requirements.txt /src/
RUN pip install --prefix=/runtime --force-reinstall -r requirements.txt
-COPY . /src
+COPY ../. /src
FROM python:3.12-slim AS output
COPY --from=builder /runtime /usr/local
-COPY . /app
+COPY ../. /app
WORKDIR /app
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80", "--log-level", "info"]
diff --git a/demos/network_agent/README.md b/demos/samples_python/network_switch_operator_agent/README.md
similarity index 100%
rename from demos/network_agent/README.md
rename to demos/samples_python/network_switch_operator_agent/README.md
diff --git a/demos/network_agent/arch_config.yaml b/demos/samples_python/network_switch_operator_agent/arch_config.yaml
similarity index 100%
rename from demos/network_agent/arch_config.yaml
rename to demos/samples_python/network_switch_operator_agent/arch_config.yaml
diff --git a/demos/network_agent/docker-compose.yaml b/demos/samples_python/network_switch_operator_agent/docker-compose.yaml
similarity index 91%
rename from demos/network_agent/docker-compose.yaml
rename to demos/samples_python/network_switch_operator_agent/docker-compose.yaml
index f8235331..90b5c084 100644
--- a/demos/network_agent/docker-compose.yaml
+++ b/demos/samples_python/network_switch_operator_agent/docker-compose.yaml
@@ -8,7 +8,7 @@ services:
chatbot_ui:
build:
- context: ../shared/chatbot_ui
+ context: ../../shared/chatbot_ui
dockerfile: Dockerfile
ports:
- "18080:8080"
diff --git a/demos/network_agent/image.png b/demos/samples_python/network_switch_operator_agent/image.png
similarity index 100%
rename from demos/network_agent/image.png
rename to demos/samples_python/network_switch_operator_agent/image.png
diff --git a/demos/network_agent/main.py b/demos/samples_python/network_switch_operator_agent/main.py
similarity index 100%
rename from demos/network_agent/main.py
rename to demos/samples_python/network_switch_operator_agent/main.py
diff --git a/demos/network_agent/requirements.txt b/demos/samples_python/network_switch_operator_agent/requirements.txt
similarity index 100%
rename from demos/network_agent/requirements.txt
rename to demos/samples_python/network_switch_operator_agent/requirements.txt
diff --git a/demos/insurance_agent/run_demo.sh b/demos/samples_python/network_switch_operator_agent/run_demo.sh
similarity index 99%
rename from demos/insurance_agent/run_demo.sh
rename to demos/samples_python/network_switch_operator_agent/run_demo.sh
index e6c678e8..6995e7d0 100644
--- a/demos/insurance_agent/run_demo.sh
+++ b/demos/samples_python/network_switch_operator_agent/run_demo.sh
@@ -24,6 +24,7 @@ start_demo() {
# Step 4: Start Network Agent
echo "Starting Network Agent using Docker Compose..."
+ cd build
docker compose up -d # Run in detached mode
}
diff --git a/demos/stock_quote/README.md b/demos/samples_python/stock_quote/README.md
similarity index 100%
rename from demos/stock_quote/README.md
rename to demos/samples_python/stock_quote/README.md
diff --git a/demos/stock_quote/arch_config.yaml b/demos/samples_python/stock_quote/arch_config.yaml
similarity index 100%
rename from demos/stock_quote/arch_config.yaml
rename to demos/samples_python/stock_quote/arch_config.yaml
diff --git a/demos/stock_quote/docker-compose.yaml b/demos/samples_python/stock_quote/docker-compose.yaml
similarity index 86%
rename from demos/stock_quote/docker-compose.yaml
rename to demos/samples_python/stock_quote/docker-compose.yaml
index 32cfbd20..a862224a 100644
--- a/demos/stock_quote/docker-compose.yaml
+++ b/demos/samples_python/stock_quote/docker-compose.yaml
@@ -1,7 +1,7 @@
services:
chatbot_ui:
build:
- context: ../shared/chatbot_ui
+ context: ../../shared/chatbot_ui
ports:
- "18080:8080"
environment:
@@ -14,7 +14,7 @@ services:
jaeger:
build:
- context: ../shared/jaeger
+ context: ../../shared/jaeger
ports:
- "16686:16686"
- "4317:4317"
diff --git a/demos/stock_quote/run_demo.sh b/demos/samples_python/stock_quote/run_demo.sh
similarity index 100%
rename from demos/stock_quote/run_demo.sh
rename to demos/samples_python/stock_quote/run_demo.sh
diff --git a/demos/stock_quote/stock_quote_demo.png b/demos/samples_python/stock_quote/stock_quote_demo.png
similarity index 100%
rename from demos/stock_quote/stock_quote_demo.png
rename to demos/samples_python/stock_quote/stock_quote_demo.png
diff --git a/demos/weather_forecast/Dockerfile b/demos/samples_python/weather_forecast/Dockerfile
similarity index 100%
rename from demos/weather_forecast/Dockerfile
rename to demos/samples_python/weather_forecast/Dockerfile
diff --git a/demos/weather_forecast/README.md b/demos/samples_python/weather_forecast/README.md
similarity index 100%
rename from demos/weather_forecast/README.md
rename to demos/samples_python/weather_forecast/README.md
diff --git a/demos/weather_forecast/arch_config.yaml b/demos/samples_python/weather_forecast/arch_config.yaml
similarity index 100%
rename from demos/weather_forecast/arch_config.yaml
rename to demos/samples_python/weather_forecast/arch_config.yaml
diff --git a/demos/weather_forecast/docker-compose-honeycomb.yaml b/demos/samples_python/weather_forecast/docker-compose-honeycomb.yaml
similarity index 77%
rename from demos/weather_forecast/docker-compose-honeycomb.yaml
rename to demos/samples_python/weather_forecast/docker-compose-honeycomb.yaml
index 9f81fa69..5b1612e6 100644
--- a/demos/weather_forecast/docker-compose-honeycomb.yaml
+++ b/demos/samples_python/weather_forecast/docker-compose-honeycomb.yaml
@@ -11,7 +11,7 @@ services:
chatbot_ui:
build:
- context: ../shared/chatbot_ui
+ context: ../../shared/chatbot_ui
ports:
- "18080:8080"
environment:
@@ -24,12 +24,12 @@ services:
otel-collector:
build:
- context: ../shared/honeycomb/
+ context: ../../shared/honeycomb/
ports:
- "4317:4317"
- "4318:4318"
volumes:
- - ../shared/honeycomb/otel-collector-config.yaml:/etc/otel-collector-config.yaml
+ - ../../shared/honeycomb/otel-collector-config.yaml:/etc/otel-collector-config.yaml
env_file:
- .env
environment:
@@ -37,10 +37,10 @@ services:
prometheus:
build:
- context: ../shared/prometheus
+ context: ../../shared/prometheus
grafana:
build:
- context: ../shared/grafana
+ context: ../../shared/grafana
ports:
- "3000:3000"
diff --git a/demos/weather_forecast/docker-compose-jaeger.yaml b/demos/samples_python/weather_forecast/docker-compose-jaeger.yaml
similarity index 83%
rename from demos/weather_forecast/docker-compose-jaeger.yaml
rename to demos/samples_python/weather_forecast/docker-compose-jaeger.yaml
index 15441de3..dab610bf 100644
--- a/demos/weather_forecast/docker-compose-jaeger.yaml
+++ b/demos/samples_python/weather_forecast/docker-compose-jaeger.yaml
@@ -11,7 +11,7 @@ services:
chatbot_ui:
build:
- context: ../shared/chatbot_ui
+ context: ../../shared/chatbot_ui
ports:
- "18080:8080"
environment:
@@ -24,7 +24,7 @@ services:
jaeger:
build:
- context: ../shared/jaeger
+ context: ../../shared/jaeger
ports:
- "16686:16686"
- "4317:4317"
@@ -32,10 +32,10 @@ services:
prometheus:
build:
- context: ../shared/prometheus
+ context: ../../shared/prometheus
grafana:
build:
- context: ../shared/grafana
+ context: ../../shared/grafana
ports:
- "3000:3000"
diff --git a/demos/weather_forecast/docker-compose-logfire.yaml b/demos/samples_python/weather_forecast/docker-compose-logfire.yaml
similarity index 77%
rename from demos/weather_forecast/docker-compose-logfire.yaml
rename to demos/samples_python/weather_forecast/docker-compose-logfire.yaml
index 6f747cd0..164862c2 100644
--- a/demos/weather_forecast/docker-compose-logfire.yaml
+++ b/demos/samples_python/weather_forecast/docker-compose-logfire.yaml
@@ -11,7 +11,7 @@ services:
chatbot_ui:
build:
- context: ../shared/chatbot_ui
+ context: ../../shared/chatbot_ui
ports:
- "18080:8080"
environment:
@@ -24,12 +24,12 @@ services:
otel-collector:
build:
- context: ../shared/logfire/
+ context: ../../shared/logfire/
ports:
- "4317:4317"
- "4318:4318"
volumes:
- - ../shared/logfire/otel-collector-config.yaml:/etc/otel-collector-config.yaml
+ - ../../shared/logfire/otel-collector-config.yaml:/etc/otel-collector-config.yaml
env_file:
- .env
environment:
@@ -37,10 +37,10 @@ services:
prometheus:
build:
- context: ../shared/prometheus
+ context: ../../shared/prometheus
grafana:
build:
- context: ../shared/grafana
+ context: ../../shared/grafana
ports:
- "3000:3000"
diff --git a/demos/weather_forecast/docker-compose-signoz.yaml b/demos/samples_python/weather_forecast/docker-compose-signoz.yaml
similarity index 80%
rename from demos/weather_forecast/docker-compose-signoz.yaml
rename to demos/samples_python/weather_forecast/docker-compose-signoz.yaml
index 392debfb..a40d32f0 100644
--- a/demos/weather_forecast/docker-compose-signoz.yaml
+++ b/demos/samples_python/weather_forecast/docker-compose-signoz.yaml
@@ -1,5 +1,5 @@
include:
- - ../shared/signoz/docker-compose-minimal.yaml
+ - ../../shared/signoz/docker-compose-minimal.yaml
services:
weather_forecast_service:
@@ -14,7 +14,7 @@ services:
chatbot_ui:
build:
- context: ../shared/chatbot_ui
+ context: ../../shared/chatbot_ui
ports:
- "18080:8080"
environment:
@@ -27,10 +27,10 @@ services:
prometheus:
build:
- context: ../shared/prometheus
+ context: ../../shared/prometheus
grafana:
build:
- context: ../shared/grafana
+ context: ../../shared/grafana
ports:
- "3000:3000"
diff --git a/demos/weather_forecast/docker-compose.yaml b/demos/samples_python/weather_forecast/docker-compose.yaml
similarity index 58%
rename from demos/weather_forecast/docker-compose.yaml
rename to demos/samples_python/weather_forecast/docker-compose.yaml
index 15441de3..566dfa8d 100644
--- a/demos/weather_forecast/docker-compose.yaml
+++ b/demos/samples_python/weather_forecast/docker-compose.yaml
@@ -11,7 +11,7 @@ services:
chatbot_ui:
build:
- context: ../shared/chatbot_ui
+ context: ../../shared/chatbot_ui
ports:
- "18080:8080"
environment:
@@ -19,23 +19,3 @@ services:
- CHAT_COMPLETION_ENDPOINT=http://host.docker.internal:10000/v1
extra_hosts:
- "host.docker.internal:host-gateway"
- volumes:
- - ./arch_config.yaml:/app/arch_config.yaml
-
- jaeger:
- build:
- context: ../shared/jaeger
- ports:
- - "16686:16686"
- - "4317:4317"
- - "4318:4318"
-
- prometheus:
- build:
- context: ../shared/prometheus
-
- grafana:
- build:
- context: ../shared/grafana
- ports:
- - "3000:3000"
diff --git a/demos/weather_forecast/main.py b/demos/samples_python/weather_forecast/main.py
similarity index 100%
rename from demos/weather_forecast/main.py
rename to demos/samples_python/weather_forecast/main.py
diff --git a/demos/weather_forecast/poetry.lock b/demos/samples_python/weather_forecast/poetry.lock
similarity index 100%
rename from demos/weather_forecast/poetry.lock
rename to demos/samples_python/weather_forecast/poetry.lock
diff --git a/demos/weather_forecast/pyproject.toml b/demos/samples_python/weather_forecast/pyproject.toml
similarity index 100%
rename from demos/weather_forecast/pyproject.toml
rename to demos/samples_python/weather_forecast/pyproject.toml
diff --git a/demos/weather_forecast/run_demo.sh b/demos/samples_python/weather_forecast/run_demo.sh
similarity index 100%
rename from demos/weather_forecast/run_demo.sh
rename to demos/samples_python/weather_forecast/run_demo.sh
diff --git a/demos/test_runner/common.py b/demos/shared/test_runner/common.py
similarity index 100%
rename from demos/test_runner/common.py
rename to demos/shared/test_runner/common.py
diff --git a/demos/test_runner/poetry.lock b/demos/shared/test_runner/poetry.lock
similarity index 100%
rename from demos/test_runner/poetry.lock
rename to demos/shared/test_runner/poetry.lock
diff --git a/demos/test_runner/pyproject.toml b/demos/shared/test_runner/pyproject.toml
similarity index 100%
rename from demos/test_runner/pyproject.toml
rename to demos/shared/test_runner/pyproject.toml
diff --git a/demos/test_runner/run_demo_tests.sh b/demos/shared/test_runner/run_demo_tests.sh
similarity index 62%
rename from demos/test_runner/run_demo_tests.sh
rename to demos/shared/test_runner/run_demo_tests.sh
index 2f7a7ae6..a029345f 100644
--- a/demos/test_runner/run_demo_tests.sh
+++ b/demos/shared/test_runner/run_demo_tests.sh
@@ -7,13 +7,13 @@ do
echo "******************************************"
echo "Running tests for $demo ..."
echo "****************************************"
- cd ../$demo
+ cd ../../samples_python/$demo
archgw up arch_config.yaml
docker compose up -d
- cd ../test_runner
- TEST_DATA=../$demo/test_data.yaml poetry run pytest
- cd ../$demo
+ cd ../../shared/test_runner
+ TEST_DATA=../../samples_python/$demo/test_data.yaml poetry run pytest
+ cd ../../samples_python/$demo
archgw down
docker compose down -v
- cd ../test_runner
+ cd ../../shared/test_runner
done
diff --git a/demos/test_runner/test_demos.py b/demos/shared/test_runner/test_demos.py
similarity index 100%
rename from demos/test_runner/test_demos.py
rename to demos/shared/test_runner/test_demos.py
diff --git a/demos/llm_routing/README.md b/demos/use_cases/llm_routing/README.md
similarity index 98%
rename from demos/llm_routing/README.md
rename to demos/use_cases/llm_routing/README.md
index 8418b7f8..08c06dc4 100644
--- a/demos/llm_routing/README.md
+++ b/demos/use_cases/llm_routing/README.md
@@ -1,5 +1,5 @@
# LLM Routing
-This demo shows how you can arch gateway to manage keys and route to appropriate LLM.
+This demo shows how you can arch gateway to manage keys and route to upstream LLM.
# Starting the demo
1. Please make sure the [pre-requisites](https://github.com/katanemo/arch/?tab=readme-ov-file#prerequisites) are installed correctly
diff --git a/demos/llm_routing/arch_config.yaml b/demos/use_cases/llm_routing/arch_config.yaml
similarity index 100%
rename from demos/llm_routing/arch_config.yaml
rename to demos/use_cases/llm_routing/arch_config.yaml
diff --git a/demos/llm_routing/docker-compose.yaml b/demos/use_cases/llm_routing/docker-compose.yaml
similarity index 76%
rename from demos/llm_routing/docker-compose.yaml
rename to demos/use_cases/llm_routing/docker-compose.yaml
index ac59499c..c2d794c6 100644
--- a/demos/llm_routing/docker-compose.yaml
+++ b/demos/use_cases/llm_routing/docker-compose.yaml
@@ -2,7 +2,7 @@ services:
chatbot_ui:
build:
- context: ../shared/chatbot_ui
+ context: ../../shared/chatbot_ui
dockerfile: Dockerfile
ports:
- "18080:8080"
@@ -15,7 +15,7 @@ services:
jaeger:
build:
- context: ../shared/jaeger
+ context: ../../shared/jaeger
ports:
- "16686:16686"
- "4317:4317"
@@ -23,10 +23,10 @@ services:
prometheus:
build:
- context: ../shared/prometheus
+ context: ../../shared/prometheus
grafana:
build:
- context: ../shared/grafana
+ context: ../../shared/grafana
ports:
- "3000:3000"
diff --git a/demos/llm_routing/jaeger_tracing_llm_routing.png b/demos/use_cases/llm_routing/jaeger_tracing_llm_routing.png
similarity index 100%
rename from demos/llm_routing/jaeger_tracing_llm_routing.png
rename to demos/use_cases/llm_routing/jaeger_tracing_llm_routing.png
diff --git a/demos/llm_routing/llm_routing_demo.png b/demos/use_cases/llm_routing/llm_routing_demo.png
similarity index 100%
rename from demos/llm_routing/llm_routing_demo.png
rename to demos/use_cases/llm_routing/llm_routing_demo.png
diff --git a/demos/llm_routing/run_demo.sh b/demos/use_cases/llm_routing/run_demo.sh
similarity index 100%
rename from demos/llm_routing/run_demo.sh
rename to demos/use_cases/llm_routing/run_demo.sh
diff --git a/demos/currency_exchange_ollama/README.md b/demos/use_cases/ollama/README.md
similarity index 100%
rename from demos/currency_exchange_ollama/README.md
rename to demos/use_cases/ollama/README.md
diff --git a/demos/currency_exchange_ollama/arch_config.yaml b/demos/use_cases/ollama/arch_config.yaml
similarity index 100%
rename from demos/currency_exchange_ollama/arch_config.yaml
rename to demos/use_cases/ollama/arch_config.yaml
diff --git a/demos/currency_exchange_ollama/docker-compose.yaml b/demos/use_cases/ollama/docker-compose.yaml
similarity index 86%
rename from demos/currency_exchange_ollama/docker-compose.yaml
rename to demos/use_cases/ollama/docker-compose.yaml
index 32e52c40..ee5465a5 100644
--- a/demos/currency_exchange_ollama/docker-compose.yaml
+++ b/demos/use_cases/ollama/docker-compose.yaml
@@ -1,7 +1,7 @@
services:
chatbot_ui:
build:
- context: ../shared/chatbot_ui
+ context: ../../shared/chatbot_ui
ports:
- "18080:8080"
environment:
@@ -14,7 +14,7 @@ services:
jaeger:
build:
- context: ../shared/jaeger
+ context: ../../shared/jaeger
ports:
- "16686:16686"
- "4317:4317"
diff --git a/demos/currency_exchange_ollama/docker-compose_honeycomb.yaml b/demos/use_cases/ollama/docker-compose_honeycomb.yaml
similarity index 77%
rename from demos/currency_exchange_ollama/docker-compose_honeycomb.yaml
rename to demos/use_cases/ollama/docker-compose_honeycomb.yaml
index 3c46c7cf..ab0df80d 100644
--- a/demos/currency_exchange_ollama/docker-compose_honeycomb.yaml
+++ b/demos/use_cases/ollama/docker-compose_honeycomb.yaml
@@ -1,7 +1,7 @@
services:
chatbot_ui:
build:
- context: ../shared/chatbot_ui
+ context: ../../shared/chatbot_ui
ports:
- "18080:8080"
environment:
@@ -14,12 +14,12 @@ services:
otel-collector:
build:
- context: ../shared/honeycomb/
+ context: ../../shared/honeycomb/
ports:
- "4317:4317"
- "4318:4318"
volumes:
- - ../shared/honeycomb/otel-collector-config.yaml:/etc/otel-collector-config.yaml
+ - ../../shared/honeycomb/otel-collector-config.yaml:/etc/otel-collector-config.yaml
env_file:
- .env
environment:
diff --git a/demos/network_agent/run_demo.sh b/demos/use_cases/ollama/run_demo.sh
similarity index 96%
rename from demos/network_agent/run_demo.sh
rename to demos/use_cases/ollama/run_demo.sh
index e6c678e8..eb47dce6 100644
--- a/demos/network_agent/run_demo.sh
+++ b/demos/use_cases/ollama/run_demo.sh
@@ -22,7 +22,7 @@ start_demo() {
echo "Starting Arch with arch_config.yaml..."
archgw up arch_config.yaml
- # Step 4: Start Network Agent
+ # Step 4: Start developer services
echo "Starting Network Agent using Docker Compose..."
docker compose up -d # Run in detached mode
}
diff --git a/demos/use_cases/spotify_bearer_auth/README.md b/demos/use_cases/spotify_bearer_auth/README.md
new file mode 100644
index 00000000..7dd3c81e
--- /dev/null
+++ b/demos/use_cases/spotify_bearer_auth/README.md
@@ -0,0 +1,31 @@
+# Use Case Demo: Bearer Authorization with Spotify APIs
+
+In this demo, we show how you can use Arch's bearer authorization capability to connect your agentic apps to third-party APIs.
+More specifically, we demonstrate how you can connect to two Spotify APIs:
+
+- [`/v1/browse/new-releases`](https://developer.spotify.com/documentation/web-api/reference/get-new-releases)
+- [`/v1/artists/{artist_id}/top-tracks`](https://developer.spotify.com/documentation/web-api/reference/get-an-artists-top-tracks)
+
+Where users can engage by asking questions like _"Show me the latest releases in the US"_, followed by queries like _"Show me top tracks from Taylor Swift"_.
+
+
+
+## Starting the demo
+
+1. Ensure the [prerequisites](https://github.com/katanemo/arch/?tab=readme-ov-file#prerequisites) are installed correctly.
+2. Create an `.env` file with API keys for OpenAI and Spotify.
+ - Sign up for an OpenAI API key at [https://platform.openai.com/signup/](https://platform.openai.com/signup/)
+ - Sign up for a Spotify Client Key/Secret by following instructions at [https://developer.spotify.com/dashboard/](https://developer.spotify.com/dashboard/)
+ - Generate a Spotify token using the [https://accounts.spotify.com/api/token API](https://accounts.spotify.com/api/token), using ```curl``` or similar commands.
+ - Create a .env file with the following keys:
+ ```
+ OPENAI_API_KEY=your_openai_api_key
+ SPOTIFY_CLIENT_KEY=your_spotify_api_token
+ ```
+
+3. Start Arch
+ ```sh
+ sh run_demo.sh
+ ```
+4. Navigate to http://localhost:18080
+5. Ask "show me new album releases in the US"
diff --git a/demos/use_cases/spotify_bearer_auth/arch_config.yaml b/demos/use_cases/spotify_bearer_auth/arch_config.yaml
new file mode 100644
index 00000000..a259a539
--- /dev/null
+++ b/demos/use_cases/spotify_bearer_auth/arch_config.yaml
@@ -0,0 +1,122 @@
+version: v0.1
+listener:
+ address: 127.0.0.1
+ port: 8080 #If you configure port 443, you'll need to update the listener with tls_certificates
+ message_format: huggingface
+
+overrides:
+ optimize_context_window: true
+
+endpoints:
+ spotify:
+ endpoint: api.spotify.com
+ protocol: https
+
+system_prompt: |
+ I have the following JSON data representing a list of albums from Spotify:
+
+ {
+ "items": [
+ {
+ "album_type": "album",
+ "artists": [
+ {
+ "external_urls": {
+ "spotify": "https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02"
+ },
+ "href": "https://api.spotify.com/v1/artists/06HL4z0CvFAxyc27GXpf02",
+ "id": "06HL4z0CvFAxyc27GXpf02",
+ "name": "Taylor Swift",
+ "type": "artist",
+ "uri": "spotify:artist:06HL4z0CvFAxyc27GXpf02"
+ }
+ ],
+ "available_markets": [ /* ... markets omitted for brevity ... */ ],
+ "external_urls": {
+ "spotify": "https://open.spotify.com/album/1Mo4aZ8pdj6L1jx8zSwJnt"
+ },
+ "href": "https://api.spotify.com/v1/albums/1Mo4aZ8pdj6L1jx8zSwJnt",
+ "id": "1Mo4aZ8pdj6L1jx8zSwJnt",
+ "images": [
+ {
+ "height": 300,
+ "url": "https://i.scdn.co/image/ab67616d00001e025076e4160d018e378f488c33",
+ "width": 300
+ },
+ {
+ "height": 64,
+ "url": "https://i.scdn.co/image/ab67616d000048515076e4160d018e378f488c33",
+ "width": 64
+ },
+ {
+ "height": 640,
+ "url": "https://i.scdn.co/image/ab67616d0000b2735076e4160d018e378f488c33",
+ "width": 640
+ }
+ ],
+ "name": "THE TORTURED POETS DEPARTMENT",
+ "release_date": "2024-04-18",
+ "release_date_precision": "day",
+ "total_tracks": 16,
+ "type": "album",
+ "uri": "spotify:album:1Mo4aZ8pdj6L1jx8zSwJnt"
+ }
+ ]
+ }
+
+ Please convert this JSON into Markdown with the following layout for each album:
+
+ - Display the album image (using Markdown image syntax) first.
+ - On the next line immediately after the image, display the album title, artist name (use the first artist listed), and the release date, all separated by a hyphen or another clear delimiter.
+ - On the next line, provide the Spotify link (using Markdown link syntax).
+
+ For example, the output should look similar to this (using the data above):
+
+ 
+ **THE TORTURED POETS DEPARTMENT**
+ Taylor Swift - 2024-04-18
+ [Listen on Spotify](https://open.spotify.com/album/1Mo4aZ8pdj6L1jx8zSwJnt)
+ Arist Id: 06HL4z0CvFAxyc27GXpf02
+
+
+ Make sure your output is valid Markdown. And don't say "formatted in Markdown". Thanks!
+
+llm_providers:
+ - name: openai
+ provider_interface: openai
+ access_key: $OPENAI_API_KEY
+ model: gpt-4o
+ default: true
+
+prompt_targets:
+ - name: get_new_releases
+ description: Get a list of new album releases featured in Spotify (shown, for example, on a Spotify player’s “Browse” tab).
+ parameters:
+ - name: country
+ description: the country where the album is released
+ required: true
+ type: str
+ in_path: true
+ - name: limit
+ type: integer
+ description: The maximum number of results to return
+ default: "5"
+ endpoint:
+ name: spotify
+ path: /v1/browse/new-releases
+ http_headers:
+ Authorization: "Bearer $SPOTIFY_CLIENT_KEY"
+
+ - name: get_artist_top_tracks
+ description: Get information about an artist's top tracks
+ parameters:
+ - name: artist_id
+ description: The ID of the artist.
+ required: true
+ type: str
+ in_path: true
+ endpoint:
+ name: spotify
+ path: /v1/artists/{artist_id}/top-tracks
+ http_headers:
+ Authorization: "Bearer $SPOTIFY_CLIENT_KEY"
diff --git a/demos/use_cases/spotify_bearer_auth/docker-compose.yaml b/demos/use_cases/spotify_bearer_auth/docker-compose.yaml
new file mode 100644
index 00000000..ee5465a5
--- /dev/null
+++ b/demos/use_cases/spotify_bearer_auth/docker-compose.yaml
@@ -0,0 +1,21 @@
+services:
+ chatbot_ui:
+ build:
+ context: ../../shared/chatbot_ui
+ ports:
+ - "18080:8080"
+ environment:
+ # this is only because we are running the sample app in the same docker container environemtn as archgw
+ - CHAT_COMPLETION_ENDPOINT=http://host.docker.internal:10000/v1
+ extra_hosts:
+ - "host.docker.internal:host-gateway"
+ volumes:
+ - ./arch_config.yaml:/app/arch_config.yaml
+
+ jaeger:
+ build:
+ context: ../../shared/jaeger
+ ports:
+ - "16686:16686"
+ - "4317:4317"
+ - "4318:4318"
diff --git a/demos/use_cases/spotify_bearer_auth/run_demo.sh b/demos/use_cases/spotify_bearer_auth/run_demo.sh
new file mode 100644
index 00000000..eb47dce6
--- /dev/null
+++ b/demos/use_cases/spotify_bearer_auth/run_demo.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+set -e
+
+# Function to start the demo
+start_demo() {
+ # Step 1: Check if .env file exists
+ if [ -f ".env" ]; then
+ echo ".env file already exists. Skipping creation."
+ else
+ # Step 2: Create `.env` file and set OpenAI key
+ if [ -z "$OPENAI_API_KEY" ]; then
+ echo "Error: OPENAI_API_KEY environment variable is not set for the demo."
+ exit 1
+ fi
+
+ echo "Creating .env file..."
+ echo "OPENAI_API_KEY=$OPENAI_API_KEY" > .env
+ echo ".env file created with OPENAI_API_KEY."
+ fi
+
+ # Step 3: Start Arch
+ echo "Starting Arch with arch_config.yaml..."
+ archgw up arch_config.yaml
+
+ # Step 4: Start developer services
+ echo "Starting Network Agent using Docker Compose..."
+ docker compose up -d # Run in detached mode
+}
+
+# Function to stop the demo
+stop_demo() {
+ # Step 1: Stop Docker Compose services
+ echo "Stopping Network Agent using Docker Compose..."
+ docker compose down
+
+ # Step 2: Stop Arch
+ echo "Stopping Arch..."
+ archgw down
+}
+
+# Main script logic
+if [ "$1" == "down" ]; then
+ stop_demo
+else
+ # Default action is to bring the demo up
+ start_demo
+fi
diff --git a/demos/use_cases/spotify_bearer_auth/spotify_bearer_auth.png b/demos/use_cases/spotify_bearer_auth/spotify_bearer_auth.png
new file mode 100644
index 00000000..3111d47f
Binary files /dev/null and b/demos/use_cases/spotify_bearer_auth/spotify_bearer_auth.png differ
diff --git a/docs/source/build_with_arch/multi_turn.rst b/docs/source/build_with_arch/multi_turn.rst
index 3ff5e6da..3bb31002 100644
--- a/docs/source/build_with_arch/multi_turn.rst
+++ b/docs/source/build_with_arch/multi_turn.rst
@@ -80,7 +80,7 @@ Once the prompt targets are configured as above, handle parameters across multi-
Demo App
~~~~~~~~
-For your convenience, we've built a `demo app `_
+For your convenience, we've built a `demo app `_
that you can test and modify locally for multi-turn RAG scenarios.
.. figure:: includes/multi_turn/mutli-turn-example.png
diff --git a/docs/source/conf.py b/docs/source/conf.py
index be9db942..3ea0822c 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -15,7 +15,7 @@ from sphinxawesome_theme.postprocess import Icons
project = "Arch Docs"
copyright = "2025, Katanemo Labs, Inc"
author = "Katanemo Labs, Inc"
-release = " v0.2.0"
+release = " v0.2.1"
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
diff --git a/docs/source/get_started/quickstart.rst b/docs/source/get_started/quickstart.rst
index 5363f817..268bf45d 100644
--- a/docs/source/get_started/quickstart.rst
+++ b/docs/source/get_started/quickstart.rst
@@ -25,7 +25,7 @@ Arch's CLI allows you to manage and interact with the Arch gateway efficiently.
$ python -m venv venv
$ source venv/bin/activate # On Windows, use: venv\Scripts\activate
- $ pip install archgw==0.2.0
+ $ pip install archgw==0.2.1
Build AI Agent with Arch Gateway
diff --git a/model_server/pyproject.toml b/model_server/pyproject.toml
index e9b2dc0e..397b58fb 100644
--- a/model_server/pyproject.toml
+++ b/model_server/pyproject.toml
@@ -1,6 +1,6 @@
[tool.poetry]
name = "archgw_modelserver"
-version = "0.2.0"
+version = "0.2.1"
description = "A model server for serving models"
authors = ["Katanemo Labs, Inc "]
license = "Apache 2.0"
diff --git a/model_server/src/commons/globals.py b/model_server/src/commons/globals.py
index 68c2e53a..2f533024 100644
--- a/model_server/src/commons/globals.py
+++ b/model_server/src/commons/globals.py
@@ -15,7 +15,7 @@ logger = get_model_server_logger()
# Define the client
-ARCH_ENDPOINT = os.getenv("ARCH_ENDPOINT", "https://api.fc.archgw.com/v1")
+ARCH_ENDPOINT = os.getenv("ARCH_ENDPOINT", "https://archfc.katanemo.dev/v1")
ARCH_API_KEY = "EMPTY"
ARCH_CLIENT = OpenAI(base_url=ARCH_ENDPOINT, api_key=ARCH_API_KEY)
diff --git a/model_server/src/core/function_calling.py b/model_server/src/core/function_calling.py
index 25c83818..99dd29ba 100644
--- a/model_server/src/core/function_calling.py
+++ b/model_server/src/core/function_calling.py
@@ -134,7 +134,7 @@ class ArchIntentHandler(ArchBaseHandler):
req.messages, req.tools, self.extra_instruction
)
- logger.info(f"[request]: {json.dumps(messages)}")
+ logger.info(f"[request to arch-fc (intent)]: {json.dumps(messages)}")
model_response = self.client.chat.completions.create(
messages=messages,
@@ -519,9 +519,11 @@ class ArchFunctionHandler(ArchBaseHandler):
"""
logger.info("[Arch-Function] - ChatCompletion")
- messages = self._process_messages(req.messages, req.tools)
+ messages = self._process_messages(
+ req.messages, req.tools, metadata=req.metadata
+ )
- logger.info(f"[request]: {json.dumps(messages)}")
+ logger.info(f"[request to arch-fc]: {json.dumps(messages)}")
# always enable `stream=True` to collect model responses
response = self.client.chat.completions.create(
diff --git a/model_server/src/core/guardrails.py b/model_server/src/core/guardrails.py
index 0d2f34fc..fae4e5ba 100644
--- a/model_server/src/core/guardrails.py
+++ b/model_server/src/core/guardrails.py
@@ -105,7 +105,7 @@ class ArchGuardHanlder:
raise NotImplementedError(f"{req.task} is not supported!")
logger.info("[Arch-Guard] - Prediction")
- logger.info(f"[request]: {req.input}")
+ logger.info(f"[request arch-guard]: {req.input}")
if len(req.input.split()) < max_num_words:
result = self._predict_text(req.task, req.input)
diff --git a/model_server/src/core/utils/model_utils.py b/model_server/src/core/utils/model_utils.py
index d971d115..7dc71acf 100644
--- a/model_server/src/core/utils/model_utils.py
+++ b/model_server/src/core/utils/model_utils.py
@@ -16,6 +16,7 @@ class Message(BaseModel):
class ChatMessage(BaseModel):
messages: List[Message] = []
tools: List[Dict[str, Any]] = []
+ metadata: Optional[Dict[str, str]] = {}
class Choice(BaseModel):
@@ -123,6 +124,7 @@ class ArchBaseHandler:
tools: List[Dict[str, Any]] = None,
extra_instruction: str = None,
max_tokens=4096,
+ metadata: Dict[str, str] = {},
):
"""
Processes a list of messages and formats them appropriately.
@@ -157,7 +159,12 @@ class ArchBaseHandler:
content = f"\n{json.dumps(tool_calls[0]['function'])}\n "
elif role == "tool":
role = "user"
- content = f"\n{json.dumps(content)}\n "
+ if metadata.get("optimize_context_window", "false").lower() == "true":
+ content = f"\n\n "
+ else:
+ content = (
+ f"\n{json.dumps(content)}\n "
+ )
processed_messages.append({"role": role, "content": content})
diff --git a/model_server/src/main.py b/model_server/src/main.py
index 74f60011..683d6227 100644
--- a/model_server/src/main.py
+++ b/model_server/src/main.py
@@ -4,7 +4,7 @@ import time
import logging
import src.commons.utils as utils
-from src.commons.globals import handler_map
+from src.commons.globals import ARCH_ENDPOINT, handler_map
from src.core.utils.model_utils import (
ChatMessage,
ChatCompletionResponse,
@@ -51,6 +51,8 @@ logging.getLogger("opentelemetry.exporter.otlp.proto.grpc.exporter").setLevel(
app = FastAPI()
FastAPIInstrumentor().instrument_app(app)
+logger.info(f"using archfc endpoint: {ARCH_ENDPOINT}")
+
@app.get("/healthz")
async def healthz():
diff --git a/tests/e2e/docker-compose.yaml b/tests/e2e/docker-compose.yaml
index 0bf9ccd3..53b4338d 100644
--- a/tests/e2e/docker-compose.yaml
+++ b/tests/e2e/docker-compose.yaml
@@ -8,7 +8,7 @@ services:
- "12000:12000"
- "19901:9901"
volumes:
- - ../../demos/weather_forecast/arch_config.yaml:/app/arch_config.yaml
+ - ../../demos/samples_python/weather_forecast/arch_config.yaml:/app/arch_config.yaml
- /etc/ssl/cert.pem:/etc/ssl/cert.pem
- ~/archgw_logs:/var/log/
extra_hosts:
diff --git a/tests/e2e/run_e2e_tests.sh b/tests/e2e/run_e2e_tests.sh
index e288e30b..c87af4f8 100644
--- a/tests/e2e/run_e2e_tests.sh
+++ b/tests/e2e/run_e2e_tests.sh
@@ -26,7 +26,7 @@ log starting > ../build.log
log building and running function_callling demo
log ===========================================
-cd ../../demos/weather_forecast/
+cd ../../demos/samples_python/weather_forecast/
docker compose up weather_forecast_service --build -d
cd -
@@ -53,7 +53,7 @@ cd ../../
tail -F ~/archgw_logs/modelserver.log &
model_server_tail_pid=$!
archgw down
-archgw up demos/weather_forecast/arch_config.yaml
+archgw up demos/samples_python/weather_forecast/arch_config.yaml
kill $model_server_tail_pid
cd -
@@ -68,6 +68,6 @@ archgw down
log shutting down the weather_forecast demo
log =======================================
-cd ../../demos/weather_forecast
+cd ../../demos/samples_python/weather_forecast
docker compose down
cd -
diff --git a/tests/rest/api_model_server.rest b/tests/rest/api_model_server.rest
index ed86fac3..3e5d2f47 100644
--- a/tests/rest/api_model_server.rest
+++ b/tests/rest/api_model_server.rest
@@ -1,6 +1,5 @@
@model_server_endpoint = http://localhost:51000
-@archfc_endpoint = https://api.fc.archgw.com
-
+@archfc_endpoint = https://archfc.katanemo.dev
### talk to function calling endpoint
POST {{model_server_endpoint}}/function_calling HTTP/1.1
@@ -119,7 +118,7 @@ Content-Type: application/json
}
### talk to Arch-Intent directly for completion
-POST {{archfc_endpoint}}/v1/chat/completions HTTP/1.1
+POST {{{{archfc_endpoint}}}}/v1/chat/completions HTTP/1.1
Content-Type: application/json
{
diff --git a/tests/rest/insurance_agent.rest b/tests/rest/insurance_agent.rest
index 225c7d8a..c45ebb85 100644
--- a/tests/rest/insurance_agent.rest
+++ b/tests/rest/insurance_agent.rest
@@ -1,5 +1,5 @@
@model_server_endpoint = http://localhost:51000
-@archfc_endpoint = https://api.fc.archgw.com
+@archfc_endpoint = https://archfc.katanemo.dev
### multi turn conversation with intent, except parameter gathering
@@ -55,7 +55,7 @@ Content-Type: application/json
]
}
### talk to Arch-Intent directly for completion
-POST https://api.fc.archgw.com/v1/chat/completions HTTP/1.1
+POST https://archfc.katanemo.dev/v1/chat/completions HTTP/1.1
Content-Type: application/json
{
@@ -126,7 +126,7 @@ Content-Type: application/json
]
}
### talk to Arch-Intent directly for completion, expect No
-POST https://api.fc.archgw.com/v1/chat/completions HTTP/1.1
+POST https://archfc.katanemo.dev/v1/chat/completions HTTP/1.1
Content-Type: application/json
{
diff --git a/tests/rest/network_agent.rest b/tests/rest/network_agent.rest
index 319b5106..dc03fa6c 100644
--- a/tests/rest/network_agent.rest
+++ b/tests/rest/network_agent.rest
@@ -1,5 +1,5 @@
@model_server_endpoint = http://localhost:51000
-@archfc_endpoint = https://api.fc.archgw.com
+@archfc_endpoint = https://archfc.katanemo.dev
### single turn function calling all parameters insurance agent summary