Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 58 additions & 39 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,8 @@ See also `datasource_memory_protocol` for Mnemos note format.
AION_LTM_WAKE_MAX_ROWS=20
AION_MNEMOS_RECALL_LIMIT=10
AION_MNEMOS_NATIVE_TOOLS=1
# Ranking fusion: RRF + recency/importance boosts
AION_MNEMOS_READONLY_TOOLS=0
AION_MNEMOS_RECALL_LIMIT_EXPOSED=1
AION_MNEMOS_RANK_HALF_LIFE_DAYS=90
AION_MNEMOS_RANK_W_RECENCY=0.3
AION_MNEMOS_RANK_W_IMPORTANCE=0.2
Expand Down Expand Up @@ -464,8 +465,11 @@ AION_MCP_USER_HOME_ISOLATION=1
AION_MCP_OAUTH_DYNAMIC_REGISTRATION=1
# Margine (secondi) prima della scadenza per refresh automatico del token OAuth (default 60)
AION_OAUTH_TOKEN_EXPIRY_BUFFER_SECONDS=60
# URL base redirect OAuth (default: AION_FASTAPI_URL + /v1/integrations/oauth/callback)
# AION_OAUTH_REDIRECT_BASE_URL=http://localhost:8001
# URL base assoluto per OAuth MCP (obbligatorio in Docker con NEXT_PUBLIC_AION_API_URL=/api).
# Deve essere l'URL browser-facing dietro Caddy (…/api), NON la porta interna uvicorn :8001.
# Esempio produzione: https://cliente.example.com/api
# Esempio locale Caddy :8066: http://thinkstation:8066/api
# AION_OAUTH_REDIRECT_BASE_URL=https://cliente.example.com/api

# -----------------------------------------------------------------------------
# Agent DB MCP (SQLite per utente) — mcp_servers/agent_db/server.py, ltm_notifier.py,
Expand Down Expand Up @@ -542,16 +546,29 @@ AION_WEB_FETCH_MAX_CHARS=24000
# PDF evidence crop (MCP pdf_evidence_crop on ocr server) — Word report screenshots
# AION_PDF_EVIDENCE_DPI=200
# AION_PDF_EVIDENCE_MAX_WHITE_RATIO=0.90
# Con AION_TOOL_OFFLOAD_ENABLED=1: cap estrazione pagina su disco (default ~min(bytes/2, 250k))
# AION_WEB_FETCH_OFFLOAD_MAX_CHARS=200000
# Formato risultati tool web nel contesto LLM: toon (default, -30/60% token) | json
# AION_TOOL_RESULT_FORMAT=toon
AION_TOOL_RESULT_FORMAT=toon
# Regex su URL completo; vuoto = nessun filtro (usa solo in ambienti controllati)
AION_WEB_FETCH_ALLOWLIST_REGEX=
# 1 = tenta StealthyFetcher Scrapling dopo Fetcher/httpx (richiede scrapling[fetchers] + browser)
AION_SCRAPLING_STEALTH_ENABLED=0
# Profondità Tavily: basic | advanced | fast | ultra-fast
AION_TAVILY_SEARCH_DEPTH=basic
# Cap tool result in agent context (NOT page extract — see AION_WEB_FETCH_MAX_CHARS)
AION_TOOL_WEB_FETCH_MAX_CHARS=48000
AION_TOOL_WEB_SEARCH_MAX_CHARS=12000
# Snippet length in TOON web_search rows (single-line; default 1200)
AION_TOON_WEB_SEARCH_SNIPPET_CHARS=1200
# Compact anticipato dopo N web_search/web_fetch (prima del 92% globale)
AION_WEB_TOOL_COMPACT_AFTER=4
# Con AION_TOOL_OFFLOAD_ENABLED=1: cap estrazione pagina su disco
AION_WEB_FETCH_OFFLOAD_MAX_CHARS=200000
AION_TOOL_CIRCUIT_BREAKER_ENABLED=1
AION_WIKIPEDIA_EXTRACT_FALLBACK_MIN_CHARS=2000
AION_WIKIPEDIA_FETCH_MODE=article
AION_CHROMA_SHARED_EMBEDDING_CACHE=1
# Set by migrate_mempalace_to_mnemos_env.py after legacy MemPalace removal
# AION_MEMORY_STACK=mnemos

