From 207f4b9fdb33b0cdb43a68f8da33bfb3d397b18c Mon Sep 17 00:00:00 2001 From: Mohammed Ansari Date: Thu, 9 Jul 2026 10:06:25 -0700 Subject: [PATCH] Add Monocle behavioral test suite Trace-based tests under tests/monocle/ asserting against the agent's Monocle execution traces (agent, tools, output, duration budget). Signed-off-by: Mohammed Ansari --- .gitignore | 3 + configs/config_openai_cli.yml | 129 +++++ tests/monocle/README.md | 73 +++ tests/monocle/conftest.py | 57 ++ tests/monocle/requirements.txt | 5 + tests/monocle/test_nvidiaaiq.py | 109 ++++ ...549dc74fb785e94d9_2026-07-09_13.17.46.json | 241 ++++++++ ...a27f91a0d86b290dd_2026-07-09_13.25.14.json | 547 ++++++++++++++++++ 8 files changed, 1164 insertions(+) create mode 100644 configs/config_openai_cli.yml create mode 100644 tests/monocle/README.md create mode 100644 tests/monocle/conftest.py create mode 100644 tests/monocle/requirements.txt create mode 100644 tests/monocle/test_nvidiaaiq.py create mode 100644 tests/monocle/traces/monocle_trace_nvidia-aiq_4a94876861e3ade549dc74fb785e94d9_2026-07-09_13.17.46.json create mode 100644 tests/monocle/traces/monocle_trace_nvidia-aiq_e2961458302a780a27f91a0d86b290dd_2026-07-09_13.25.14.json diff --git a/.gitignore b/.gitignore index da134e0bc..d1e6757a8 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,9 @@ env/ .env .env.local .env.*.local + +# Monocle traces +.monocle/ # Logs *.log logs/ diff --git a/configs/config_openai_cli.yml b/configs/config_openai_cli.yml new file mode 100644 index 000000000..38cd13bae --- /dev/null +++ b/configs/config_openai_cli.yml @@ -0,0 +1,129 @@ +# This is the default configuration for the CLI mode. +# It has the following features: +# - Human-in-the-loop clarification and plan approval before deep research starts +# - Web search and Paper search tools by default +# - There is no knowledge retrieval + +general: + telemetry: + logging: + console: + _type: console + level: INFO + # tracing: + # langsmith: # Optional: LangSmith tracing - requires langsmith API key. Set using `export LANGSMITH_API_KEY=` + # _type: langsmith + # project: nvidia-aiq + +llms: + nemotron_llm_intent: + _type: openai + model_name: gpt-4o + api_key: ${OPENAI_API_KEY} + temperature: 0.5 + top_p: 0.9 + max_tokens: 4096 + num_retries: 5 + + nemotron_super_llm: + _type: openai + model_name: gpt-4o + api_key: ${OPENAI_API_KEY} + temperature: 0.7 + top_p: 0.7 + max_tokens: 16384 + num_retries: 5 + +functions: + # ========================================================================= + # Data Source Registry + # ========================================================================= + # Central registry that controls: + # 1. UI toggles — each source appears as an on/off switch in the frontend + # 2. Per-message filtering — users can select active sources per request + # 3. Tool auto-inheritance — agents with no explicit `tools` list receive + # every tool listed here (use `exclude_tools` on agents to specialize) + # + # Source entry fields: + # id, name, description, tools, requires_auth (default: false), + # default_enabled (default: true) + # + # See docs/source/customization/tools-and-sources.md for full details. + # ========================================================================= + data_sources: + _type: data_source_registry + sources: + - id: web_search + name: "Web Search" + description: "Search the web for real-time information." + tools: + - web_search_tool + - advanced_web_search_tool + # - id: paper_search + # name: "Academic Papers" + # description: "Search academic papers and scientific publications." + # tools: + # - paper_search_tool + + web_search_tool: + _type: exa_web_search + max_results: 5 + max_content_length: 1000 + + advanced_web_search_tool: + _type: exa_web_search + max_results: 2 + + # Paper Search (optional - requires SERPER_API_KEY) + # Uncomment the block below and set SERPER_API_KEY to enable academic paper search. + # paper_search_tool: + # _type: paper_search + # max_results: 5 + # serper_api_key: ${SERPER_API_KEY} + + # ========================================================================= + # Agents — inherit all registry tools; use exclude_tools to specialize + # ========================================================================= + intent_classifier: + _type: intent_classifier + llm: nemotron_llm_intent + # tools: omitted -> inherits all from data_source_registry + # exclude_tools: [] + # llm_timeout: 90 # optional; seconds for intent LLM call (default 90) + + clarifier_agent: + _type: clarifier_agent + llm: nemotron_super_llm + planner_llm: nemotron_super_llm + # tools: omitted -> inherits all from data_source_registry + # exclude_tools: [] + max_turns: 3 + enable_plan_approval: true + log_response_max_chars: 2000 + verbose: true + + shallow_research_agent: + _type: shallow_research_agent + llm: nemotron_super_llm + # tools: omitted -> inherits all from data_source_registry + exclude_tools: + - advanced_web_search_tool + max_llm_turns: 10 + max_tool_iterations: 5 + + deep_research_agent: + _type: deep_research_agent + enable_citation_verification: true + orchestrator_llm: nemotron_super_llm + source_router_llm: nemotron_super_llm + researcher_llm: nemotron_super_llm + planner_llm: nemotron_super_llm + writer_llm: nemotron_super_llm + exclude_tools: + - web_search_tool + +workflow: + _type: chat_deepresearcher_agent + enable_escalation: true + enable_clarifier: true + checkpoint_db: ${AIQ_CHECKPOINT_DB:-./checkpoints.db} diff --git a/tests/monocle/README.md b/tests/monocle/README.md new file mode 100644 index 000000000..8236abe5d --- /dev/null +++ b/tests/monocle/README.md @@ -0,0 +1,73 @@ +# AI-Q behavioural tests (Monocle Test Tools) + +Trace-based tests that lock in the AI-Q research agent's behaviour. AI-Q runs on +the NeMo Agent Toolkit (NAT); Monocle records each run as a structured trace -- +the agent invocation, every tool call, and timings -- and each test asserts +against that trace: which agent ran, which tools it called, what it was asked, +what it produced, and its duration cost. A later prompt, model, or tool change +that regresses the behaviour fails here. + +## Layout + +- `test_nvidiaaiq.py` — the suite: two offline tests + one live test +- `conftest.py` — Monocle setup, `.env` loading, and `run_nvidiaaiq()` +- `traces/` — recorded good-trace fixtures the offline tests replay +- `requirements.txt` — dependencies + +## Tests + +| Test | Scenario | What it shows | +|---|---|---| +| `test_capabilities_intro` | "Hi, what can you do?" | direct answer, a `does_not_call_tool` negative, budget | +| `test_nvda_stock_lookup` | Current NVIDIA stock price | `web_search_tool` call, input/output, budget | +| `test_nvda_stock_lookup_live` | The stock question, run live | live run, web-search path, structure + budget | + +The offline tests replay recorded traces with duration budgets measured from +those runs (rounded up with headroom). The live test drives the agent +end-to-end and asserts structure and budget only, since the output legitimately +varies run to run. + +Note on budgets: NAT traces do not carry token metadata -- the `inference.*` +spans record only finish reasons, no token counts -- so `under_token_limit(...)` +would sum 0 and always pass. This suite omits it and budgets on +`under_duration(..., span_type="workflow")` instead. The agent name asserted +(`LangGraph`) is the real `entity.1.name` on the `agentic.invocation` spans (NAT +runs its research agents on a LangGraph runtime); the web tool is +`web_search_tool`. + +## Run + +```bash +pip install -r requirements.txt +pytest tests/monocle/ -k "not live" # offline, no network, no keys +``` + +The live test is opt-in (`RUN_LIVE_NVIDIAAIQ=1`) and skipped by default. +NAT binds its async singletons to the first event loop, so only one in-process +live run works per process, and NAT leaves non-daemon threads that keep the +interpreter from exiting cleanly. So run the live test in its own process, with +keys in `deploy/.env` (`OPENAI_API_KEY` plus a search key, `EXA_API_KEY`/`SERPER_API_KEY`): + +```bash +RUN_LIVE_NVIDIAAIQ=1 pytest tests/monocle/ -k nvda_stock_lookup_live -s +``` + +They drive the workflow via `configs/config_openai_cli.yml` with an +auto-approving `user_input_callback`, so a human-in-the-loop clarification or +plan-approval interrupt is answered automatically instead of blocking the run. + +## Add your own test + +1. Run AI-Q under Monocle and capture a trace of a run you're happy with + (Monocle writes trace JSON to `.monocle/` by default). +2. Move it into `traces/` and load it with + `monocle_trace_asserter.with_trace_source("file", trace_path=path)`. +3. Assert with the fluent API — `called_agent(...)`, `called_tool(...)`, + `contains_input/output(...)`, `under_duration(..., span_type="workflow")` — + then add it alongside the others. + +## Evaluations (optional) + +Each test carries a commented-out `check_eval("hallucination", ...)` chain. +Monocle can run evaluation checks against a trace; set `OKAHU_API_KEY` and +uncomment to enable. diff --git a/tests/monocle/conftest.py b/tests/monocle/conftest.py new file mode 100644 index 000000000..9e5f36ebb --- /dev/null +++ b/tests/monocle/conftest.py @@ -0,0 +1,57 @@ +"""Pytest scaffold for the AI-Q (NeMo Agent Toolkit) Monocle test suite. + +Enables Monocle tracing, loads the repo `deploy/.env`, and exposes +``run_nvidiaaiq`` -- the single entry the live tests use to drive the agent +under instrumentation and return its final answer text. +""" +import asyncio +import os +import uuid +from pathlib import Path + +from dotenv import load_dotenv +from monocle_apptrace import setup_monocle_telemetry + +HERE = Path(__file__).resolve().parent +TRACES = HERE / "traces" +REPO_ROOT = HERE.parent.parent + +# This repo runs pytest with `--import-mode=importlib`, so a test's directory is +# not auto-added to sys.path and `import conftest` would load a *second* copy of +# this module -- double-instrumenting the tracer. Guard the one-time setup. +if not os.environ.get("_NVIDIAAIQ_MONOCLE_READY"): + setup_monocle_telemetry(workflow_name="nvidia-aiq") + load_dotenv(REPO_ROOT / "deploy" / ".env") + os.environ["_NVIDIAAIQ_MONOCLE_READY"] = "1" + +# The CLI-mode workflow used for live runs. It exposes the web/paper search +# tools and a human-in-the-loop clarification + plan-approval step. +LIVE_CONFIG = REPO_ROOT / "configs" / "config_openai_cli.yml" + + +def run_nvidiaaiq(message: str) -> str: + """Run the AI-Q (NAT) workflow once and return its final response text. + + NAT's CLI workflow can raise a human-in-the-loop interrupt (clarification or + plan approval). We pass an auto-approving ``user_input_callback`` so the run + never blocks waiting on a human -- a short affirmative satisfies both the + clarifier and plan approval. + """ + from nat.builder.context import ContextState + from nat.data_models.interactive import HumanResponseText + from nat.runtime.loader import load_workflow + + async def _auto_approve(prompt): + return HumanResponseText(text="Yes, proceed with the research plan.") + + async def _run() -> str: + async with load_workflow(str(LIVE_CONFIG)) as session_manager: + try: + ContextState.get().conversation_id.set(str(uuid.uuid4())) + except Exception: + pass + async with session_manager.session(user_input_callback=_auto_approve) as session: + async with session.run(message) as runner: + return await runner.result(to_type=str) + + return asyncio.run(_run()) diff --git a/tests/monocle/requirements.txt b/tests/monocle/requirements.txt new file mode 100644 index 000000000..705e879a1 --- /dev/null +++ b/tests/monocle/requirements.txt @@ -0,0 +1,5 @@ +# Installing monocle_test_tools pulls in everything this suite needs +# (pytest, pytest-asyncio, and monocle_apptrace come transitively). +monocle_test_tools +# Auto-loads the repo deploy/.env for the live tests. +python-dotenv diff --git a/tests/monocle/test_nvidiaaiq.py b/tests/monocle/test_nvidiaaiq.py new file mode 100644 index 000000000..86fbab7e9 --- /dev/null +++ b/tests/monocle/test_nvidiaaiq.py @@ -0,0 +1,109 @@ +"""Trace-based behavioural tests for AI-Q (NeMo Agent Toolkit), using Monocle +Test Tools. + +Each test asserts against the Monocle trace a run emits -- which agent ran, +which tools it called, what it was asked, what it produced, and its duration +cost. Two offline tests replay recorded good traces (fast, no keys); one live +test runs the agent end-to-end. + + pytest tests/monocle/ -k "not live" # offline, no keys + RUN_LIVE_NVIDIAAIQ=1 pytest tests/monocle/ -k live -s # live (needs OPENAI + a search key) + +NOTE ON TOKENS: no `under_token_limit` here. NAT calls the OpenAI models in +streaming mode without `stream_options.include_usage`, so the response carries +no usage and the `inference.*` spans record only {finish_reason, finish_type}. +This is upstream (NAT), not a Monocle gap -- Monocle captures token counts +whenever the response includes usage. So the suite budgets on +`under_duration(..., span_type="workflow")` instead. The agent name is +"LangGraph" (NAT runs on a LangGraph runtime); the web tool is `web_search_tool`. +""" +import os +import sys +from pathlib import Path + +import pytest +from monocle_test_tools import TraceAssertion + +# This repo uses `--import-mode=importlib`, which does not put a test's own +# directory on sys.path; make the sibling conftest importable by name. +sys.path.insert(0, str(Path(__file__).resolve().parent)) +from conftest import TRACES, run_nvidiaaiq # noqa: E402 + +# Recorded good traces (captured from this repo under monocle_apptrace 0.8.8). +# Q: "Hi, what can you do?" -- meta/capabilities, answered directly (no tools). +TRACE_INTRO = str(TRACES / "monocle_trace_nvidia-aiq_4a94876861e3ade549dc74fb785e94d9_2026-07-09_13.17.46.json") +# Q: "What is the current stock price of NVIDIA today?" -- live-fact lookup that +# calls web_search_tool once. +TRACE_STOCK = str(TRACES / "monocle_trace_nvidia-aiq_e2961458302a780a27f91a0d86b290dd_2026-07-09_13.25.14.json") + + +# --- Offline: replay recorded good traces --------------------------------- + +def test_capabilities_intro(monocle_trace_asserter: TraceAssertion): + """Meta/capabilities question. The orchestrator answers directly (routes it + as a meta_response) -- no tool is called. Real trace: 5 spans, ~2.0s.""" + monocle_trace_asserter.with_trace_source("file", trace_path=TRACE_INTRO) + + monocle_trace_asserter.called_agent("LangGraph").contains_input("what can you do") + monocle_trace_asserter.contains_output("AI Research Assistant") + monocle_trace_asserter.does_not_call_tool("web_search_tool", "LangGraph") + monocle_trace_asserter.under_duration(10, span_type="workflow") + + # Eval layer (deferred -- set OKAHU_API_KEY and uncomment to enable): + # monocle_trace_asserter.with_evaluation("okahu").check_eval("hallucination", "no_hallucination") \ + # .check_eval("contextual_precision", "high_precision") \ + # .check_eval("sentiment", "positive") \ + # .check_eval("bias", "unbiased") + + +def test_nvda_stock_lookup(monocle_trace_asserter: TraceAssertion): + """Live-fact lookup. The agent calls web_search_tool once and reports the + price it found ($202.78, the captured value). Real trace: 11 spans, ~7.7s.""" + monocle_trace_asserter.with_trace_source("file", trace_path=TRACE_STOCK) + + monocle_trace_asserter.called_agent("LangGraph").contains_input("stock price of NVIDIA") + monocle_trace_asserter.contains_output("202.78") + monocle_trace_asserter.called_tool("web_search_tool", "LangGraph") + monocle_trace_asserter.under_duration(15, span_type="workflow") + + # monocle_trace_asserter.with_evaluation("okahu").check_eval("hallucination", "no_hallucination") \ + # .check_eval("contextual_precision", "high_precision") \ + # .check_eval("sentiment", "positive") \ + # .check_eval("bias", "unbiased") + + +# --- Live: run the agent end-to-end --------------------------------------- +# The web-search fact lookup (web_search_tool over the configured provider). +# Output text varies run to run, so it asserts structure + budget with +# contains_any_output kept phrasing-robust. +# +# Opt-in (RUN_LIVE_NVIDIAAIQ=1), one run per process: NAT binds its async +# singletons (module-level locks) to the first event loop, so a second +# asyncio.run() in the same process raises "bound to a different event loop", +# and NAT leaves non-daemon worker threads that keep the interpreter from +# exiting cleanly. So a default `pytest tests/monocle/` skips this (offline +# stays green and exits clean); run it explicitly, e.g.: +# RUN_LIVE_NVIDIAAIQ=1 pytest tests/monocle/ -k live -s +_LIVE = pytest.mark.skipif( + os.environ.get("RUN_LIVE_NVIDIAAIQ") != "1", + reason="opt-in live run (set RUN_LIVE_NVIDIAAIQ=1; run one live test per process -- see note above)", +) + + +@_LIVE +def test_nvda_stock_lookup_live(monocle_trace_asserter: TraceAssertion): + """Web-search path: the NVIDIA stock question, run live (web_search_tool).""" + monocle_trace_asserter.validator.test_workflow( + run_nvidiaaiq, + {"test_input": ("What is the current stock price of NVIDIA today?",)}, + ) + + monocle_trace_asserter.called_agent("LangGraph") + monocle_trace_asserter.contains_any_output("NVIDIA", "NVDA", "stock", "price") + monocle_trace_asserter.called_tool("web_search_tool", "LangGraph") + monocle_trace_asserter.under_duration(120, span_type="workflow") + + # monocle_trace_asserter.with_evaluation("okahu").check_eval("hallucination", "no_hallucination") \ + # .check_eval("contextual_precision", "high_precision") \ + # .check_eval("sentiment", "positive") \ + # .check_eval("bias", "unbiased") diff --git a/tests/monocle/traces/monocle_trace_nvidia-aiq_4a94876861e3ade549dc74fb785e94d9_2026-07-09_13.17.46.json b/tests/monocle/traces/monocle_trace_nvidia-aiq_4a94876861e3ade549dc74fb785e94d9_2026-07-09_13.17.46.json new file mode 100644 index 000000000..15ca63516 --- /dev/null +++ b/tests/monocle/traces/monocle_trace_nvidia-aiq_4a94876861e3ade549dc74fb785e94d9_2026-07-09_13.17.46.json @@ -0,0 +1,241 @@ +[{ + "name": "openai.resources.chat.completions.AsyncCompletions.create", + "context": { + "trace_id": "4a94876861e3ade549dc74fb785e94d9", + "span_id": "7627ea74114f5154", + "trace_state": "[]" + }, + "kind": "SpanKind.INTERNAL", + "parent_id": "e3c2cc3afb7d162b", + "start_time": "2026-07-09T20:17:44.169277Z", + "end_time": "2026-07-09T20:17:46.174298Z", + "status": { + "status_code": "OK" + }, + "attributes": { + "monocle_apptrace.version": "0.8.8", + "monocle_apptrace.language": "python", + "span_source": "/.venv/lib/python3.12/site-packages/openai/_legacy_response.py:384", + "workflow.name": "nvidia-aiq", + "span.type": "inference.modelapi", + "scope.agentic.session": "22021b48-b866-405d-a090-e33f4877efba", + "scope.agentic.turn": "33ead0d1ec7b41de8aae382ae321d8d5", + "scope.agentic.invocation": "a8627112ca54600aedfaf1190acc6a34", + "span.subtype": "turn_end" + }, + "events": [], + "links": [], + "resource": { + "attributes": { + "service.name": "nvidia-aiq" + }, + "schema_url": "" + } +} +,{ + "name": "langchain_core.language_models.chat_models.BaseChatModel.ainvoke", + "context": { + "trace_id": "4a94876861e3ade549dc74fb785e94d9", + "span_id": "e3c2cc3afb7d162b", + "trace_state": "[]" + }, + "kind": "SpanKind.INTERNAL", + "parent_id": "08b58f6b6f954baf", + "start_time": "2026-07-09T20:17:44.167177Z", + "end_time": "2026-07-09T20:17:46.182559Z", + "status": { + "status_code": "OK" + }, + "attributes": { + "monocle_apptrace.version": "0.8.8", + "monocle_apptrace.language": "python", + "span_source": "/.venv/lib/python3.12/site-packages/nat/utils/exception_handlers/automatic_retries.py:265", + "workflow.name": "nvidia-aiq", + "entity.1.type": "inference.generic", + "span.type": "inference.framework", + "scope.agentic.session": "22021b48-b866-405d-a090-e33f4877efba", + "scope.agentic.turn": "33ead0d1ec7b41de8aae382ae321d8d5", + "scope.agentic.invocation": "a8627112ca54600aedfaf1190acc6a34", + "entity.count": 1, + "span.subtype": "turn_end" + }, + "events": [ + { + "name": "data.input", + "timestamp": "2026-07-09T20:17:44.167252Z", + "attributes": { + "input": [ + "{\"system\": \"You are the orchestration layer of an AI Research Assistant built by NVIDIA. Your goal is to analyze the user's query, determine its intent, and provide either a direct response (Meta) or a research plan (Shallow/Deep).\\n\\n### STEP 1: INTENT CLASSIFICATION\\nClassify the query as \\\"meta\\\" or \\\"research\\\".\\n- **meta**: System identity, abilities, greetings, time/date, tool questions, out-of-scope requests (code/files), emotional check-ins, jokes, casual chat, small talk, or any request that does not need external sources (e.g. \\\"tell me a joke\\\", \\\"how are you\\\").\\n- **research**: Facts, data, analysis, \\\"how-to\\\", scientific/technical topics, or anything requiring external sources (web search, documents, etc.).\\n- **Rule**: If a query is mixed or you are unsure, choose \\\"research\\\".\\n\\n### STEP 2: BRANCHING LOGIC\\n\\n#### IF INTENT IS \\\"META\\\":\\nGenerate a direct response to the user.\\n1. **Identity**: You are the AI Research Assistant. You have two layers: Shallow (fast) and Deep (structured).\\n2. **Greeting**: Use the user's first name if available. Be brief and friendly.\\n3. **Out-of-Scope**: If they ask to run code, edit files, or send emails, politely decline, explain why, and redirect to research capabilities.\\n4. **Constraints**: No emojis. Do not answer research questions here.\\n\\n#### IF INTENT IS \\\"RESEARCH\\\":\\nDetermine the semantic route and depth.\\n- **route = \\\"report_ask\\\"** only when an active report is available and the user asks a question answerable from that existing report.\\n- **route = \\\"report_cosmetic_edit\\\"** only when an active report is available and the user asks for mechanical or aesthetic edits that do not require new evidence.\\n- **route = \\\"report_delta_research\\\"** only when an active report is available and the user asks for fresh evidence, deeper analysis, or a new analytical perspective on the same report topic.\\n- **route = \\\"standalone_research\\\"** for generic factual questions, new topics, unrelated report requests, or when no active report is available.\\n\\nRoute examples:\\n- \\\"what are the risks in this report?\\\" -> route = \\\"report_ask\\\"\\n- \\\"summarize this report\\\" -> route = \\\"report_ask\\\"\\n- \\\"make this shorter\\\" -> route = \\\"report_cosmetic_edit\\\"\\n- \\\"change tone\\\" -> route = \\\"report_cosmetic_edit\\\"\\n- \\\"format as bullets\\\" -> route = \\\"report_cosmetic_edit\\\"\\n- \\\"rewrite this report from a player-performance POV\\\" -> route = \\\"report_delta_research\\\"\\n- \\\"redo this with newer evidence\\\" -> route = \\\"report_delta_research\\\"\\n- \\\"can we write a report on this from a supply-chain angle?\\\" -> route = \\\"report_delta_research\\\"\\n- \\\"write a separate report on player performance\\\" -> route = \\\"standalone_research\\\"\\n\\nDetermine the depth for standalone_research.\\n- **shallow**: Single main question, factual lookup, 2-3 tool calls, no complex comparison.\\n- **deep**: Explicit report-generation requests (\\\"write/create/generate a report\\\"), multi-faceted requests,\\n explicit comparisons, trend analysis, strategy/roadmaps, or \\\"comprehensive\\\" requests.\\n- **Tie-break**: If unsure, choose \\\"shallow\\\".\\n\\n### OUTPUT FORMAT\\nYou must respond ONLY with a JSON object using this schema:\\n{\\n \\\"intent\\\": \\\"meta\\\" | \\\"research\\\",\\n \\\"route\\\": \\\"report_ask\\\" | \\\"report_cosmetic_edit\\\" | \\\"report_delta_research\\\" | \\\"standalone_research\\\" | \\\"meta\\\",\\n \\\"meta_response\\\": \\\"The text response if intent is meta, otherwise null\\\",\\n \\\"research_depth\\\": \\\"shallow\\\" | \\\"deep\\\" | null,\\n \\\"route_reasoning\\\": \\\"One sentence explanation for the route and depth, otherwise null\\\"\\n}### CONTEXT\\nCurrent Date and Time: 2026-07-09 13:17:44\\n\\n\\n\\nActive report: none\\n\\n\\nAvailable Tools:\\n\\n- advanced_web_search_tool: Retrieves relevant contexts from web search (using Exa) for the given question.\\n\\n Args:\\n question (str): The question to be answered. Will be truncated to 400 characters if longer.\\n\\n Returns:\\n str: The web search results containing relevant documents and their URLs.- web_search_tool: Retrieves relevant contexts from web search (using Exa) for the given question.\\n\\n Args:\\n question (str): The question to be answered. Will be truncated to 400 characters if longer.\\n\\n Returns:\\n str: The web search results containing relevant documents and their URLs.\\n\\n\\n### USER QUERY\\n\\\"Hi, what can you do?\\\"\"}" + ] + } + }, + { + "name": "data.output", + "timestamp": "2026-07-09T20:17:46.182474Z", + "attributes": { + "response": "{\"ai\": \"```json\\n{\\n \\\"intent\\\": \\\"meta\\\",\\n \\\"route\\\": \\\"meta\\\",\\n \\\"meta_response\\\": \\\"Hello! I am the AI Research Assistant. I can help with research by providing factual information, generating reports, and analyzing data. If you have any specific questions or topics you'd like to explore, feel free to ask!\\\",\\n \\\"research_depth\\\": null,\\n \\\"route_reasoning\\\": null\\n}\\n```\"}" + } + }, + { + "name": "metadata", + "timestamp": "2026-07-09T20:17:46.182514Z", + "attributes": { + "finish_reason": "stop", + "finish_type": "success" + } + } + ], + "links": [], + "resource": { + "attributes": { + "service.name": "nvidia-aiq" + }, + "schema_url": "" + } +} +,{ + "name": "langgraph.graph.state.CompiledStateGraph.astream", + "context": { + "trace_id": "4a94876861e3ade549dc74fb785e94d9", + "span_id": "08b58f6b6f954baf", + "trace_state": "[]" + }, + "kind": "SpanKind.INTERNAL", + "parent_id": "06283298ccbb919b", + "start_time": "2026-07-09T20:17:44.159915Z", + "end_time": "2026-07-09T20:17:46.187493Z", + "status": { + "status_code": "OK" + }, + "attributes": { + "monocle_apptrace.version": "0.8.8", + "monocle_apptrace.language": "python", + "span_source": "/.venv/lib/python3.12/site-packages/langgraph/pregel/main.py:4061", + "workflow.name": "nvidia-aiq", + "entity.1.type": "agent.langgraph", + "entity.1.name": "LangGraph", + "last.inference": "e3c2cc3afb7d162b:*", + "span.type": "agentic.invocation", + "scope.agentic.session": "22021b48-b866-405d-a090-e33f4877efba", + "scope.agentic.turn": "33ead0d1ec7b41de8aae382ae321d8d5", + "scope.agentic.invocation": "a8627112ca54600aedfaf1190acc6a34", + "entity.count": 1, + "span.subtype": "content_processing", + "monocle.last.agent.invocation.id": "", + "monocle.last.agent.name": "" + }, + "events": [ + { + "name": "data.input", + "timestamp": "2026-07-09T20:17:44.159954Z", + "attributes": { + "input": "[\"Hi, what can you do?\"]" + } + }, + { + "name": "data.output", + "timestamp": "2026-07-09T20:17:46.187298Z", + "attributes": { + "response": "Hello! I am the AI Research Assistant. I can help with research by providing factual information, generating reports, and analyzing data. If you have any specific questions or topics you'd like to explore, feel free to ask!" + } + } + ], + "links": [], + "resource": { + "attributes": { + "service.name": "nvidia-aiq" + }, + "schema_url": "" + } +} +,{ + "name": "langgraph.graph.state.CompiledStateGraph.ainvoke", + "context": { + "trace_id": "4a94876861e3ade549dc74fb785e94d9", + "span_id": "06283298ccbb919b", + "trace_state": "[]" + }, + "kind": "SpanKind.INTERNAL", + "parent_id": "a10fe78911676ddf", + "start_time": "2026-07-09T20:17:44.157812Z", + "end_time": "2026-07-09T20:17:46.187610Z", + "status": { + "status_code": "OK" + }, + "attributes": { + "monocle_apptrace.version": "0.8.8", + "monocle_apptrace.language": "python", + "span_source": "/src/aiq_agent/agents/chat_researcher/agent.py:570", + "workflow.name": "nvidia-aiq", + "entity.1.type": "agent.langgraph", + "monocle.last.agent.invocation.id": "08b58f6b6f954baf", + "monocle.last.agent.name": "LangGraph", + "last.inference": "e3c2cc3afb7d162b:*", + "span.type": "agentic.turn", + "scope.agentic.session": "22021b48-b866-405d-a090-e33f4877efba", + "scope.agentic.turn": "33ead0d1ec7b41de8aae382ae321d8d5", + "entity.count": 1, + "span.subtype": "turn" + }, + "events": [ + { + "name": "data.input", + "timestamp": "2026-07-09T20:17:44.157854Z", + "attributes": { + "input": "[\"Hi, what can you do?\"]" + } + }, + { + "name": "data.output", + "timestamp": "2026-07-09T20:17:46.187592Z", + "attributes": { + "response": "Hello! I am the AI Research Assistant. I can help with research by providing factual information, generating reports, and analyzing data. If you have any specific questions or topics you'd like to explore, feel free to ask!" + } + } + ], + "links": [], + "resource": { + "attributes": { + "service.name": "nvidia-aiq" + }, + "schema_url": "" + } +} +,{ + "name": "workflow", + "context": { + "trace_id": "4a94876861e3ade549dc74fb785e94d9", + "span_id": "a10fe78911676ddf", + "trace_state": "[]" + }, + "kind": "SpanKind.INTERNAL", + "parent_id": null, + "start_time": "2026-07-09T20:17:44.157761Z", + "end_time": "2026-07-09T20:17:46.187621Z", + "status": { + "status_code": "OK" + }, + "attributes": { + "monocle_apptrace.version": "0.8.8", + "monocle_apptrace.language": "python", + "span_source": "/src/aiq_agent/agents/chat_researcher/agent.py:570", + "scope.agentic.session": "22021b48-b866-405d-a090-e33f4877efba", + "scope.agentic.turn": "33ead0d1ec7b41de8aae382ae321d8d5", + "workflow.name": "nvidia-aiq", + "span.type": "workflow", + "entity.1.name": "nvidia-aiq", + "entity.1.type": "workflow.langgraph", + "entity.2.type": "app_hosting.generic", + "entity.2.name": "generic", + "last.inference": "e3c2cc3afb7d162b:*" + }, + "events": [], + "links": [], + "resource": { + "attributes": { + "service.name": "nvidia-aiq" + }, + "schema_url": "" + } +} +] \ No newline at end of file diff --git a/tests/monocle/traces/monocle_trace_nvidia-aiq_e2961458302a780a27f91a0d86b290dd_2026-07-09_13.25.14.json b/tests/monocle/traces/monocle_trace_nvidia-aiq_e2961458302a780a27f91a0d86b290dd_2026-07-09_13.25.14.json new file mode 100644 index 000000000..33d12973a --- /dev/null +++ b/tests/monocle/traces/monocle_trace_nvidia-aiq_e2961458302a780a27f91a0d86b290dd_2026-07-09_13.25.14.json @@ -0,0 +1,547 @@ +[{ + "name": "openai.resources.chat.completions.AsyncCompletions.create", + "context": { + "trace_id": "e2961458302a780a27f91a0d86b290dd", + "span_id": "899cb44dd4cbc266", + "trace_state": "[]" + }, + "kind": "SpanKind.INTERNAL", + "parent_id": "4965175556232f45", + "start_time": "2026-07-09T20:25:11.461959Z", + "end_time": "2026-07-09T20:25:13.656256Z", + "status": { + "status_code": "OK" + }, + "attributes": { + "monocle_apptrace.version": "0.8.8", + "monocle_apptrace.language": "python", + "span_source": "/.venv/lib/python3.12/site-packages/openai/_legacy_response.py:384", + "workflow.name": "nvidia-aiq", + "span.type": "inference.modelapi", + "scope.agentic.session": "3231a666-792d-49a0-bf51-37ba47f4eaf4", + "scope.agentic.turn": "1b91d731c386e41fcfbb29d01e3d0e7e", + "scope.agentic.invocation": "5133c49ef68f7b6f2fc506866a02c2c3", + "span.subtype": "turn_end" + }, + "events": [], + "links": [], + "resource": { + "attributes": { + "service.name": "nvidia-aiq" + }, + "schema_url": "" + } +} +,{ + "name": "langchain_core.language_models.chat_models.BaseChatModel.ainvoke", + "context": { + "trace_id": "e2961458302a780a27f91a0d86b290dd", + "span_id": "4965175556232f45", + "trace_state": "[]" + }, + "kind": "SpanKind.INTERNAL", + "parent_id": "252e148439056756", + "start_time": "2026-07-09T20:25:11.459818Z", + "end_time": "2026-07-09T20:25:13.660089Z", + "status": { + "status_code": "OK" + }, + "attributes": { + "monocle_apptrace.version": "0.8.8", + "monocle_apptrace.language": "python", + "span_source": "/.venv/lib/python3.12/site-packages/nat/utils/exception_handlers/automatic_retries.py:265", + "workflow.name": "nvidia-aiq", + "entity.1.type": "inference.generic", + "span.type": "inference.framework", + "scope.agentic.session": "3231a666-792d-49a0-bf51-37ba47f4eaf4", + "scope.agentic.turn": "1b91d731c386e41fcfbb29d01e3d0e7e", + "scope.agentic.invocation": "5133c49ef68f7b6f2fc506866a02c2c3", + "entity.count": 1, + "span.subtype": "turn_end" + }, + "events": [ + { + "name": "data.input", + "timestamp": "2026-07-09T20:25:11.459889Z", + "attributes": { + "input": [ + "{\"system\": \"You are the orchestration layer of an AI Research Assistant built by NVIDIA. Your goal is to analyze the user's query, determine its intent, and provide either a direct response (Meta) or a research plan (Shallow/Deep).\\n\\n### STEP 1: INTENT CLASSIFICATION\\nClassify the query as \\\"meta\\\" or \\\"research\\\".\\n- **meta**: System identity, abilities, greetings, time/date, tool questions, out-of-scope requests (code/files), emotional check-ins, jokes, casual chat, small talk, or any request that does not need external sources (e.g. \\\"tell me a joke\\\", \\\"how are you\\\").\\n- **research**: Facts, data, analysis, \\\"how-to\\\", scientific/technical topics, or anything requiring external sources (web search, documents, etc.).\\n- **Rule**: If a query is mixed or you are unsure, choose \\\"research\\\".\\n\\n### STEP 2: BRANCHING LOGIC\\n\\n#### IF INTENT IS \\\"META\\\":\\nGenerate a direct response to the user.\\n1. **Identity**: You are the AI Research Assistant. You have two layers: Shallow (fast) and Deep (structured).\\n2. **Greeting**: Use the user's first name if available. Be brief and friendly.\\n3. **Out-of-Scope**: If they ask to run code, edit files, or send emails, politely decline, explain why, and redirect to research capabilities.\\n4. **Constraints**: No emojis. Do not answer research questions here.\\n\\n#### IF INTENT IS \\\"RESEARCH\\\":\\nDetermine the semantic route and depth.\\n- **route = \\\"report_ask\\\"** only when an active report is available and the user asks a question answerable from that existing report.\\n- **route = \\\"report_cosmetic_edit\\\"** only when an active report is available and the user asks for mechanical or aesthetic edits that do not require new evidence.\\n- **route = \\\"report_delta_research\\\"** only when an active report is available and the user asks for fresh evidence, deeper analysis, or a new analytical perspective on the same report topic.\\n- **route = \\\"standalone_research\\\"** for generic factual questions, new topics, unrelated report requests, or when no active report is available.\\n\\nRoute examples:\\n- \\\"what are the risks in this report?\\\" -> route = \\\"report_ask\\\"\\n- \\\"summarize this report\\\" -> route = \\\"report_ask\\\"\\n- \\\"make this shorter\\\" -> route = \\\"report_cosmetic_edit\\\"\\n- \\\"change tone\\\" -> route = \\\"report_cosmetic_edit\\\"\\n- \\\"format as bullets\\\" -> route = \\\"report_cosmetic_edit\\\"\\n- \\\"rewrite this report from a player-performance POV\\\" -> route = \\\"report_delta_research\\\"\\n- \\\"redo this with newer evidence\\\" -> route = \\\"report_delta_research\\\"\\n- \\\"can we write a report on this from a supply-chain angle?\\\" -> route = \\\"report_delta_research\\\"\\n- \\\"write a separate report on player performance\\\" -> route = \\\"standalone_research\\\"\\n\\nDetermine the depth for standalone_research.\\n- **shallow**: Single main question, factual lookup, 2-3 tool calls, no complex comparison.\\n- **deep**: Explicit report-generation requests (\\\"write/create/generate a report\\\"), multi-faceted requests,\\n explicit comparisons, trend analysis, strategy/roadmaps, or \\\"comprehensive\\\" requests.\\n- **Tie-break**: If unsure, choose \\\"shallow\\\".\\n\\n### OUTPUT FORMAT\\nYou must respond ONLY with a JSON object using this schema:\\n{\\n \\\"intent\\\": \\\"meta\\\" | \\\"research\\\",\\n \\\"route\\\": \\\"report_ask\\\" | \\\"report_cosmetic_edit\\\" | \\\"report_delta_research\\\" | \\\"standalone_research\\\" | \\\"meta\\\",\\n \\\"meta_response\\\": \\\"The text response if intent is meta, otherwise null\\\",\\n \\\"research_depth\\\": \\\"shallow\\\" | \\\"deep\\\" | null,\\n \\\"route_reasoning\\\": \\\"One sentence explanation for the route and depth, otherwise null\\\"\\n}### CONTEXT\\nCurrent Date and Time: 2026-07-09 13:25:11\\n\\n\\n\\nActive report: none\\n\\n\\nAvailable Tools:\\n\\n- advanced_web_search_tool: Retrieves relevant contexts from web search (using Exa) for the given question.\\n\\n Args:\\n question (str): The question to be answered. Will be truncated to 400 characters if longer.\\n\\n Returns:\\n str: The web search results containing relevant documents and their URLs.- web_search_tool: Retrieves relevant contexts from web search (using Exa) for the given question.\\n\\n Args:\\n question (str): The question to be answered. Will be truncated to 400 characters if longer.\\n\\n Returns:\\n str: The web search results containing relevant documents and their URLs.\\n\\n\\n### USER QUERY\\n\\\"What is the current stock price of NVIDIA today?\\\"\"}" + ] + } + }, + { + "name": "data.output", + "timestamp": "2026-07-09T20:25:13.660055Z", + "attributes": { + "response": "{\"ai\": \"```json\\n{\\n \\\"intent\\\": \\\"research\\\",\\n \\\"route\\\": \\\"standalone_research\\\",\\n \\\"meta_response\\\": null,\\n \\\"research_depth\\\": \\\"shallow\\\",\\n \\\"route_reasoning\\\": \\\"The user is asking for a factual lookup of NVIDIA's current stock price, which requires a real-time web search.\\\"\\n}\\n```\"}" + } + }, + { + "name": "metadata", + "timestamp": "2026-07-09T20:25:13.660073Z", + "attributes": { + "finish_reason": "stop", + "finish_type": "success" + } + } + ], + "links": [], + "resource": { + "attributes": { + "service.name": "nvidia-aiq" + }, + "schema_url": "" + } +} +,{ + "name": "openai.resources.chat.completions.AsyncCompletions.create", + "context": { + "trace_id": "e2961458302a780a27f91a0d86b290dd", + "span_id": "aafe4cbbaaa63aa9", + "trace_state": "[]" + }, + "kind": "SpanKind.INTERNAL", + "parent_id": "335965332693a78f", + "start_time": "2026-07-09T20:25:13.675238Z", + "end_time": "2026-07-09T20:25:15.346552Z", + "status": { + "status_code": "OK" + }, + "attributes": { + "monocle_apptrace.version": "0.8.8", + "monocle_apptrace.language": "python", + "span_source": "/.venv/lib/python3.12/site-packages/openai/_legacy_response.py:384", + "workflow.name": "nvidia-aiq", + "span.type": "inference.modelapi", + "scope.agentic.session": "3231a666-792d-49a0-bf51-37ba47f4eaf4", + "scope.agentic.turn": "1b91d731c386e41fcfbb29d01e3d0e7e", + "scope.agentic.invocation": "4e25542b5829546b4dc93f55b4a69d90" + }, + "events": [], + "links": [], + "resource": { + "attributes": { + "service.name": "nvidia-aiq" + }, + "schema_url": "" + } +} +,{ + "name": "langchain_core.language_models.chat_models.BaseChatModel.ainvoke", + "context": { + "trace_id": "e2961458302a780a27f91a0d86b290dd", + "span_id": "335965332693a78f", + "trace_state": "[]" + }, + "kind": "SpanKind.INTERNAL", + "parent_id": "ba5636fc1b3a0acb", + "start_time": "2026-07-09T20:25:13.674457Z", + "end_time": "2026-07-09T20:25:15.348959Z", + "status": { + "status_code": "OK" + }, + "attributes": { + "monocle_apptrace.version": "0.8.8", + "monocle_apptrace.language": "python", + "span_source": "/.venv/lib/python3.12/site-packages/nat/utils/exception_handlers/automatic_retries.py:265", + "workflow.name": "nvidia-aiq", + "entity.1.type": "inference.generic", + "span.type": "inference.framework", + "entity.2.name": "web_search_tool", + "entity.2.type": "tool.function", + "scope.agentic.session": "3231a666-792d-49a0-bf51-37ba47f4eaf4", + "scope.agentic.turn": "1b91d731c386e41fcfbb29d01e3d0e7e", + "scope.agentic.invocation": "4e25542b5829546b4dc93f55b4a69d90", + "entity.count": 2, + "span.subtype": "tool_call" + }, + "events": [ + { + "name": "data.input", + "timestamp": "2026-07-09T20:25:13.674550Z", + "attributes": { + "input": [ + "{\"system\": \"You are a Shallow Research Agent. Your role is to provide rapid, citation-backed answers using available tools.\\n\\n## CRITICAL: Source Hierarchy\\nPrioritize sources based on the query intent:\\n\\n1. **User Documents (Highest Priority)**: If a knowledge_search or document tool is available, use it first for \\\"my files,\\\" \\\"the uploaded doc,\\\" or personal/provided data.\\n2. **Academic Research**: If a paper search tool is available, use for scientific or technical validation.\\n3. **Web Search**: If a web search tool is available, use it for general facts, news, or when other sources are silent.\\n\\n## Query Rewriting (before calling search tools)\\nBefore calling any search tool, rewrite the user's question into a **search-friendly query** that includes **all context the user implied**. Add whatever is needed for the index to return relevant results \\u2014 do not pass the raw user message if it relies on implicit context.\\n\\n- **Add missing context**: Time (current date/year from the Context section below), scope, topic, or other details the user assumed but the search index does not have.\\n- **Examples**: Add current year for \\\"upcoming\\\" or \\\"next\\\" questions; expand vague shorthand with the obvious topic or scope.\\n\\nPass the **rewritten query** to the search tool. This greatly improves result relevance.\\n\\n## Research Rules\\n- **Only use tools listed** in the Available Tools section below. Do not assume access to tools not listed. If no web search tool is listed, you have NO web access.\\n- **Loop Prevention**: Max 2 calls per tool. If results are empty, change your search string once or move to synthesis.\\n\\n## Citation Rules\\nCite sources inline with [1], [2], etc. Include a `**References:**` section at the end.\\n- **Format**: `- [N] Title - URL` or `- [N] filename.pdf, p.X` for internal documents\\n- Use only URLs that appeared in tool results. Do not add URLs from memory.\\n- If you use a tool result to answer, include at least one inline citation and a `**References:**` section.\\n- For tool results without URLs or document citation keys, cite the exact tool name from the tool call: `- [1] mcp_time__get_current_time`.\\n- Citations are automatically verified \\u2014 focus on answering the question, not on perfecting references.\\n\\n**Example**:\\n\\\"The uploaded report shows a 5% margin [1].\\n\\n**References:**\\n- [1] Q4_Review.pdf, p. 2 (Internal)\\\"## Context\\nCurrent date and time: 2026-07-09 13:25:13\\n\\n\\n## Available Tools\\n\\n- **web_search_tool**: Retrieves relevant contexts from web search (using Exa) for the given question.\\n\\n Args:\\n question (str): The question to be answered. Will be truncated to 400 characters if longer.\\n\\n Returns:\\n str: The web search results containing relevant documents and their URLs.\\n\\n\\n\\n\"}", + "{\"human\": \"What is the current stock price of NVIDIA today?\"}" + ] + } + }, + { + "name": "data.output", + "timestamp": "2026-07-09T20:25:15.348887Z", + "attributes": { + "response": "{\"ai\": {\"name\": \"web_search_tool\", \"args\": {\"question\": \"current stock price of NVIDIA July 9 2026\"}, \"id\": \"call_1TPHlH9hEn01ZQZAkrRi6x85\", \"type\": \"tool_call\"}}" + } + }, + { + "name": "metadata", + "timestamp": "2026-07-09T20:25:15.348925Z", + "attributes": { + "finish_reason": "tool_calls", + "finish_type": "tool_call" + } + } + ], + "links": [], + "resource": { + "attributes": { + "service.name": "nvidia-aiq" + }, + "schema_url": "" + } +} +,{ + "name": "web_search_tool", + "context": { + "trace_id": "e2961458302a780a27f91a0d86b290dd", + "span_id": "e4424afd67f9903b", + "trace_state": "[]" + }, + "kind": "SpanKind.INTERNAL", + "parent_id": "ba5636fc1b3a0acb", + "start_time": "2026-07-09T20:25:15.353889Z", + "end_time": "2026-07-09T20:25:16.922392Z", + "status": { + "status_code": "OK" + }, + "attributes": { + "monocle_apptrace.version": "0.8.8", + "monocle_apptrace.language": "python", + "span_source": "/.venv/lib/python3.12/site-packages/langchain_core/tools/base.py:1096", + "workflow.name": "nvidia-aiq", + "entity.1.name": "web_search_tool", + "entity.1.description": "Retrieves relevant contexts from web search (using Exa) for the given question.\n\n Args:\n question (str): The question to be answered. Will be truncated to 400 characters if longer.\n\n Returns:\n str: The web search results containing relevant documents and their URLs.", + "entity.2.name": "LangGraph", + "entity.2.type": "agent.langgraph", + "span.type": "agentic.tool.invocation", + "entity.1.type": "tool.langgraph", + "scope.agentic.session": "3231a666-792d-49a0-bf51-37ba47f4eaf4", + "scope.agentic.turn": "1b91d731c386e41fcfbb29d01e3d0e7e", + "scope.agentic.invocation": "4e25542b5829546b4dc93f55b4a69d90", + "entity.count": 2, + "span.subtype": "content_generation" + }, + "events": [ + { + "name": "data.input", + "timestamp": "2026-07-09T20:25:15.354017Z", + "attributes": { + "input": "{'question': 'current stock price of NVIDIA July 9 2026'}" + } + }, + { + "name": "data.output", + "timestamp": "2026-07-09T20:25:16.922328Z", + "attributes": { + "response": "\n\nNVIDIA Corp (NVDA) | Currently at $202.78 (-0.66%) | Jul 9, 2026\n\n# NVDA \u2014 NVIDIA Corp\n\nNVIDIA Corp (NVDA) is currently at $202.78, down $1.34 (0.66%) today, as of July 9, 2026.\n\n## Today's Trading\n\n- Open: $204.35\n- High: $204.58\n- Low: $198.97\n- Close: $202.78\n- Volume: 130.82M\n\n## Previous Close\n\n- Close: $204.12\n\n\n---\n\n\n\nNVIDIA Corporation - Stock Quote & Chart\n\nStock Chart ; July 07, 2026, $196.93 ; July 06, 2026, $195.55 ; July 02, 2026, $194.83 ; July 01, 2026, $197.58.\n\n\n---\n\n\n\nNVIDIA Corporation (NVDA) Stock Historical Prices & Data - Yahoo Finance\n\n\nDate\nOpen\nClose Close price adjusted for splits.\nJul 9, 2026\n204.46\n203.31\nJul 8, 2026\n195.18\n204.12\nJul 7, 2026\n192.37\n196.93\nJul 6, 2026\n194.42\n195.55\n\n\n---\n\n\n\nNVIDIA Stock Price History - Investing.com\n\nAccess NVIDIA stock price history with daily data, historical prices, all-time highs, and stock chart history ... 06/08/2026 - 07/09/2026. Date. Price. Open. High.\n" + } + } + ], + "links": [], + "resource": { + "attributes": { + "service.name": "nvidia-aiq" + }, + "schema_url": "" + } +} +,{ + "name": "openai.resources.chat.completions.AsyncCompletions.create", + "context": { + "trace_id": "e2961458302a780a27f91a0d86b290dd", + "span_id": "b2c363163c27acf5", + "trace_state": "[]" + }, + "kind": "SpanKind.INTERNAL", + "parent_id": "391bd33f776e54b8", + "start_time": "2026-07-09T20:25:16.935224Z", + "end_time": "2026-07-09T20:25:19.152550Z", + "status": { + "status_code": "OK" + }, + "attributes": { + "monocle_apptrace.version": "0.8.8", + "monocle_apptrace.language": "python", + "span_source": "/.venv/lib/python3.12/site-packages/openai/_legacy_response.py:384", + "workflow.name": "nvidia-aiq", + "span.type": "inference.modelapi", + "scope.agentic.session": "3231a666-792d-49a0-bf51-37ba47f4eaf4", + "scope.agentic.turn": "1b91d731c386e41fcfbb29d01e3d0e7e", + "scope.agentic.invocation": "4e25542b5829546b4dc93f55b4a69d90", + "span.subtype": "turn_end" + }, + "events": [], + "links": [], + "resource": { + "attributes": { + "service.name": "nvidia-aiq" + }, + "schema_url": "" + } +} +,{ + "name": "langchain_core.language_models.chat_models.BaseChatModel.ainvoke", + "context": { + "trace_id": "e2961458302a780a27f91a0d86b290dd", + "span_id": "391bd33f776e54b8", + "trace_state": "[]" + }, + "kind": "SpanKind.INTERNAL", + "parent_id": "ba5636fc1b3a0acb", + "start_time": "2026-07-09T20:25:16.933692Z", + "end_time": "2026-07-09T20:25:19.155183Z", + "status": { + "status_code": "OK" + }, + "attributes": { + "monocle_apptrace.version": "0.8.8", + "monocle_apptrace.language": "python", + "span_source": "/.venv/lib/python3.12/site-packages/nat/utils/exception_handlers/automatic_retries.py:265", + "workflow.name": "nvidia-aiq", + "entity.1.type": "inference.generic", + "span.type": "inference.framework", + "scope.agentic.session": "3231a666-792d-49a0-bf51-37ba47f4eaf4", + "scope.agentic.turn": "1b91d731c386e41fcfbb29d01e3d0e7e", + "scope.agentic.invocation": "4e25542b5829546b4dc93f55b4a69d90", + "entity.count": 1, + "span.subtype": "turn_end" + }, + "events": [ + { + "name": "data.input", + "timestamp": "2026-07-09T20:25:16.934087Z", + "attributes": { + "input": [ + "{\"system\": \"You are a Shallow Research Agent. Your role is to provide rapid, citation-backed answers using available tools.\\n\\n## CRITICAL: Source Hierarchy\\nPrioritize sources based on the query intent:\\n\\n1. **User Documents (Highest Priority)**: If a knowledge_search or document tool is available, use it first for \\\"my files,\\\" \\\"the uploaded doc,\\\" or personal/provided data.\\n2. **Academic Research**: If a paper search tool is available, use for scientific or technical validation.\\n3. **Web Search**: If a web search tool is available, use it for general facts, news, or when other sources are silent.\\n\\n## Query Rewriting (before calling search tools)\\nBefore calling any search tool, rewrite the user's question into a **search-friendly query** that includes **all context the user implied**. Add whatever is needed for the index to return relevant results \\u2014 do not pass the raw user message if it relies on implicit context.\\n\\n- **Add missing context**: Time (current date/year from the Context section below), scope, topic, or other details the user assumed but the search index does not have.\\n- **Examples**: Add current year for \\\"upcoming\\\" or \\\"next\\\" questions; expand vague shorthand with the obvious topic or scope.\\n\\nPass the **rewritten query** to the search tool. This greatly improves result relevance.\\n\\n## Research Rules\\n- **Only use tools listed** in the Available Tools section below. Do not assume access to tools not listed. If no web search tool is listed, you have NO web access.\\n- **Loop Prevention**: Max 2 calls per tool. If results are empty, change your search string once or move to synthesis.\\n\\n## Citation Rules\\nCite sources inline with [1], [2], etc. Include a `**References:**` section at the end.\\n- **Format**: `- [N] Title - URL` or `- [N] filename.pdf, p.X` for internal documents\\n- Use only URLs that appeared in tool results. Do not add URLs from memory.\\n- If you use a tool result to answer, include at least one inline citation and a `**References:**` section.\\n- For tool results without URLs or document citation keys, cite the exact tool name from the tool call: `- [1] mcp_time__get_current_time`.\\n- Citations are automatically verified \\u2014 focus on answering the question, not on perfecting references.\\n\\n**Example**:\\n\\\"The uploaded report shows a 5% margin [1].\\n\\n**References:**\\n- [1] Q4_Review.pdf, p. 2 (Internal)\\\"## Context\\nCurrent date and time: 2026-07-09 13:25:16\\n\\n\\n## Available Tools\\n\\n- **web_search_tool**: Retrieves relevant contexts from web search (using Exa) for the given question.\\n\\n Args:\\n question (str): The question to be answered. Will be truncated to 400 characters if longer.\\n\\n Returns:\\n str: The web search results containing relevant documents and their URLs.\\n\\n\\n\\n\"}", + "{\"human\": \"What is the current stock price of NVIDIA today?\"}", + "{\"ai\": \"[{\\\"name\\\": \\\"web_search_tool\\\", \\\"args\\\": {\\\"question\\\": \\\"current stock price of NVIDIA July 9 2026\\\"}, \\\"id\\\": \\\"call_1TPHlH9hEn01ZQZAkrRi6x85\\\", \\\"type\\\": \\\"tool_call\\\"}]\"}", + "{\"tool\": \"\\n\\nNVIDIA Corp (NVDA) | Currently at $202.78 (-0.66%) | Jul 9, 2026\\n\\n# NVDA \\u2014 NVIDIA Corp\\n\\nNVIDIA Corp (NVDA) is currently at $202.78, down $1.34 (0.66%) today, as of July 9, 2026.\\n\\n## Today's Trading\\n\\n- Open: $204.35\\n- High: $204.58\\n- Low: $198.97\\n- Close: $202.78\\n- Volume: 130.82M\\n\\n## Previous Close\\n\\n- Close: $204.12\\n\\n\\n---\\n\\n\\n\\nNVIDIA Corporation - Stock Quote & Chart\\n\\nStock Chart ; July 07, 2026, $196.93 ; July 06, 2026, $195.55 ; July 02, 2026, $194.83 ; July 01, 2026, $197.58.\\n\\n\\n---\\n\\n\\n\\nNVIDIA Corporation (NVDA) Stock Historical Prices & Data - Yahoo Finance\\n\\n\\nDate\\nOpen\\nClose Close price adjusted for splits.\\nJul 9, 2026\\n204.46\\n203.31\\nJul 8, 2026\\n195.18\\n204.12\\nJul 7, 2026\\n192.37\\n196.93\\nJul 6, 2026\\n194.42\\n195.55\\n\\n\\n---\\n\\n\\n\\nNVIDIA Stock Price History - Investing.com\\n\\nAccess NVIDIA stock price history with daily data, historical prices, all-time highs, and stock chart history ... 06/08/2026 - 07/09/2026. Date. Price. Open. High.\\n\"}" + ] + } + }, + { + "name": "data.output", + "timestamp": "2026-07-09T20:25:19.155046Z", + "attributes": { + "response": "{\"ai\": \"As of July 9, 2026, NVIDIA Corp (NVDA) is trading at $202.78, which is down by $1.34 (0.66%) today [1].\\n\\n**References:**\\n- [1] [NVIDIA Corp (NVDA) | Currently at $202.78 (-0.66%) | Jul 9, 2026](https://exa.ai/library/markets/stock/NVDA?t=6a5011bc870bf6f5e301d76b)\"}" + } + }, + { + "name": "metadata", + "timestamp": "2026-07-09T20:25:19.155119Z", + "attributes": { + "finish_reason": "stop", + "finish_type": "success" + } + } + ], + "links": [], + "resource": { + "attributes": { + "service.name": "nvidia-aiq" + }, + "schema_url": "" + } +} +,{ + "name": "langgraph.graph.state.CompiledStateGraph.ainvoke", + "context": { + "trace_id": "e2961458302a780a27f91a0d86b290dd", + "span_id": "ba5636fc1b3a0acb", + "trace_state": "[]" + }, + "kind": "SpanKind.INTERNAL", + "parent_id": "252e148439056756", + "start_time": "2026-07-09T20:25:13.669218Z", + "end_time": "2026-07-09T20:25:19.159892Z", + "status": { + "status_code": "OK" + }, + "attributes": { + "monocle_apptrace.version": "0.8.8", + "monocle_apptrace.language": "python", + "span_source": "/src/aiq_agent/agents/shallow_researcher/agent.py:356", + "workflow.name": "nvidia-aiq", + "entity.1.type": "agent.langgraph", + "entity.1.name": "LangGraph", + "last.inference": "391bd33f776e54b8:*", + "span.type": "agentic.invocation", + "scope.agentic.session": "3231a666-792d-49a0-bf51-37ba47f4eaf4", + "scope.agentic.turn": "1b91d731c386e41fcfbb29d01e3d0e7e", + "scope.agentic.invocation": "4e25542b5829546b4dc93f55b4a69d90", + "entity.count": 1, + "span.subtype": "content_processing", + "monocle.last.agent.invocation.id": "", + "monocle.last.agent.name": "", + "inference.decision.span.id": "4965175556232f45" + }, + "events": [ + { + "name": "data.input", + "timestamp": "2026-07-09T20:25:13.669291Z", + "attributes": { + "input": "[\"What is the current stock price of NVIDIA today?\"]" + } + }, + { + "name": "data.output", + "timestamp": "2026-07-09T20:25:19.159787Z", + "attributes": { + "response": "As of July 9, 2026, NVIDIA Corp (NVDA) is trading at $202.78, which is down by $1.34 (0.66%) today [1].\n\n**References:**\n- [1] [NVIDIA Corp (NVDA) | Currently at $202.78 (-0.66%) | Jul 9, 2026](https://exa.ai/library/markets/stock/NVDA?t=6a5011bc870bf6f5e301d76b)" + } + } + ], + "links": [], + "resource": { + "attributes": { + "service.name": "nvidia-aiq" + }, + "schema_url": "" + } +} +,{ + "name": "langgraph.graph.state.CompiledStateGraph.astream", + "context": { + "trace_id": "e2961458302a780a27f91a0d86b290dd", + "span_id": "252e148439056756", + "trace_state": "[]" + }, + "kind": "SpanKind.INTERNAL", + "parent_id": "2571d8f530754181", + "start_time": "2026-07-09T20:25:11.453034Z", + "end_time": "2026-07-09T20:25:19.165599Z", + "status": { + "status_code": "OK" + }, + "attributes": { + "monocle_apptrace.version": "0.8.8", + "monocle_apptrace.language": "python", + "span_source": "/.venv/lib/python3.12/site-packages/langgraph/pregel/main.py:4061", + "workflow.name": "nvidia-aiq", + "entity.1.type": "agent.langgraph", + "entity.1.name": "LangGraph", + "last.inference": "391bd33f776e54b8:*", + "span.type": "agentic.invocation", + "scope.agentic.session": "3231a666-792d-49a0-bf51-37ba47f4eaf4", + "scope.agentic.turn": "1b91d731c386e41fcfbb29d01e3d0e7e", + "scope.agentic.invocation": "5133c49ef68f7b6f2fc506866a02c2c3", + "entity.count": 1, + "span.subtype": "content_processing", + "monocle.last.agent.invocation.id": "", + "monocle.last.agent.name": "" + }, + "events": [ + { + "name": "data.input", + "timestamp": "2026-07-09T20:25:11.453076Z", + "attributes": { + "input": "[\"What is the current stock price of NVIDIA today?\"]" + } + }, + { + "name": "data.output", + "timestamp": "2026-07-09T20:25:19.165379Z", + "attributes": { + "response": "As of July 9, 2026, NVIDIA Corp (NVDA) is trading at $202.78, which is down by $1.34 (0.66%) today [1].\n\n## Sources\n- [1] [NVIDIA Corp (NVDA) | Currently at $202.78 (-0.66%) | Jul 9, 2026](https://exa.ai/library/markets/stock/NVDA?t=6a5011bc870bf6f5e301d76b)\n" + } + } + ], + "links": [], + "resource": { + "attributes": { + "service.name": "nvidia-aiq" + }, + "schema_url": "" + } +} +,{ + "name": "langgraph.graph.state.CompiledStateGraph.ainvoke", + "context": { + "trace_id": "e2961458302a780a27f91a0d86b290dd", + "span_id": "2571d8f530754181", + "trace_state": "[]" + }, + "kind": "SpanKind.INTERNAL", + "parent_id": "9d62bf471530da08", + "start_time": "2026-07-09T20:25:11.450935Z", + "end_time": "2026-07-09T20:25:19.165744Z", + "status": { + "status_code": "OK" + }, + "attributes": { + "monocle_apptrace.version": "0.8.8", + "monocle_apptrace.language": "python", + "span_source": "/src/aiq_agent/agents/chat_researcher/agent.py:570", + "workflow.name": "nvidia-aiq", + "entity.1.type": "agent.langgraph", + "monocle.last.agent.invocation.id": "252e148439056756", + "monocle.last.agent.name": "LangGraph", + "last.inference": "391bd33f776e54b8:*", + "span.type": "agentic.turn", + "scope.agentic.session": "3231a666-792d-49a0-bf51-37ba47f4eaf4", + "scope.agentic.turn": "1b91d731c386e41fcfbb29d01e3d0e7e", + "entity.count": 1, + "span.subtype": "turn" + }, + "events": [ + { + "name": "data.input", + "timestamp": "2026-07-09T20:25:11.450977Z", + "attributes": { + "input": "[\"What is the current stock price of NVIDIA today?\"]" + } + }, + { + "name": "data.output", + "timestamp": "2026-07-09T20:25:19.165721Z", + "attributes": { + "response": "As of July 9, 2026, NVIDIA Corp (NVDA) is trading at $202.78, which is down by $1.34 (0.66%) today [1].\n\n## Sources\n- [1] [NVIDIA Corp (NVDA) | Currently at $202.78 (-0.66%) | Jul 9, 2026](https://exa.ai/library/markets/stock/NVDA?t=6a5011bc870bf6f5e301d76b)\n" + } + } + ], + "links": [], + "resource": { + "attributes": { + "service.name": "nvidia-aiq" + }, + "schema_url": "" + } +} +,{ + "name": "workflow", + "context": { + "trace_id": "e2961458302a780a27f91a0d86b290dd", + "span_id": "9d62bf471530da08", + "trace_state": "[]" + }, + "kind": "SpanKind.INTERNAL", + "parent_id": null, + "start_time": "2026-07-09T20:25:11.450884Z", + "end_time": "2026-07-09T20:25:19.165759Z", + "status": { + "status_code": "OK" + }, + "attributes": { + "monocle_apptrace.version": "0.8.8", + "monocle_apptrace.language": "python", + "span_source": "/src/aiq_agent/agents/chat_researcher/agent.py:570", + "scope.agentic.session": "3231a666-792d-49a0-bf51-37ba47f4eaf4", + "scope.agentic.turn": "1b91d731c386e41fcfbb29d01e3d0e7e", + "workflow.name": "nvidia-aiq", + "span.type": "workflow", + "entity.1.name": "nvidia-aiq", + "entity.1.type": "workflow.langgraph", + "entity.2.type": "app_hosting.generic", + "entity.2.name": "generic", + "last.inference": "391bd33f776e54b8:*" + }, + "events": [], + "links": [], + "resource": { + "attributes": { + "service.name": "nvidia-aiq" + }, + "schema_url": "" + } +} +] \ No newline at end of file