mirror of
https://github.com/hoshikawa2/agent_platform_oci.git
synced 2026-09-07 10:13:46 +00:00
bugfix: aofertas
This commit is contained in:
@@ -0,0 +1,195 @@
|
|||||||
|
###############################################################################
|
||||||
|
# AI AGENT PLATFORM - CONFIGURAÇÃO ÚNICA
|
||||||
|
# Este arquivo é lido por Pydantic Settings no framework e no backend template.
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
APP_NAME=ai-agent-template
|
||||||
|
APP_ENV=local
|
||||||
|
LOG_LEVEL=INFO
|
||||||
|
API_HOST=0.0.0.0
|
||||||
|
API_PORT=8000
|
||||||
|
CORS_ORIGINS=http://localhost:5173,http://127.0.0.1:5173
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# LLM - OCI Generative AI como provider principal
|
||||||
|
###############################################################################
|
||||||
|
# Opções: mock, oci_openai, oci_sdk, openai_compatible
|
||||||
|
LLM_PROVIDER=oci_openai
|
||||||
|
LLM_TEMPERATURE=0.2
|
||||||
|
LLM_MAX_TOKENS=2048
|
||||||
|
LLM_TIMEOUT_SECONDS=120
|
||||||
|
|
||||||
|
# OCI OpenAI-compatible endpoint
|
||||||
|
OCI_GENAI_BASE_URL=https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/openai/v1
|
||||||
|
OCI_GENAI_MODEL=openai.gpt-4.1
|
||||||
|
OCI_GENAI_API_KEY=sk-ph3FgX6ph3FgX6ph3FgX6ph3FgX6ph3FgX6ph3FgX6
|
||||||
|
OCI_GENAI_PROJECT_OCID=
|
||||||
|
|
||||||
|
# OCI SDK / signer / profiles
|
||||||
|
OCI_CONFIG_FILE=~/.oci/config
|
||||||
|
OCI_PROFILE=DEFAULT
|
||||||
|
OCI_COMPARTMENT_ID=ocid1.compartment.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
OCI_REGION=us-chicago-1
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Persistência
|
||||||
|
###############################################################################
|
||||||
|
# Opções: memory, autonomous, mongodb
|
||||||
|
SESSION_REPOSITORY_PROVIDER=sqlite
|
||||||
|
MEMORY_REPOSITORY_PROVIDER=sqlite
|
||||||
|
CHECKPOINT_REPOSITORY_PROVIDER=sqlite
|
||||||
|
SQLITE_DB_PATH=./data/agent_framework.db
|
||||||
|
|
||||||
|
# Autonomous Database
|
||||||
|
ADB_USER=admin
|
||||||
|
ADB_PASSWORD=fjhsdf04954hf
|
||||||
|
ADB_DSN=oradb23aidev_high
|
||||||
|
ADB_WALLET_LOCATION=/ORACLE/DEFAULT/Wallet_ORADB23aiDev
|
||||||
|
ADB_WALLET_PASSWORD=fjhsdf04954hf
|
||||||
|
ADB_TABLE_PREFIX=AGENTFW
|
||||||
|
|
||||||
|
# MongoDB - também pode representar Autonomous usando API compatível com Mongo, se habilitada no ambiente
|
||||||
|
MONGODB_URI=mongodb://mongo:mongopassword@localhost:27017
|
||||||
|
MONGODB_DATABASE=agent_platform
|
||||||
|
|
||||||
|
# Redis
|
||||||
|
REDIS_URL=redis://localhost:6379/0
|
||||||
|
ENABLE_REDIS_CACHE=false
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# RAG / Vector / Graph
|
||||||
|
###############################################################################
|
||||||
|
VECTOR_STORE_PROVIDER=sqlite
|
||||||
|
GRAPH_STORE_PROVIDER=sqlite
|
||||||
|
RAG_TOP_K=5
|
||||||
|
EMBEDDING_PROVIDER=mock
|
||||||
|
OCI_EMBEDDING_MODEL=cohere.embed-multilingual-v3.0
|
||||||
|
RAG_FILE_GLOBS=*.md,*.txt,*.yaml,*.yml,*.json
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Observabilidade
|
||||||
|
###############################################################################
|
||||||
|
ENABLE_LANGFUSE=true
|
||||||
|
LANGFUSE_TRACE_MODE=compact # Opcional: verbose, compact
|
||||||
|
LANGFUSE_PUBLIC_KEY=pk-lf-2f9da109-5b0f-4c78-b61d-9598ed787eba
|
||||||
|
LANGFUSE_SECRET_KEY=sk-lf-a4cb0cdd-f2ea-4468-9911-cebeb91ba944
|
||||||
|
LANGFUSE_HOST=http://localhost:3005
|
||||||
|
ENABLE_OTEL=false
|
||||||
|
OTEL_EXPORTER_OTLP_ENDPOINT=
|
||||||
|
OTEL_SERVICE_NAME=ai-agent-template
|
||||||
|
ENABLE_LANGFUSE_OPENAI_AUTO_INSTRUMENTATION=true
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Analytics / Observer corporativo
|
||||||
|
###############################################################################
|
||||||
|
# Quando true, AgentObserver publica eventos IC.*, NOC.* e GRL.* nos providers abaixo.
|
||||||
|
ENABLE_ANALYTICS=false
|
||||||
|
# Providers aceitos: oci_streaming,pubsub,noop
|
||||||
|
ANALYTICS_PROVIDERS=pubsub
|
||||||
|
# Compatibilidade FIRST/TIM: pode informar AGENT_PUBSUB_TOPIC diretamente.
|
||||||
|
AGENT_PUBSUB_TOPIC=
|
||||||
|
GCP_PUBSUB_TOPIC_PATH=
|
||||||
|
GCP_PROJECT_ID=
|
||||||
|
GCP_PUBSUB_TOPIC=
|
||||||
|
GCP_PUBSUB_TIMEOUT_SECONDS=30
|
||||||
|
# Credencial GCP segue padrão Google:
|
||||||
|
# GOOGLE_APPLICATION_CREDENTIALS=/secrets/gcp-service-account.json
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# OCI Streaming
|
||||||
|
###############################################################################
|
||||||
|
ENABLE_OCI_STREAMING=false
|
||||||
|
OCI_STREAM_ENDPOINT=
|
||||||
|
OCI_STREAM_OCID=
|
||||||
|
OCI_STREAM_PARTITION_KEY=agent-events
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Guardrails, Judges, Supervisor
|
||||||
|
###############################################################################
|
||||||
|
ENABLE_INPUT_GUARDRAILS=true
|
||||||
|
ENABLE_OUTPUT_GUARDRAILS=true
|
||||||
|
ENABLE_JUDGES=true
|
||||||
|
ENABLE_SUPERVISOR=true
|
||||||
|
ENABLE_OUTPUT_SUPERVISOR=true
|
||||||
|
ENABLE_PARALLEL_GUARDRAILS=true
|
||||||
|
GUARDRAILS_FAIL_FAST=true
|
||||||
|
OUTPUT_SUPERVISOR_MAX_RETRIES=3
|
||||||
|
GUARDRAILS_CONFIG_PATH=./config/guardrails.yaml
|
||||||
|
JUDGES_CONFIG_PATH=./config/judges.yaml
|
||||||
|
PROMPT_POLICY_PATH=./config/prompt_policy.yaml
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Gateway de canais
|
||||||
|
###############################################################################
|
||||||
|
DEFAULT_CHANNEL=web
|
||||||
|
# embedded = backend may parse simple/native channel payloads.
|
||||||
|
# external = backend only accepts GatewayRequest normalized by an external Channel Gateway.
|
||||||
|
FRAMEWORK_CHANNEL_INPUT_MODE=embedded
|
||||||
|
ENABLE_VOICE_ADAPTER=true
|
||||||
|
ENABLE_WHATSAPP_ADAPTER=true
|
||||||
|
ENABLE_TEXT_ADAPTER=true
|
||||||
|
|
||||||
|
#################################################
|
||||||
|
# ENTERPRISE ROUTING
|
||||||
|
#################################################
|
||||||
|
# Arquivo YAML com intents, keywords, políticas de estado e fallback.
|
||||||
|
ROUTING_CONFIG_PATH=./config/routing.yaml
|
||||||
|
# true = usa LLM para classificar quando keywords/estado não resolverem.
|
||||||
|
# Em produção, costuma ser útil; em desenvolvimento, false evita custo e latência.
|
||||||
|
ENABLE_LLM_ROUTER=true
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# MCP / Tools
|
||||||
|
###############################################################################
|
||||||
|
ENABLE_MCP_TOOLS=true
|
||||||
|
MCP_SERVERS_CONFIG_PATH=./config/mcp_servers.yaml
|
||||||
|
TOOLS_CONFIG_PATH=./config/tools.yaml
|
||||||
|
TOOL_POLICIES_PATH=./config/tool_policies.yaml
|
||||||
|
MCP_TOOL_TIMEOUT_SECONDS=30
|
||||||
|
|
||||||
|
# router = EnterpriseRouter seleciona um agente; supervisor = pode acionar múltiplos agentes
|
||||||
|
ROUTING_MODE=router
|
||||||
|
|
||||||
|
# Usage/cost accounting
|
||||||
|
USAGE_REPOSITORY_PROVIDER=sqlite
|
||||||
|
IDENTITY_CONFIG_PATH=./config/identity.yaml
|
||||||
|
MCP_PARAMETER_MAPPING_PATH=./config/mcp_parameter_mapping.yaml
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# ConversationSummaryMemory / compressão de contexto conversacional
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
ENABLE_CONVERSATION_SUMMARY_MEMORY=true
|
||||||
|
MEMORY_CONTEXT_STRATEGY=summary
|
||||||
|
MEMORY_HISTORY_LIMIT=80
|
||||||
|
MEMORY_RECENT_MESSAGES_LIMIT=8
|
||||||
|
MEMORY_SUMMARY_TRIGGER_MESSAGES=20
|
||||||
|
MEMORY_MAX_SUMMARY_CHARS=6000
|
||||||
|
MEMORY_SUMMARY_USE_LLM=true
|
||||||
|
MEMORY_INJECT_RECENT_MESSAGES=true
|
||||||
|
MEMORY_INJECT_SUMMARY=true
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# MCP Gateway
|
||||||
|
###############################################################################
|
||||||
|
# true = framework routes tool calls to the dedicated MCP Gateway.
|
||||||
|
# false = framework calls MCP servers directly from mcp_servers.yaml.
|
||||||
|
MCP_GATEWAY_ENABLED=true
|
||||||
|
MCP_GATEWAY_URL=http://localhost:8300
|
||||||
|
MCP_GATEWAY_TIMEOUT_SECONDS=60
|
||||||
|
# MCP_GATEWAY_TOKEN=
|
||||||
|
MCP_GATEWAY_AGENT_ID=telecom_contas
|
||||||
|
MCP_GATEWAY_TENANT_ID=default
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# LONG-TERM MEMORY
|
||||||
|
###############################################################################
|
||||||
|
ENABLE_LONG_TERM_MEMORY=true
|
||||||
|
LONG_TERM_MEMORY_PROVIDER=sqlite
|
||||||
|
LONG_TERM_MEMORY_SQLITE_PATH=./data/agent_framework.db
|
||||||
|
LONG_TERM_MEMORY_TABLE=agentfw_long_term_memory
|
||||||
|
# For Autonomous/Oracle, defaults to ${ADB_TABLE_PREFIX}_LONG_TERM_MEMORY
|
||||||
|
# LONG_TERM_MEMORY_ORACLE_TABLE=AGENTFW_LONG_TERM_MEMORY
|
||||||
|
LONG_TERM_MEMORY_MAX_CONTEXT_ITEMS=20
|
||||||
|
LONG_TERM_MEMORY_MIN_CONFIDENCE=0.70
|
||||||
|
LONG_TERM_MEMORY_AUTO_EXTRACT=true
|
||||||
|
LONG_TERM_MEMORY_INJECT_CONTEXT=true
|
||||||
@@ -74,6 +74,16 @@ def _format_conversation_history(
|
|||||||
msgs.pop()
|
msgs.pop()
|
||||||
lines: list[str] = []
|
lines: list[str] = []
|
||||||
for msg in msgs:
|
for msg in msgs:
|
||||||
|
if isinstance(msg, dict):
|
||||||
|
role = str(msg.get("role") or msg.get("type") or "").lower()
|
||||||
|
if role in {"system", "tool", "function"}:
|
||||||
|
continue
|
||||||
|
if role == "human":
|
||||||
|
role = "user"
|
||||||
|
elif role in {"ai", "bot"}:
|
||||||
|
role = "assistant"
|
||||||
|
content = _message_content_to_str(msg.get("content", ""))
|
||||||
|
else:
|
||||||
cls = type(msg).__name__
|
cls = type(msg).__name__
|
||||||
if cls in _SKIPPED_CLASSES:
|
if cls in _SKIPPED_CLASSES:
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -48,6 +48,10 @@ Decida na ordem, PARE no primeiro match:
|
|||||||
casa aqui, siga para o passo 5.
|
casa aqui, siga para o passo 5.
|
||||||
Vale o pedido generico ("quero cancelar", "todos") sobre o que a conversa
|
Vale o pedido generico ("quero cancelar", "todos") sobre o que a conversa
|
||||||
trata, e vale confirmar ou pedir permissao para executar essa acao.
|
trata, e vale confirmar ou pedir permissao para executar essa acao.
|
||||||
|
IMPORTANTE: se o cliente acabou de PEDIR cancelamento/contestacao/ajuste do
|
||||||
|
mesmo alvo, a fala do agente que apenas pede CONFIRMACAO da transacao e
|
||||||
|
allowed=true. A confirmacao NAO precisa repetir a justificativa do cliente
|
||||||
|
("nao reconheco", "esta caro" etc.); o pedido transacional anterior basta.
|
||||||
Vale tambem trocar uma variante transacional por outra DA MESMA FAMILIA sobre
|
Vale tambem trocar uma variante transacional por outra DA MESMA FAMILIA sobre
|
||||||
o MESMO escopo, sempre limitada ao valor JA COBRADO no item (ressarcimento <->
|
o MESMO escopo, sempre limitada ao valor JA COBRADO no item (ressarcimento <->
|
||||||
devolucao <-> reembolso <-> cancelamento <-> credito em fatura): negar o dobro e
|
devolucao <-> reembolso <-> cancelamento <-> credito em fatura): negar o dobro e
|
||||||
|
|||||||
64
tests/unit/test_langgraph_checkpoint_runtime_config.py
Normal file
64
tests/unit/test_langgraph_checkpoint_runtime_config.py
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
from types import SimpleNamespace
|
||||||
|
|
||||||
|
from agent_framework.checkpoints.langgraph_saver import (
|
||||||
|
RepositoryCheckpointSaver,
|
||||||
|
_durable_config,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class _Repo:
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self.saved = None
|
||||||
|
|
||||||
|
async def put(self, thread_id, checkpoint):
|
||||||
|
self.saved = (thread_id, checkpoint)
|
||||||
|
|
||||||
|
async def get_latest(self, thread_id):
|
||||||
|
return self.saved[1] if self.saved and self.saved[0] == thread_id else None
|
||||||
|
|
||||||
|
|
||||||
|
def test_private_pregel_runtime_is_not_durable() -> None:
|
||||||
|
config = {
|
||||||
|
"tags": ["x"],
|
||||||
|
"configurable": {
|
||||||
|
"thread_id": "t1",
|
||||||
|
"tenant": "default",
|
||||||
|
"__pregel_runtime": "stringified-runtime",
|
||||||
|
"__pregel_store": "stringified-store",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
cleaned = _durable_config(config)
|
||||||
|
|
||||||
|
assert cleaned == {
|
||||||
|
"tags": ["x"],
|
||||||
|
"configurable": {"thread_id": "t1", "tenant": "default"},
|
||||||
|
}
|
||||||
|
assert "__pregel_runtime" in config["configurable"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_saver_strips_private_runtime_before_put_and_restore() -> None:
|
||||||
|
repo = _Repo()
|
||||||
|
saver = RepositoryCheckpointSaver(SimpleNamespace(), repository=repo)
|
||||||
|
config = {
|
||||||
|
"configurable": {
|
||||||
|
"thread_id": "t1",
|
||||||
|
"__pregel_runtime": "Runtime(...) persisted by JSON backend",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkpoint = {"id": "cp1", "v": 1}
|
||||||
|
|
||||||
|
returned = asyncio.run(saver.aput(config, checkpoint, {}, {}))
|
||||||
|
assert returned["configurable"] == {"thread_id": "t1", "checkpoint_id": "cp1"}
|
||||||
|
assert repo.saved is not None
|
||||||
|
persisted = repo.saved[1]
|
||||||
|
assert "__pregel_runtime" not in persisted["config"]["configurable"]
|
||||||
|
|
||||||
|
# Also protects legacy records already stored with a stringified runtime.
|
||||||
|
persisted["config"]["configurable"]["__pregel_runtime"] = "legacy-string"
|
||||||
|
restored = saver._make_tuple(persisted)
|
||||||
|
restored_config = restored.config if hasattr(restored, "config") else restored["config"]
|
||||||
|
assert "__pregel_runtime" not in restored_config["configurable"]
|
||||||
Reference in New Issue
Block a user