# -----------------------------------------------------------------------------
# API client URLs (chat-ui SSR, upload, download)
Expand Down Expand Up @@ -720,13 +737,13 @@ AION_TOOL_RESULT_MAX_CHARS=24000
# AION_TURN_DIAGNOSTICS_LOG=data/diagnostics/turns.jsonl
# AION_AGENT_DEBUG_LOG=data/diagnostics/agent-debug.jsonl

# Harness v2 (Pi-inspired patterns) — tutti default off per rollout graduale
# AION_HARNESS_V2_MESSAGES=1
# AION_HARNESS_V2_INJECTIONS=1
# AION_HARNESS_V2_COMPACTION=1
# AION_HARNESS_V2_PROVIDER=1
# AION_HARNESS_V2_TOOLS=1
# AION_HARNESS_V2_TURN=1
# Harness v2 (Pi-inspired patterns) — default on for new installs
AION_HARNESS_V2_MESSAGES=1
AION_HARNESS_V2_INJECTIONS=1
AION_HARNESS_V2_COMPACTION=1
AION_HARNESS_V2_PROVIDER=1
AION_HARNESS_V2_TOOLS=1
AION_HARNESS_V2_TURN=1

# Long Run mode (Pi agent runtime via services/pi-long-run worker)
# AION_LONG_RUN_ENABLED=0
Expand Down Expand Up @@ -885,7 +902,9 @@ AION_ENV=dev
# AION_CURRENT_PROFILE_SLUG=
# URL pubblico admin-ui per i banner Chainlit; vuoto = usa default in-code.
AION_ADMIN_UI_URL=http://localhost:3870
# URL pubblico del chat-ui (per redirect OAuth dopo autenticazione utente)
# URL pubblico del chat-ui (per redirect OAuth dopo autenticazione utente).
# In Docker/prod usare il dominio browser-facing, NON localhost:8003:
# AION_CHAT_URL=https://cliente.example.com
AION_CHAT_URL=http://localhost:8003
# Override base URL OAuth MCP integrations (default: derivato da AION_CHAT_URL)
# AION_OAUTH_REDIRECT_BASE_URL=
Expand Down Expand Up @@ -984,43 +1003,43 @@ AION_AGENT_DB_EMBED_SECRET=
# -----------------------------------------------------------------------------
# Optimizer (dataset di valutazione) — src/optimizer/
# -----------------------------------------------------------------------------
# --- Benchmark harness (eval + LongMemEval-V2) ---
# --- Benchmark harness (eval + LongMemEval-V2) — not written to prod .env by setup ---
AION_BENCHMARK_DATA_DIR=data/benchmarks
AION_BENCHMARK_VERBOSE=1
AION_BENCHMARK_SUBPROCESS_PYTHON=python
AION_LME_V2_TIER=small
AION_LME_V2_TEXT_ONLY=1
AION_LME_V2_JUDGE_PROFILE=aion_std
AION_LME_V2_DOWNLOAD_SCREENSHOTS=0
AION_LME_V2_MAX_TRAJECTORIES=100
# AION_LME_V2_TIER=small
# AION_LME_V2_TEXT_ONLY=1
# AION_LME_V2_JUDGE_PROFILE=aion_std
# AION_LME_V2_DOWNLOAD_SCREENSHOTS=0
# AION_LME_V2_MAX_TRAJECTORIES=100
# 0 = unlimited (full retention — benchmark default via apply_benchmark_isolation_env)
AION_LME_V2_MAX_STATES_PER_TRAJ=0
AION_LME_V2_MAX_TREE_CHARS=0
AION_LME_V2_MAX_CHUNKS_PER_TRAJ=0
AION_LME_V2_BOILERPLATE_THRESHOLD=0.6
AION_LME_V2_INGEST_BATCH_SIZE=500
AION_LME_V2_COMPRESS_SCOPE=0
AION_LME_V2_AGENT_PROFILE=benchmark_memory
AION_LME_V2_SKIP_IMAGE_QUESTIONS=1
# AION_LME_V2_MAX_STATES_PER_TRAJ=0
# AION_LME_V2_MAX_TREE_CHARS=0
# AION_LME_V2_MAX_CHUNKS_PER_TRAJ=0
# AION_LME_V2_BOILERPLATE_THRESHOLD=0.6
# AION_LME_V2_INGEST_BATCH_SIZE=500
# AION_LME_V2_COMPRESS_SCOPE=0
# AION_LME_V2_AGENT_PROFILE=benchmark_memory
# AION_LME_V2_SKIP_IMAGE_QUESTIONS=1
# Max non-menuitem UI labels per state (menuitems are always kept — answers hide in dropdowns)
AION_LME_V2_UI_LABEL_LIMIT=80
# AION_LME_V2_UI_LABEL_LIMIT=80
# Max chars per Mnemos note at ingest (Mnemos CONTENT_MAX_CHARS is 500)
AION_LME_V2_NOTE_MAX_CHARS=480
# AION_LME_V2_NOTE_MAX_CHARS=480
# FTS recall rows merged per benchmark question (boosted query + full text)
AION_LME_V2_RECALL_LIMIT=20
# AION_LME_V2_RECALL_LIMIT=20
# Skip Mnemos wake block during QA (reduces noise from unrelated early trajectories)
AION_LME_V2_SKIP_WAKE=1
AION_LME_V2_QA_MAX_TOKENS=512
AION_LME_V2_QA_TIMEOUT=120
# AION_LME_V2_SKIP_WAKE=1
# AION_LME_V2_QA_MAX_TOKENS=512
# AION_LME_V2_QA_TIMEOUT=120
# Qwen3/vLLM: MUST stay 1 for benchmark judge (0 => thinking on => content=null)
AION_LME_V2_QA_DISABLE_REASONING=1
# AION_LME_V2_QA_DISABLE_REASONING=1
# Official scoring: 156/451 questions carry eval_function=llm_*_checker and need
# an LLM grader. Set 0 to score them 0.0 without any LLM call (offline runs).
AION_LME_V2_LLM_JUDGE=1
AION_LME_V2_JUDGE_MAX_TOKENS=16
AION_LME_V2_JUDGE_TIMEOUT=60
# AION_LME_V2_LLM_JUDGE=1
# AION_LME_V2_JUDGE_MAX_TOKENS=16
# AION_LME_V2_JUDGE_TIMEOUT=60
# Benchmark agent + Mnemos (set automatically by apply_benchmark_isolation_env)
AION_MNEMOS_READONLY_TOOLS=1
# AION_MNEMOS_READONLY_TOOLS=1
AION_MNEMOS_RECALL_LIMIT_EXPOSED=1
AION_OPTUNA_STORAGE=sqlite:///data/optuna.db

