Home Playground Docs hub

Guide G-13 · Applied Intelligence

Choosing Evergreen vs Bella vs Chloe

Verified against local · 2026-09-23 · evergreen-ai-service 3.0.1 (workspace HEAD), chloe (workspace HEAD)
Journey. As a developer, I need an AI feature — but which of the
platform's three AI surfaces do I call? This guide maps the decision, then
shows the one call that defines each surface.

The platform offers three ways to get model intelligence, all backed by the same Evergreen AI model fleet:

SurfaceWhat it isYou bringBest for
Evergreen AI (session console)A conversation you configure: model-selection criteria, generation parameters, RAG grounding, streamingSession criteria and message flowBuilt-in AI features in your product — chat, document Q&A, multimodal pipelines
Bella (predefined sessions)The same session machinery, pre-tuned: an optimized system prompt and model pick loaded from a templateA template id and messagesProduct-ready assistants (support personas, reviewers, companions) without prompt engineering
Chloe (reasoning API)An OpenAI-compatible endpoint that plans how much reasoning a prompt deserves and spends accordinglyOne question per callHard questions where answer quality matters more than per-call latency — analysis, comparison, judgment calls

The short version: Evergreen when you want control, Bella when you want a tuned assistant without the tuning, Chloe when one shot must be as good as it can be within a budget. All three share the platform's auth (guide G-01) and model governance; none of them require you to host anything.

Concepts (only what this journey needs)

a session, exchange messages over it (history is server-side), and delete it when done. Chloe is one-shot: every call is self-contained — send messages, get the answer, nothing to clean up.

selection_criteria (capability filters the service resolves to a model — see G-10). A predefined session replaces that whole block with one template id; the template's author already made the choices.

deep, maximum, default auto) trades latency/cost against answer depth. Higher effort means more deliberation before the answer comes back — choose per call, not per integration.

Path A — Evergreen AI: the configurable session

The full lifecycle (create → chat → stream → history → delete) is guide G-10; the one call that defines this surface is session creation with your criteria:

bash
curl -s -X POST "${EVG_URL}/v3/sessions" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "x-api-key: ${INAYA_API_KEY}" \
  -H "x-client-app-key: ${INAYA_APP_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "required_modalities": ["Text"],
    "selection_criteria": [
      { "MinContextWindowLength": { "optionality": "MustHave", "length": 32768 } }
    ],
    "temperature": 0.2
  }'

Expected response — 200 with an ai_session_id you then address with the chat calls from G-10.

TIP

Add "use_rag": { "collection_id": "…" } to the creation body and the session grounds its answers in your own documents — see G-11.

Path B — Bella: the predefined session

Same session machinery, one template id instead of a criteria block. Templates ship with the platform (e.g. igentic.bella.v1 — the Bella assistant persona) or with your tenant's deployment; the id is the JSON file name in the predefined-sessions folder, minus .json:

bash
curl -s -X POST "${EVG_URL}/v3/sessions/pre-defined" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "x-api-key: ${INAYA_API_KEY}" \
  -H "x-client-app-key: ${INAYA_APP_KEY}" \
  -H "Content-Type: application/json" \
  -d '{ "predefined_session_id": "'"${PREDEFINED_SESSION_ID}"'" }'
python
import json, os, urllib.request

req = urllib.request.Request(
    f"{os.environ['EVG_URL']}/v3/sessions/pre-defined",
    data=json.dumps({
        "predefined_session_id": os.environ["PREDEFINED_SESSION_ID"],
    }).encode(),
    headers={
        "Content-Type": "application/json",
        "Authorization": f"Bearer {os.environ['TOKEN']}",
        "x-api-key": os.environ["INAYA_API_KEY"],
        "x-client-app-key": os.environ["INAYA_APP_KEY"],
    },
)
print(json.dumps(json.load(urllib.request.urlopen(req, timeout=60)), indent=2))

Expected response — 200 with the same ai_session_id shape as Path A; from here, chat/stream/history/delete work exactly as in G-10. Overlay fields (temperature, history_ttl_in_seconds, …) may be sent alongside the id to adjust the template per session.

NOTE

A template can only start if its pinned model is actually available. The shipped templates pin cloud models; the local stack ships a docs template (inayalabs.docsdemo.v1, pinning the local Qwen3_VL_4B_Q4) so this path is exercisable offline. 404 means template or its model not found.

Path C — Chloe: the reasoning endpoint

One call, no session. The request is shaped like an OpenAI chat completion; effort is the budget knob:

