Commit 033dded8 authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Integrate Agentic ingress with WebUI

parent 8b2672a5
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -340,6 +340,14 @@ for COMPONENT in $TFS_COMPONENTS; do
        sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT:${VERSION}#image: $IMAGE_URL#g" "$MANIFEST"
    fi

    if [ "$COMPONENT" == "webui" ] && [[ "$TFS_COMPONENTS" == *"agentic"* ]]; then
        sed -E -i '/value: "\/webui\/"/ a\
            - name: AGENTICSERVICE_SERVICE_HOST\
              value: "agenticservice"\
            - name: AGENTICSERVICE_SERVICE_PORT_HTTP\
              value: "8800"' "$MANIFEST"
    fi

    sed -E -i "s#imagePullPolicy: .*#imagePullPolicy: Always#g" "$MANIFEST"

    # TODO: harmonize names of the monitoring component
+1 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ metadata:
data:
  ADK_MODEL: "openai/gpt-4.1-mini"
  ADK_AGENT_GRAPH: "single"
  ADK_HTTP_ROOT_PATH: "/agentic"
  ADK_DOMAIN_ID: "A"
  ADK_DOMAIN_NAME: "domain-a"
  ADK_PEERS: ""
+13 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ DEFAULT_AGENTIC_SPECTRUM_DB_PATH = "/var/lib/tfs-agentic/adk_spectrum.sqlite"
DEFAULT_AGENTIC_A2A_TIMEOUT_SECONDS = "180"
DEFAULT_AGENTIC_DEFAULT_SLOT_WIDTH = "16"
DEFAULT_AGENTIC_DOMAIN_API_PORT = "8800"
DEFAULT_AGENTIC_HTTP_ROOT_PATH = "/agentic"
DEFAULT_AGENTIC_MCP_STARTUP_WARMUP_TIMEOUT_SECONDS = "10"
DEFAULT_AGENTIC_MCP_TOOL_TIMEOUT_SECONDS = "30"
DEFAULT_AGENTIC_RUN_TIMEOUT_SECONDS = "120"
@@ -50,6 +51,7 @@ ENVVAR_ADK_A2A_PUBLIC_URL = "ADK_A2A_PUBLIC_URL"
ENVVAR_ADK_A2A_TIMEOUT_SECONDS = "ADK_A2A_TIMEOUT_SECONDS"
ENVVAR_ADK_DEFAULT_SLOT_WIDTH = "ADK_DEFAULT_SLOT_WIDTH"
ENVVAR_ADK_DOMAIN_API_PORT = "ADK_DOMAIN_API_PORT"
ENVVAR_ADK_HTTP_ROOT_PATH = "ADK_HTTP_ROOT_PATH"
ENVVAR_ADK_MODEL = "ADK_MODEL"
ENVVAR_ADK_AGENT_GRAPH = "ADK_AGENT_GRAPH"
ENVVAR_ADK_DOMAIN_ID = "ADK_DOMAIN_ID"
@@ -201,6 +203,17 @@ def get_agentic_domain_api_port() -> int:
    )


def get_agentic_http_root_path() -> str:
    root_path = get_setting(
        ENVVAR_ADK_HTTP_ROOT_PATH,
        default=DEFAULT_AGENTIC_HTTP_ROOT_PATH,
    )
    root_path = root_path.strip().rstrip("/")
    if not root_path:
        return ""
    return root_path if root_path.startswith("/") else f"/{root_path}"


def get_agentic_graph_normalized() -> str:
    return get_agentic_graph().strip().lower() or DEFAULT_AGENTIC_GRAPH

+61 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ Server components are available:
```bash
cd ~/tfs-ctrl
TFS_COMPONENTS="context device pathcomp opticalcontroller service nbi webui mcp_server agentic" \
TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml" \
CRDB_DROP_DATABASE_IF_EXISTS=YES \
./deploy/all.sh
```
@@ -38,6 +39,13 @@ The deployment manifest creates:
- `agenticservice`: HTTP service on port `8800`.
- `tfs-ingress-agentic`: ingress path `/agentic`.

When WebUI and Agentic are both selected in `TFS_COMPONENTS`, the TFS WebUI
navigation bar exposes an `Agentic` entry. The link opens the Agentic service
root through `/agentic`, which redirects to the generated FastAPI
documentation under `/agentic/docs`.
Expose the WebUI ingress with `manifests/nginx_ingress_http.yaml` to reach the
TFS WebUI through `/webui/`.

Do not commit real LLM API keys, MCP tokens, SSH keys, or controller
credentials. Patch secrets at deployment time:

@@ -62,6 +70,8 @@ Main settings:
- `ADK_MODEL`: LLM model identifier. Default is `openai/gpt-4.1-mini`.
- `ADK_AGENT_GRAPH`: agent graph to run. Default is `single`; `granular` is
  kept for debugging and fallback.
- `ADK_HTTP_ROOT_PATH`: HTTP prefix used when Agentic is exposed behind the
  TFS ingress. Default is `/agentic`.
- `ADK_DOMAIN_ID`: short domain identifier such as `A`.
- `ADK_DOMAIN_NAME`: human-readable domain name such as `domain-a`.
- `ADK_PEERS`: comma-separated peer map in the form
@@ -131,6 +141,19 @@ The component source is split into:
`GET /health` returns component health, local domain ID, peer summary, session
database health, and startup warm-up results.

`GET /` redirects to the generated Agentic API documentation. Through the TFS
ingress this is reachable as:

```text
http://<controller-host>/agentic
```

or directly as:

```text
http://<controller-host>/agentic/docs
```

`POST /agent/run` receives operator-facing natural-language requests:

```bash
@@ -165,6 +188,44 @@ Diagnostic endpoints are also available for direct workflow tests:
Prefer `/agent/run` for operator-facing validation. Use direct diagnostic
endpoints only for integration tests and failure isolation.

## Google ADK WebUI

Google ADK WebUI is intended for development and debugging of the agent graph.
The production TFS component runs the Agentic FastAPI service on port `8800`;
it does not start `adk web` as a second long-running process.

The package exposes `agentic.agent:root_agent` so ADK Web can discover the
same root agent used by the service. From a development checkout with the
Agentic dependencies installed, start ADK Web from the directory containing the
`agentic` package:

```bash
cd ~/tfs-ctrl/src
PYTHONPATH=. adk web --host 0.0.0.0 --port 8000
```

Then open:

```text
http://<development-host>:8000
```

and select the `agentic` app. Use the same environment variables documented
above, especially `ADK_MODEL`, `OPENAI_API_KEY`, `TFS_MCP_URL`, `ADK_DOMAIN_ID`,
`ADK_PEERS`, and the session/spectrum database paths.

For Kubernetes debugging, run ADK Web in a temporary debug pod or side process
using the same image and environment as `agenticservice`, then expose or
port-forward its port:

```bash
kubectl -n tfs port-forward deployment/agenticservice 8800:8800
```

The command above exposes the production Agentic API locally as
`http://127.0.0.1:8800`. If a separate ADK Web debug process is started on port
`8000`, port-forward that process instead and open `http://127.0.0.1:8000`.

## Smoke Tests

After deployment, check health:

src/agentic/agent.py

0 → 100644
+17 −0
Original line number Diff line number Diff line
# Copyright 2022-2026 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from agentic.service.agent import root_agent

__all__ = ("root_agent",)
Loading