Expand Down
12 changes: 11 additions & 1 deletion admin-ui/lib/mcpOAuthSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,18 @@ export type ConnectorOAuthSetupHints = {
scopes: string[];
};

function absoluteApiBase(): string {
const base = apiBase();
if (/^https?:\/\//i.test(base)) return base;
if (typeof window !== "undefined") {
const path = base.startsWith("/") ? base : `/${base}`;
return `${window.location.origin}${path}`;
}
return base;
}

export function defaultOAuthRedirectUri(): string {
return `${apiBase()}/v1/integrations/oauth/callback`;
return `${absoluteApiBase().replace(/\/$/, "")}/v1/integrations/oauth/callback`;
}

export function connectorOAuthSetupHints(
Expand Down
4 changes: 2 additions & 2 deletions chat-ui/components/integrations/CredentialConfigDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useMemo, useState } from "react";
import { Plug, Plus, X } from "lucide-react";

import type { CredentialField, Integration } from "@/components/integrations/types";
import { apiBase } from "@/lib/config";
import { apiBase, oauthCallbackRedirectUri } from "@/lib/config";
import { jsonHeaders } from "@/lib/api/aion";
import { oauthManagedFieldKeys, oauthProviderDisplayName } from "@/lib/integrations/oauthLabels";
import { useT } from "@/lib/i18n/use-t";
Expand Down Expand Up @@ -73,7 +73,7 @@ export function CredentialConfigDialog({
}

async function handleOAuthLogin() {
const redirectUri = `${apiBase()}/v1/integrations/oauth/callback`;
const redirectUri = oauthCallbackRedirectUri();
try {
const res = await fetch(
`${apiBase()}/v1/integrations/oauth/start?server_slug=${encodeURIComponent(integration.server_slug)}&redirect_uri=${encodeURIComponent(redirectUri)}`,
Expand Down
15 changes: 15 additions & 0 deletions chat-ui/lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,21 @@ export function apiBase(): string {
return "http://localhost:8001";
}

/** Same-origin absolute API base (required for OAuth redirect_uri when apiBase() is `/api`). */
export function absoluteApiBase(): string {
const base = apiBase();
if (/^https?:\/\//i.test(base)) return base;
if (typeof window !== "undefined") {
const path = base.startsWith("/") ? base : `/${base}`;
return `${window.location.origin}${path}`;
}
return base;
}

export function oauthCallbackRedirectUri(): string {
return `${absoluteApiBase().replace(/\/$/, "")}/v1/integrations/oauth/callback`;
}

export function adminUiBase(): string {
return (process.env.NEXT_PUBLIC_AION_ADMIN_UI_URL || "http://localhost:3870").replace(/\/$/, "");
}
2 changes: 1 addition & 1 deletion config_std/mcp_registry.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ grafana:
memory:
command: "python"
args: ["-u", "query_memory/server.py"]
description: "Database di conoscenza e cache query verificate"
description: "QueryMemory (SQL/PromQL cache) + session_search — NOT Mnemos LTM (use native memory_* tools)"

code:
command: "python"
Expand Down
1 change: 1 addition & 0 deletions config_std/profiles/generic_assistant.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ skills:
critical_skills:
- core_protocol
- artifact_protocol
- memory_protocol
- web_research_protocol
- incremental_execution_protocol
native_tool_groups:
Expand Down
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ services:
# Local default (DOMAIN non valorizzato): http://localhost via Caddy su :80.
# In prod sovrascrivere nel .env: AION_PUBLIC_API_URL=https://${DOMAIN}/api
AION_PUBLIC_API_URL: ${AION_PUBLIC_API_URL:-http://localhost/api}
# OAuth callback base (browser-facing). Defaults to AION_PUBLIC_API_URL when absolute.
AION_OAUTH_REDIRECT_BASE_URL: ${AION_OAUTH_REDIRECT_BASE_URL:-${AION_PUBLIC_API_URL:-http://localhost/api}}
AION_CORS_ORIGINS: ${AION_CORS_ORIGINS:-*}
# Root path per il reverse proxy: Caddy strippa /api, root_path glielo
# restituisce per generare URL corretti nello schema OpenAPI / Swagger UI.
Expand Down
3 changes: 3 additions & 0 deletions docker/Caddyfile
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
write_timeout 0
response_header_timeout 0
}
header_up Host {host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Prefix /api
}
}
Expand Down
4 changes: 4 additions & 0 deletions docker/Dockerfile.backend
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ COPY --from=uv-bin /uv /uvx /usr/local/bin/

WORKDIR /app

# mcp-remote proxy for remote-bridge MCP servers (ClickUp, Notion, GitHub Copilot, …)
COPY docker/package.mcp-remote.json ./package.json
RUN npm install --omit=dev

# Application code (runtime dirs config/ and mcp_servers/ come from sync at boot)
COPY src/ ./src/
COPY mcp_servers_std/ ./mcp_servers_std/
Expand Down
8 changes: 8 additions & 0 deletions docker/package.mcp-remote.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"private": true,
"name": "aion-mcp-remote-deps",
"description": "mcp-remote stdio proxy for remote-bridge MCP servers (ClickUp, Notion, …)",
"dependencies": {
"mcp-remote": "^0.1.38"
}
}
Loading