bash
curl -s -X POST "${CHLOE_URL}/v3/chloe/chat/completions" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "x-api-key: ${INAYA_API_KEY}" \
  -H "x-client-app-key: ${INAYA_APP_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "chloe",
    "messages": [ { "role": "user", "content": "Which is the better trade-off for a logging library: structured JSON or plain text? Two sentences." } ],
    "effort": "balanced"
  }'

Expected response — 200 with an OpenAI-compatible body: choices[0].message.content is the answer, plus a deliberation block recording what the request cost (latency, estimated unit cost, effort honored). Treat deliberation as telemetry, not input. Roles system and developer are accepted for steering; stream is not yet supported — omit it. Evergreen unreachable → 503.

NOTE

Verified manual: the request/response contract, auth (401 without a JWT), and validation errors (400 for stream: true, empty messages, unsupported roles) were all exercised live, but the happy-path answer requires a model fleet member tagged with a maturity level — no locally-managed model carries one yet, so Chloe's profiles find no candidate on the local stack (the call fails with a gateway 404, surfaced as 503). On deployed environments with mature cloud models in the fleet, the same call answers normally.

Full working example

Both session paths in one script (which_surface.sh) — it fetches a user JWT via the QA shortcut first (local/QA environments only; production uses the G-01 flows):

bash
#!/usr/bin/env bash
set -euo pipefail

# 0. Obtain a user JWT (QA shortcut — see G-01 for production flows)
TOKEN=$(curl -sf -X POST "${AUTH_URL}/v3/auth/qa/login" \
  -H "Content-Type: application/json" \
  -H "x-api-key: ${INAYA_API_KEY}" \
  -H "x-client-app-key: ${INAYA_APP_KEY}" \
  -d "{\"device_id\": \"g13-demo-device\", \"locale\": \"en-US\", \"tenant_id\": \"${TENANT_ID}\", \"username\": \"g13-demo\"}" \
  | python3 -c 'import json,sys; print(json.load(sys.stdin)["token"])')
AUTH=(-H "Authorization: Bearer ${TOKEN}"
      -H "x-api-key: ${INAYA_API_KEY}"
      -H "x-client-app-key: ${INAYA_APP_KEY}")

# 1. Path B — predefined session (Bella path)
SESSION_ID=$(curl -sf -X POST "${EVG_URL}/v3/sessions/pre-defined" "${AUTH[@]}" \
  -H "Content-Type: application/json" \
  -d "{\"predefined_session_id\": \"${PREDEFINED_SESSION_ID}\"}" \
  | python3 -c 'import json,sys; print(json.load(sys.stdin)["ai_session_id"])')
echo "predefined session: ${SESSION_ID}"

# 2. Chat on it, then clean up (same calls as G-10)
curl -sf --max-time 300 -X POST "${EVG_URL}/v3/sessions/${SESSION_ID}/chat-messages" \
  "${AUTH[@]}" -F "user_message=Say hello in exactly three words." \
  | python3 -c 'import json,sys; d=json.load(sys.stdin); print("reply:", d["content"][0]["Text"][:40], "| model:", d["model_name"])'
curl -sf -o /dev/null -w "session delete: %{http_code}\n" -X DELETE "${EVG_URL}/v3/sessions/${SESSION_ID}" "${AUTH[@]}"

(AUTH_URL is the Auth Service — http://127.0.0.1:40004; EVG_URL is Evergreen AI — http://127.0.0.1:40071. PREDEFINED_SESSION_ID is inayalabs.docsdemo.v1 on the local stack, a shipped template id like igentic.bella.v1 in deployed environments.)

Try it live

Open the Playground → Applied Intelligence: Evergreen AI · Session Console for Path A, or the Our AI Models family for Bella and Chloe chat UIs — same surfaces, running against live services.

Copy agent prompt

Agent prompt — copy and hand to your agent
You are helping pick between the Inaya Labs AI surfaces. Evergreen AI
(${EVG_URL}) creates configurable sessions (POST /v3/sessions with
selection_criteria — see guide G-10). Predefined sessions (Bella path) start
with POST /v3/sessions/pre-defined and a predefined_session_id such as
igentic.bella.v1. Chloe (${CHLOE_URL}) answers one-shot questions via POST
/v3/chloe/chat/completions with an OpenAI-style messages array and an effort
budget knob (fast|balanced|deep|maximum|auto). Steps: (1) start a predefined
session using PREDEFINED_SESSION_ID from env; report the ai_session_id.
(2) Send "Say hello in exactly three words." via POST
/v3/sessions/<id>/chat-messages (multipart field user_message); report the
reply text and model_name. (3) DELETE /v3/sessions/<id>. Never log the JWT.

API reference

Next journeys