oskaragent 0.1.38a0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- oskaragent/__init__.py +49 -0
- oskaragent/agent.py +1911 -0
- oskaragent/agent_config.py +328 -0
- oskaragent/agent_mcp_tools.py +102 -0
- oskaragent/agent_tools.py +962 -0
- oskaragent/helpers.py +175 -0
- oskaragent-0.1.38a0.dist-info/METADATA +29 -0
- oskaragent-0.1.38a0.dist-info/RECORD +30 -0
- oskaragent-0.1.38a0.dist-info/WHEEL +5 -0
- oskaragent-0.1.38a0.dist-info/licenses/LICENSE +21 -0
- oskaragent-0.1.38a0.dist-info/top_level.txt +2 -0
- tests/1a_test_basico.py +43 -0
- tests/1b_test_history.py +72 -0
- tests/1c_test_basico.py +61 -0
- tests/2a_test_tool_python.py +50 -0
- tests/2b_test_tool_calculator.py +54 -0
- tests/2c_test_tool_savefile.py +50 -0
- tests/3a_test_upload_md.py +46 -0
- tests/3b_test_upload_img.py +43 -0
- tests/3c_test_upload_pdf_compare.py +44 -0
- tests/4_test_RAG.py +56 -0
- tests/5_test_MAS.py +58 -0
- tests/6a_test_MCP_tool_CRM.py +77 -0
- tests/6b_test_MCP_tool_ITSM.py +72 -0
- tests/6c_test_MCP_tool_SQL.py +69 -0
- tests/6d_test_MCP_tool_DOC_SQL.py +45 -0
- tests/7a_test_BI_CSV.py +37 -0
- tests/7b_test_BI_SQL.py +47 -0
- tests/8a_test_external_tool.py +194 -0
- tests/helpers.py +60 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from oskaragent.agent import Oskar
|
|
7
|
+
from oskaragent.agent_config import AgentConfig
|
|
8
|
+
from tests.helpers import set_key
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def main() -> None:
|
|
12
|
+
# Set OpenAI API key
|
|
13
|
+
set_key()
|
|
14
|
+
|
|
15
|
+
# Caminho do arquivo de imagem a ser descrito
|
|
16
|
+
img_path = (Path(__file__).parent / "sources" / "img_pent.png").resolve()
|
|
17
|
+
if not img_path.exists():
|
|
18
|
+
raise FileNotFoundError(f"Arquivo não encontrado: {img_path}")
|
|
19
|
+
|
|
20
|
+
# Instancia o agente oskaragent (configuração simples)
|
|
21
|
+
agent_cfg = AgentConfig(
|
|
22
|
+
model_settings={
|
|
23
|
+
"history_window_size": 5, # parametrizável
|
|
24
|
+
},
|
|
25
|
+
)
|
|
26
|
+
agent = Oskar(agent_config=agent_cfg, is_verbose=False)
|
|
27
|
+
|
|
28
|
+
# Pergunta ao agente para descrever a imagem
|
|
29
|
+
question = "Descreva a imagem anexada em detalhes em português."
|
|
30
|
+
result: dict[str, Any] = agent.answer(
|
|
31
|
+
question=question,
|
|
32
|
+
attached_files=str(img_path)
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
# Extrai e imprime o conteúdo da resposta (descrição)
|
|
36
|
+
content = (result or {}).get("content") or ""
|
|
37
|
+
print("Descrição gerada:\n")
|
|
38
|
+
print(content)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
if __name__ == "__main__":
|
|
42
|
+
main()
|
|
43
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from oskaragent.agent import Oskar
|
|
7
|
+
from oskaragent.agent_config import AgentConfig
|
|
8
|
+
|
|
9
|
+
from tests.helpers import set_key
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def main() -> None:
|
|
13
|
+
# Set OpenAI API key
|
|
14
|
+
set_key()
|
|
15
|
+
|
|
16
|
+
# Caminho dos arquivos pdf para comparação
|
|
17
|
+
pdf1_path = Path("sources/GlobalThreatReport2024.pdf").resolve()
|
|
18
|
+
if not pdf1_path.exists():
|
|
19
|
+
raise FileNotFoundError(f"Arquivo não encontrado: {pdf1_path}")
|
|
20
|
+
|
|
21
|
+
pdf2_path = Path("sources/comptia-state-of-cybersecurity-2025.pdf").resolve()
|
|
22
|
+
if not pdf2_path.exists():
|
|
23
|
+
raise FileNotFoundError(f"Arquivo não encontrado: {pdf2_path}")
|
|
24
|
+
|
|
25
|
+
# Instancia o agente oskaragent (com configurações padrão)
|
|
26
|
+
agent = Oskar(agent_config=AgentConfig(), is_verbose=True)
|
|
27
|
+
|
|
28
|
+
# Pergunta ao agente para fazer um resumo do arquivo
|
|
29
|
+
question = "Faça uma análise comparativa desses dois documentos PDF e apresente o resultado em português."
|
|
30
|
+
|
|
31
|
+
result: dict[str, Any] = agent.answer(
|
|
32
|
+
question=question,
|
|
33
|
+
attached_files=[str(pdf1_path), str(pdf2_path)]
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
# Extrai e imprime o conteúdo da resposta (resumo)
|
|
37
|
+
content = (result or {}).get("content") or ""
|
|
38
|
+
print("Resumo gerado:\n")
|
|
39
|
+
print(content)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
if __name__ == "__main__":
|
|
43
|
+
main()
|
|
44
|
+
|
tests/4_test_RAG.py
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from tests.helpers import set_key
|
|
6
|
+
from oskaragent.agent import Oskar
|
|
7
|
+
from oskaragent.agent_config import AgentConfig
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def main() -> None:
|
|
11
|
+
"""Execute smoke test forcing local RAG retriever against the psicologia base."""
|
|
12
|
+
# Set OpenAI API key
|
|
13
|
+
set_key()
|
|
14
|
+
|
|
15
|
+
# cria a base de dados RAG
|
|
16
|
+
# create_knowledge_base_from_file(knowledge_base_name="psicologia",
|
|
17
|
+
# knowledge_base_folder="./sources/vectorstore",
|
|
18
|
+
# file_path="./sources/artigo psicologia.md")
|
|
19
|
+
|
|
20
|
+
# Configura o agente para usar o índice local de RAG
|
|
21
|
+
ag_cfg = AgentConfig(
|
|
22
|
+
knowledge_base=[
|
|
23
|
+
{
|
|
24
|
+
"name": "psicologia",
|
|
25
|
+
"folder": "./sources/vectorstore"
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
# Observação: para habilitar o retriever local, também é possível
|
|
29
|
+
# informar `working_dbs=["./sources/vectorstore"]`. Aqui seguimos exatamente o pedido.
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
# Ativar logs detalhados para ver chamadas de ferramenta (inclui logs azuis)
|
|
33
|
+
agent = Oskar(agent_config=ag_cfg, is_verbose=True)
|
|
34
|
+
|
|
35
|
+
question = "Quantas sessões foram realizadas?"
|
|
36
|
+
# Força o uso do RAG local chamando explicitamente a ferramenta de recuperação
|
|
37
|
+
# Caso prefira deixar o modelo decidir, use action="chat".
|
|
38
|
+
result: dict[str, Any] = agent.answer(
|
|
39
|
+
question=question,
|
|
40
|
+
action="tool:retriever_tool",
|
|
41
|
+
message_format="raw",
|
|
42
|
+
is_consult_prompt=False,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# Imprime apenas o conteúdo textual da resposta
|
|
46
|
+
content = (result or {}).get("content")
|
|
47
|
+
if content:
|
|
48
|
+
print(content)
|
|
49
|
+
else:
|
|
50
|
+
# Fallback: imprime o objeto completo para facilitar o debug
|
|
51
|
+
import json as _json
|
|
52
|
+
print(_json.dumps(result or {}, ensure_ascii=False, indent=2))
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
if __name__ == "__main__":
|
|
56
|
+
main()
|
tests/5_test_MAS.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
import json
|
|
5
|
+
|
|
6
|
+
from tests.helpers import set_key
|
|
7
|
+
from oskaragent.agent import Oskar
|
|
8
|
+
from oskaragent.agent_config import AgentConfig
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _response_log(assistant_message_struct: dict[str, Any]):
|
|
12
|
+
usage = assistant_message_struct.get("usage", {}) or {}
|
|
13
|
+
print(
|
|
14
|
+
f"[callback] message_id={assistant_message_struct.get('message_id')} "
|
|
15
|
+
f"tokens={{'input_tokens': {usage.get('input_tokens')}, 'output_tokens': {usage.get('output_tokens')}, 'total_tokens': {usage.get('total_tokens')}}}"
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def main() -> int:
|
|
20
|
+
# Set OpenAI API key
|
|
21
|
+
set_key()
|
|
22
|
+
|
|
23
|
+
# ------------- agente subordinado
|
|
24
|
+
ag_cfg = AgentConfig(
|
|
25
|
+
agent_id="AssistenteOskar",
|
|
26
|
+
agent_name="Assistente do oskaragent",
|
|
27
|
+
system_prompt="""
|
|
28
|
+
Você conhece todos os colaboradores da empresa.
|
|
29
|
+
Quando for perguntado, você informar o cargo de qualquer um deles.
|
|
30
|
+
Segue a lista dos colaboradores:
|
|
31
|
+
- José Carlos: Programador
|
|
32
|
+
- Elisa: Gerente de Financeiro
|
|
33
|
+
- Jacques: Diretor
|
|
34
|
+
- Maria: Analista de BI
|
|
35
|
+
""",
|
|
36
|
+
)
|
|
37
|
+
agent_assistente = Oskar(agent_config=ag_cfg, response_callback=_response_log, is_verbose=True)
|
|
38
|
+
|
|
39
|
+
# ------------- agente orquestrador
|
|
40
|
+
ag_cfg = AgentConfig(
|
|
41
|
+
agent_name="Chefe",
|
|
42
|
+
model_settings={"history_window_size": 5},
|
|
43
|
+
)
|
|
44
|
+
agent_chefe = Oskar(agent_config=ag_cfg, response_callback=_response_log, is_verbose=True)
|
|
45
|
+
|
|
46
|
+
agent_chefe.add_subordinated_agent(agent_assistente,
|
|
47
|
+
role="Conhece todos os colaboradores da empresa e pode informar o cargo de qualquer um deles.")
|
|
48
|
+
test_q = "Qual é o cargo do colaborador Jacques?"
|
|
49
|
+
res = agent_chefe.answer(test_q)
|
|
50
|
+
|
|
51
|
+
print(test_q)
|
|
52
|
+
# Ensure UTF-8 characters are printed properly (no ASCII escapes)
|
|
53
|
+
print(json.dumps(res, indent=2, ensure_ascii=False))
|
|
54
|
+
return 0
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
if __name__ == "__main__":
|
|
58
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from textwrap import dedent
|
|
4
|
+
from typing import Any
|
|
5
|
+
import json
|
|
6
|
+
|
|
7
|
+
from tests.helpers import set_key
|
|
8
|
+
from oskaragent.agent import Oskar
|
|
9
|
+
from oskaragent.agent_config import AgentConfig
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _response_log(assistant_message_struct: dict[str, Any]):
|
|
13
|
+
usage = assistant_message_struct.get("usage", {}) or {}
|
|
14
|
+
print(
|
|
15
|
+
f"[callback] message_id={assistant_message_struct.get('message_id')} "
|
|
16
|
+
f"tokens={{'input_tokens': {usage.get('input_tokens')}, 'output_tokens': {usage.get('output_tokens')}, 'total_tokens': {usage.get('total_tokens')}}}"
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def main() -> int:
|
|
21
|
+
# Set OpenAI API key
|
|
22
|
+
set_key()
|
|
23
|
+
|
|
24
|
+
system_prompt = dedent("""
|
|
25
|
+
### Instruções:
|
|
26
|
+
Atue como um analista especializado no módulo de vendas do Salesforce. Use suas habilidades e conhecimentos técnicos para orientar vendedores na superação de obstáculos em negociações, oferecendo estratégias eficazes para fechar vendas. Você deve manter um comportamento didático, criativo, organizado e comunicativo, empregando seu elevado pensamento crítico para adaptar as soluções às necessidades específicas dos clientes.
|
|
27
|
+
|
|
28
|
+
Você tem conhecimento em venda de produtos de segurança da informação dos fabricantes Check Point, Fortinet, Checkmarx, Proofpoint, Algosec e vários outros. Então você também pode responder perguntas e pedidos técnicos referentes a esses produtos.
|
|
29
|
+
|
|
30
|
+
### Interlocutor
|
|
31
|
+
Suas respostas devem ser direcionadas a vendedores que possuem um entendimento básico a intermediário sobre produtos de segurança da informação e técnicas de venda, mas buscam aprimoramento na negociação e no entendimento técnico avançado das soluções oferecidas.
|
|
32
|
+
|
|
33
|
+
### Tarefas
|
|
34
|
+
- Usar a ferramenta apropriada para buscar as informações atualizadas da oportunidade, que estão no Salesforce.
|
|
35
|
+
- Responda ao pedido realizado.
|
|
36
|
+
|
|
37
|
+
### Modo, tom e estilo da resposta
|
|
38
|
+
Suas respostas devem ser diretas, confiantes e didáticas, mantendo um tom profissional e acessível. Priorize a clareza e precisão nas informações técnicas, adaptando a complexidade das explicações ao nível de entendimento do interlocutor.
|
|
39
|
+
|
|
40
|
+
### Casos atípicos
|
|
41
|
+
1. Se o interlocutor pedir algo sobre uma oportunidade, mas não informar o código da oportunidade, então considere o código {OPO}.
|
|
42
|
+
2. Se o interlocutor fizer perguntas que não se relacionam diretamente com estratégias de venda ou produtos de segurança da informação, responda que seu foco é fornecer consultoria em vendas e segurança da informação e sugira buscar um especialista adequado para outras questões.
|
|
43
|
+
|
|
44
|
+
### Limites da conversa
|
|
45
|
+
Responda apenas perguntas sobre estratégias de venda, produtos de segurança da informação e sua aplicação, e uso do CRM Salesforce. Não responda perguntas e pedidos que não sejam associados ao papel 'Consultor de Vendas'.
|
|
46
|
+
""")
|
|
47
|
+
|
|
48
|
+
mcp_tools = [
|
|
49
|
+
{
|
|
50
|
+
"mcpServerUrl": "http://localhost:8001/mcp",
|
|
51
|
+
"tools": ["get_opportunity_info_by_id"]
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
ag_cfg = AgentConfig(
|
|
56
|
+
system_prompt=system_prompt,
|
|
57
|
+
tools_names=["get_opportunity_info_by_id"],
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
agent = Oskar(agent_config=ag_cfg,
|
|
61
|
+
response_callback=_response_log,
|
|
62
|
+
mcp_tools=mcp_tools,
|
|
63
|
+
is_verbose=True)
|
|
64
|
+
|
|
65
|
+
# No explicit question provided: run a quick test prompt and exit
|
|
66
|
+
# test_q = "Mostre a linha do tempo da oportunidade OPO-ORIZON-2024-08-0001"
|
|
67
|
+
test_q = "Qual é a dor do cliente na oportunidade OPO-ACME-2025-11-0042"
|
|
68
|
+
res = agent.answer(test_q)
|
|
69
|
+
|
|
70
|
+
print(test_q)
|
|
71
|
+
# Ensure UTF-8 characters are printed properly (no ASCII escapes)
|
|
72
|
+
print(json.dumps(res, indent=2, ensure_ascii=False))
|
|
73
|
+
return 0
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
if __name__ == "__main__":
|
|
77
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from textwrap import dedent
|
|
4
|
+
from typing import Any
|
|
5
|
+
import json
|
|
6
|
+
|
|
7
|
+
from tests.helpers import set_key
|
|
8
|
+
from oskaragent.agent import Oskar
|
|
9
|
+
from oskaragent.agent_config import AgentConfig
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _response_log(assistant_message_struct: dict[str, Any]):
|
|
13
|
+
usage = assistant_message_struct.get("usage", {}) or {}
|
|
14
|
+
print(
|
|
15
|
+
f"[callback] message_id={assistant_message_struct.get('message_id')} "
|
|
16
|
+
f"tokens={{'input_tokens': {usage.get('input_tokens')}, 'output_tokens': {usage.get('output_tokens')}, 'total_tokens': {usage.get('total_tokens')}}}"
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def main() -> int:
|
|
21
|
+
# Set OpenAI API key
|
|
22
|
+
set_key()
|
|
23
|
+
|
|
24
|
+
system_prompt = dedent("""
|
|
25
|
+
# Persona:
|
|
26
|
+
Atue como um analista responsável pela consulta e armazenamentos dos dados de chamados de suporte técnico no Salesforce Services Cloud.
|
|
27
|
+
|
|
28
|
+
# Objetivo:
|
|
29
|
+
Consultar informações de chamados no Salesforce, fazer análises e responder as perguntas solicitadas.
|
|
30
|
+
|
|
31
|
+
# Restrições:
|
|
32
|
+
- Se o interlocutor fizer perguntas que não se relacionam diretamente ao suporte técnico, responda que seu foco é fornecer consultoria em suporte técnico e segurança da informação e sugira buscar um especialista adequado para outras questões.
|
|
33
|
+
- Não responda perguntas e pedidos que não sejam associados ao seu papel.
|
|
34
|
+
- Se não localizar as informações solicitadas, então responda "Não tenho a informação solicitada". Não crie ou invente numa resposta.
|
|
35
|
+
|
|
36
|
+
# Formato e Estilo:
|
|
37
|
+
- Suas respostas devem ser diretas, confiantes e didáticas, mantendo um tom profissional e acessível.
|
|
38
|
+
- Suas respostas devem ser direcionadas a analistas que possuem entendimento avançados sobre produtos de segurança da informação.
|
|
39
|
+
|
|
40
|
+
# Tarefas
|
|
41
|
+
- Recuperar os dados do chamado técnico usando a ferramenta apropriada.
|
|
42
|
+
- Preparar e apresentar o relatório solicitado em formato markdown.""")
|
|
43
|
+
|
|
44
|
+
mcp_tools = [
|
|
45
|
+
{
|
|
46
|
+
"mcpServerUrl": "http://localhost:8001/mcp",
|
|
47
|
+
"tools": ["get_salesforce_case_info_by_id"]
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
ag_cfg = AgentConfig(
|
|
52
|
+
system_prompt=system_prompt,
|
|
53
|
+
tools_names=["get_salesforce_case_info_by_id"],
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
agent = Oskar(agent_config=ag_cfg,
|
|
57
|
+
mcp_tools=mcp_tools,
|
|
58
|
+
response_callback=_response_log,
|
|
59
|
+
is_verbose=True)
|
|
60
|
+
|
|
61
|
+
# No explicit question provided: run a quick test prompt and exit
|
|
62
|
+
test_q = "Mostre a linha do tempo do chamado 00042386"
|
|
63
|
+
res = agent.answer(test_q)
|
|
64
|
+
|
|
65
|
+
print(test_q)
|
|
66
|
+
# Ensure UTF-8 characters are printed properly (no ASCII escapes)
|
|
67
|
+
print(json.dumps(res, indent=2, ensure_ascii=False))
|
|
68
|
+
return 0
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
if __name__ == "__main__":
|
|
72
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from textwrap import dedent
|
|
4
|
+
from typing import Any
|
|
5
|
+
import json
|
|
6
|
+
|
|
7
|
+
from tests.helpers import set_key
|
|
8
|
+
from oskaragent.agent import Oskar
|
|
9
|
+
from oskaragent.agent_config import AgentConfig
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _response_log(assistant_message_struct: dict[str, Any]):
|
|
13
|
+
usage = assistant_message_struct.get("usage", {}) or {}
|
|
14
|
+
print(
|
|
15
|
+
f"[callback] message_id={assistant_message_struct.get('message_id')} "
|
|
16
|
+
f"tokens={{'input_tokens': {usage.get('input_tokens')}, 'output_tokens': {usage.get('output_tokens')}, 'total_tokens': {usage.get('total_tokens')}}}"
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def main() -> int:
|
|
21
|
+
# Set OpenAI API key
|
|
22
|
+
set_key()
|
|
23
|
+
|
|
24
|
+
system_prompt = dedent("""
|
|
25
|
+
### Papel
|
|
26
|
+
Atue como um assistente para os colaboradores da equipe de BDR, para responder perguntas sobre pessoas e empresas.
|
|
27
|
+
|
|
28
|
+
### Tarefas
|
|
29
|
+
- Usar a ferramenta apropriada para buscar as informações sobre pessoas e empresas.
|
|
30
|
+
- Responda ao pedido realizado.
|
|
31
|
+
|
|
32
|
+
### Modo, tom e estilo da resposta
|
|
33
|
+
Suas respostas devem ser diretas, confiantes e didáticas, mantendo um tom profissional e acessível. Priorize a clareza e precisão nas informações técnicas, adaptando a complexidade das explicações ao nível de entendimento do interlocutor.
|
|
34
|
+
|
|
35
|
+
### Casos atípicos
|
|
36
|
+
Se o interlocutor fizer perguntas que não se relacionam diretamente com pessoas e empresas, responda que seu foco é fornecer consultoria para as atividades de BDR.
|
|
37
|
+
|
|
38
|
+
### Limites da conversa
|
|
39
|
+
Responda apenas perguntas sobre pessoas, empresas e atividades de BDR. Não responda perguntas e pedidos que não sejam associados à base de clientes.
|
|
40
|
+
""")
|
|
41
|
+
|
|
42
|
+
mcp_tools = [
|
|
43
|
+
{
|
|
44
|
+
"mcpServerUrl": "http://localhost:8001/mcp",
|
|
45
|
+
"tools": ["get_salesforce_case_info_by_id"]
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
ag_cfg = AgentConfig(
|
|
50
|
+
system_prompt=system_prompt
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
agent = Oskar(agent_config=ag_cfg,
|
|
54
|
+
response_callback=_response_log,
|
|
55
|
+
mcp_tools=mcp_tools,
|
|
56
|
+
is_verbose=True)
|
|
57
|
+
|
|
58
|
+
# No explicit question provided: run a quick test prompt and exit
|
|
59
|
+
test_q = 'Liste em formato de tabela as pessoas cujos nomes correspondam a "José Carlos".'
|
|
60
|
+
res = agent.answer(test_q)
|
|
61
|
+
|
|
62
|
+
print(test_q)
|
|
63
|
+
# Ensure UTF-8 characters are printed properly (no ASCII escapes)
|
|
64
|
+
print(json.dumps(res, indent=2, ensure_ascii=False))
|
|
65
|
+
return 0
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
if __name__ == "__main__":
|
|
69
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
import json
|
|
5
|
+
|
|
6
|
+
from tests.helpers import set_key
|
|
7
|
+
from oskaragent.agent import Oskar
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _response_log(assistant_message_struct: dict[str, Any]):
|
|
11
|
+
usage = assistant_message_struct.get("usage", {}) or {}
|
|
12
|
+
print(
|
|
13
|
+
f"[callback] message_id={assistant_message_struct.get('message_id')} "
|
|
14
|
+
f"tokens={{'input_tokens': {usage.get('input_tokens')}, 'output_tokens': {usage.get('output_tokens')}, 'total_tokens': {usage.get('total_tokens')}}}"
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def main() -> int:
|
|
19
|
+
# Set OpenAI API key
|
|
20
|
+
set_key()
|
|
21
|
+
|
|
22
|
+
mcp_tools = [
|
|
23
|
+
{
|
|
24
|
+
"mcpServerUrl": "http://localhost:8001/mcp",
|
|
25
|
+
"tools": ["get_salesforce_case_info_by_id"]
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
agent = Oskar(input_data={"ticket": 42555},
|
|
30
|
+
response_callback=_response_log,
|
|
31
|
+
mcp_tools=mcp_tools,
|
|
32
|
+
is_verbose=True)
|
|
33
|
+
|
|
34
|
+
# No explicit question provided: run a quick test prompt and exit
|
|
35
|
+
test_q = 'Faça uma síntese do ticket {ticket}.'
|
|
36
|
+
res = agent.answer(test_q)
|
|
37
|
+
|
|
38
|
+
print(test_q)
|
|
39
|
+
# Ensure UTF-8 characters are printed properly (no ASCII escapes)
|
|
40
|
+
print(json.dumps(res, indent=2, ensure_ascii=False))
|
|
41
|
+
return 0
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
if __name__ == "__main__":
|
|
45
|
+
raise SystemExit(main())
|
tests/7a_test_BI_CSV.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
from oskaragent.agent import Oskar
|
|
6
|
+
from oskaragent.agent_config import AgentConfig
|
|
7
|
+
from tests.helpers import set_key
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def main() -> None:
|
|
11
|
+
# Set OpenAI API key
|
|
12
|
+
set_key()
|
|
13
|
+
|
|
14
|
+
# Configura o agente para usar o índice local de RAG
|
|
15
|
+
ag_cfg = AgentConfig(
|
|
16
|
+
working_files=[
|
|
17
|
+
{
|
|
18
|
+
"name": "basileia",
|
|
19
|
+
"description": "Dados de temperatura da cidade de Basileia",
|
|
20
|
+
"pathname": "./sources/Basileia.csv"
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
# Ativar logs detalhados para ver chamadas de ferramenta (inclui logs azuis)
|
|
26
|
+
agent = Oskar(agent_config=ag_cfg, is_verbose=True)
|
|
27
|
+
|
|
28
|
+
test_q = 'Faça um gráfico de linhas que mostra a evolução da média da temperatura ao longo dos anos. Considere a maior valor de cada ano.'
|
|
29
|
+
res = agent.answer(test_q)
|
|
30
|
+
|
|
31
|
+
print(test_q)
|
|
32
|
+
# Ensure UTF-8 characters are printed properly (no ASCII escapes)
|
|
33
|
+
print(json.dumps(res, indent=2, ensure_ascii=False))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
if __name__ == "__main__":
|
|
37
|
+
main()
|
tests/7b_test_BI_SQL.py
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
from oskaragent.agent import Oskar
|
|
6
|
+
from oskaragent.agent_config import AgentConfig
|
|
7
|
+
from tests.helpers import set_key
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def main() -> None:
|
|
11
|
+
# Set OpenAI API key
|
|
12
|
+
set_key()
|
|
13
|
+
|
|
14
|
+
# Configura o agente para usar o índice local de RAG
|
|
15
|
+
ag_cfg = AgentConfig(
|
|
16
|
+
working_databases=[
|
|
17
|
+
{
|
|
18
|
+
"name": "Chamados",
|
|
19
|
+
"description": "Informações sobre chamados de suporte técnico",
|
|
20
|
+
"connection_string": "Driver={SQL Server};Server=CGSQL07;Database=DB_KPI;Uid=relkpi;Pwd=tele13",
|
|
21
|
+
"query": """
|
|
22
|
+
select top 100
|
|
23
|
+
CH.NumeroChamado as 'Número do Chamado', CJE.MnemonicoCliente as 'Nome do Cliente', CH.TipoChamado as 'Tipo do Chamado', CH.Classificacao as 'Classificação', CH.[Status] as 'Situação', CH.[Fila] as 'Grupo de Atendimento', CH.[Contrato] as 'Contrato', CH.DataAbertura as 'Data da Abertura', CH.DataEncerramento as 'Data do Encerramento', CH.Titulo as 'Título', CH.Descricao as 'Descrição', CH.Fabricante,
|
|
24
|
+
CH.CausaIncidente as 'Causa do Incidente', CH.DetalheCausas as 'Detalhe da Causa', CH.Indisponibilidade,
|
|
25
|
+
CH.Resolucao as 'Solucão'
|
|
26
|
+
from gestaocorp.vwChamado as CH
|
|
27
|
+
join gestaocorp.vwCotacao as CO on CO.IdCotacao = CH.IdCotacao
|
|
28
|
+
join gestaocorp.vwOportunidade as OPO on OPO.IdOportunidade = CO.IdOportunidade
|
|
29
|
+
join gestaocorp.vwConjEmpresas as CJE on CJE.IdConjEmpresas = OPO.IdConjEmpresas
|
|
30
|
+
""",
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
# Ativar logs detalhados para ver chamadas de ferramenta (inclui logs azuis)
|
|
36
|
+
agent = Oskar(agent_config=ag_cfg, is_verbose=True)
|
|
37
|
+
|
|
38
|
+
test_q = 'Faça um gráfico de barras por Fabricante.'
|
|
39
|
+
res = agent.answer(test_q)
|
|
40
|
+
|
|
41
|
+
print(test_q)
|
|
42
|
+
# Ensure UTF-8 characters are printed properly (no ASCII escapes)
|
|
43
|
+
print(json.dumps(res, indent=2, ensure_ascii=False))
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
if __name__ == "__main__":
|
|
47
|
+
main()
|